ace editorにJSXのハイライトモードをつけてみる

多分まだ誰もやっていなかったので。大文字で始まるのはクラス扱いしたりとか、けっこうインチキ臭いけど、わりとまともに表示されるよ!やったね!

ダウンロード・インストールはgithubから行なってください。
追記:本家のほうにマージしてもらったので、本家の方からgit cloneしてください。
git clone git://github.com/ajaxorg/ace.git
cd ace #追記(忘れてた)
git submodule update --init --recursive
npm install dryice
make

DEMO:acedemo

まぁ、余談ですが、aceのビルドシステムって再利用性高くていいですね。大体が命名規則でファイルを拾ってくれて、しかも書いたコード量だけみたら200行いかないくらいですから。あと、CLAとかプルリクエストとか(英語に関しても)色々初めてのことだらけだったので勉強になりました。

ここらへん(拡張のしかた、プルリクエストに関する色々)について詳しいことは追々記事を書こうかなと思います。
posted by 右京 | javascript

simpleflv ver 1.0.1

simple flv

MP3ファイル一つでFLV動画が作れる優れものです。ただ作るだけでなくて、オーディオプレイヤーによくあるスペクトルを表示してくれて視覚的にも割と楽しめます。しかもオフラインでも動きます。

ただし、Chromeでしか動きません!

使い方:

simpleflv_start.png
Start to buildボタンを押す。

simpleflv_size.png
サイズを選ぶ。選んだらChoose Colorを押す。

simpleflv_color.png
色を選ぶ。選んだらChoose Fileを押す。

simpleflv_file.png
ファイルを選ぶ。ドラッグ&ドロップかダイアログで選択する。
すると処理が開始して、5〜10秒で生成されたファイルがダウンロードされます。
簡単ですね。


ちなみに、Webページに使用している静的ファイルはAmazon S3で管理しています。普通の鯖でアプリケーションキャッシュを使おうとするとちょっとだけ面倒なんですが、S3ならばアップロードしてメタデータのContent-Typeをtext/cache-manifestに変えるだけでOK。ありがちな初期設定料も掛からず、ファイルが数十KB(アプリケーションキャッシュで次回以降はほぼ0)とかなら値段も相当安くなるのでスタンドアロンで動作するようなアプリを作る場合は相性がいいです。是非使ってみたらいいんじゃないでしょうか。
posted by 右京 | javascript

メルフィルタバンク

Web Audio APIのRealTimeAnalyserが吐き出すスペクトラムをビジュアライズしてもそれっぽくないので調べてみたら、どうやらメルフィルタバンクというのを使えば良いそう。メル周波数ケプストラム係数(MFCC) - 人工知能に関する断創録

というわけでPythonコードをJavaScriptに書き換えてみたよ。
create mel filter band − Gist
// http://d.hatena.ne.jp/aidiary/20120225/1330179868
// port python to JavaScript.

function melFilterBand(sampleRate, nfft, numChannels) {
var fmax = sampleRate >>> 1,
melmax = hz2mel(fmax),
nmax = nfft / 2,
df = sampleRate / nfft,
dmel = melmax / (numChannels + 1),
melcenters = [],
fcenters = [],
indexcenter = [],
indexstart = [],
indexstop = [],
filterbank = [],
i, j, n, m, increment, decrement, triWindow;

function hz2mel(f) {
return 1127.01048 * Math.log(f / 700.0 + 1.0);
}

function mel2hz(m) {
return 700.0 * (Math.exp(m / 1127.01048) - 1.0);
}

for(i = 0, n = numChannels; i < n; ++i) melcenters[i] = (i + 1) * dmel;

for(i = 0; i < n; ++i) fcenters[i] = mel2hz(melcenters[i]);

for(i = 0; i < n; ++i) indexcenter[i] = Math.round(fcenters[i] / df);

indexstart[0] = 0;
for(i = 0; i < n - 1; ++i) indexstart.push(indexcenter[i]);

for(i = 1; i < n; ++i) indexstop.push(indexcenter[i]);
indexstop.push(nmax);

for(i = 0; i < n; ++i) {
increment = 1 / (indexcenter[i] - indexstart[i]);
triWindow = [];
for(j = indexstart[i], m = indexcenter[i]; j < m; ++j) {
triWindow.push((j - indexstart[i]) * increment);
}
decrement = 1 / (indexstop[i] - indexcenter[i]);
for(j = indexcenter[i], m = indexstop[i]; j < m; ++j) {
triWindow.push(1 - (j - indexcenter[i]) * decrement);
}
filterbank[i] = triWindow;
}

return {
filterband: filterband,
indexcenter: indexcenter
};
}

まぁ、Mp3とかを処理するときは20kHzくらいから上がちょん切られていることもあるので、そこらへんは拡張子から空気読む必要がありそうだね。
posted by 右京 | javascript

JavaScriptでJava風にsuperクラスにアクセスするライブラリ作った

https://github.com/ukyo/jssuper

※ProxyとECMA5が実装されている処理系で動かしてね。
追記:prototypeチェーンにsuperが2つ絡むとループすることに気がついた・・・のだけど、解決法がわからん。superは一回だけでお願いします(これはひどい)。

まぁ、ソースコードはこれだけなんですが。しかしながら、プロパティだとsuperって書いても一応平気なんですね・・・。
Object.defineProperty(Object.prototype, 'super', {
get: function() {
var superProto, method, constructor;

superProto = Object.getPrototypeOf(Object.getPrototypeOf(this));

method = function(rcvr, name) {
return superProto[name].bind(this);
}.bind(this);

constructor = function() {
superProto.constructor.apply(this, arguments);
}.bind(this);

return Proxy.createFunction({get: method}, constructor);
}
});

こんな感じで使えます。extendする系のライブラリでも普通に動くと思います。
function A(message) {
this.message = message;
}

function B() {
//super classのコンストラクタを呼ぶ
this.super('hello!');
}
B.prototype = Object.create(A.prototype);

A.prototype.foo = function() {
return '#' + this.message + '#';
};

B.prototype.foo = function() {
//super classのメソッドを呼ぶ
//もちろんcall(this)しなくてもOK
return '(' + this.super.foo() + ')';
};

var b = new B;
b.foo(); // '(#hello!#);'が返ってくる。
posted by 右京 | javascript

JavaScriptでPythonのsuperっぽいことをする。

ECMA HarmonyのProxyとECMA5のFunction.prototype.bindを使うと実現できます(たったの7行!)。

superを実現している部分(superは予約語・・・)
var __super = function(self) {
return Proxy.create({
get: function(rcvr, name) {
return self.__proto__.__proto__[name].bind(self);
}
});
};


追記:こうしないとだめだった・・・。単一継承なのに。
var sup = function(self, Class) {
return Proxy.create(
{get: function(rcvr, name) {
name = name === '__init__' ? 'constructor' : name;
return Object.getPrototypeOf(Class.prototype)[name].bind(self);
}}
);
};

posted by 右京 | javascript

extendとmixin

なるべく薄く作ろうとするとこんな感じになるのかなぁ。coffeescriptだと__super__をつくってオーバーライドした親クラスのメソッドを呼んだりして。生のJSで実際にやるとしたら、Hoge.__super__.hoge.call(this, arg1, arg2);みたいにしなければいけないところをsuperと書くだけで同じことができるというのはやっぱりよくできてる(パフォーマンスは別にして)。ただ、proxyが黒魔術的な力を持っているのでオーバーライドしたメソッドから親クラスのメソッドを呼ぶ簡単な方法が提案されたらいいねー。

//extend
//一回ダミーのコンストラクタを作ることによってインスタンス作成時にエラーを出すかんじのものも継承できる
function extend(child, parent) {
var F = function(){};
F.prototype = parent.prototype;
child.prototype = new F;
}

//mixin
function mixin(to, from) {
var tp = to.prototype, k;
for(k in from) if(from.hasOwnProperty(k)) tp[k] = from[k];
}

//usage
function A(name){
if(typeof name !== 'string') throw new TypeError('name must be string.');
this.name = name;
}

A.prototype.hello = function() {
alert(this.name + ' says hello.');
};

var MeifukusigatakiMixin = {
woonyaa: function(){
alert('(」・ω・)」うー!(/・ω・)/にゃー!と叫ぶ' + this.name);
}
};

function B(name){
A.call(this, name);
}
//extendしてからmixinしないとダメ!
extend(B, A);
mixin(B, MeifukusigatakiMixin);

var b = new B('ハスターくん');
b.hello();
b.woonyaa();

function C(name){
B.call(this, name);
}
extend(C, B);

var UnkoMixin = {
unko: function() {
alert('うんこをする' + this.name);
}
};

mixin(B, UnkoMixin);
b.unko();

var c = new C('ニャル子');
c.hello();
c.woonyaa();
c.unko(); //prototypeチェーンに入っているのでもちろんOK
posted by 右京 | javascript

愉快なforEach

Array.prototypeには結構愉快なメソッドがあって、そのメソッドを他のオブジェクトのprototypeにくっつけても動くようなのもある。走査系というんですかね、lengthがあって0,1,2...みたいにシーケンシャルにアクセスするようなやつ。例えばforEach(もちろん他にもあるんだけど)。

function addEach() {
var each = [].forEach;
arguments.forEach = each;
arguments.forEach(function(obj) {
obj.prototype.forEach = each;
});
}

addEach(String, NodeList, FileList);

上の例でもわかるようにもちろんインスタンスに直接forEachをくっつけることもできる。prototypeチェーンで速度が落ちるのが嫌だとか、prototypeを汚したくない場合はそれもありかもね(call使えばいいのだけど)。
posted by 右京 | javascript

javascriptのnative APIで任意の文字コードからutf8に変換

1.BlobBuilder#appendで文字列を追加すると自動的にutf8に変換される
2.FileReader#readAsTextで任意の文字コードのBlobを読み込んで文字列に変換できる

これらを使うとなんでもutf8に変換できるね!という話。ただし、任意の文字コード→任意の文字コードはやっぱり変換テーブルが必要だけど。BlobBuilder#appendで文字コード指定できないのかな?

処理の流れ。
Array or Uint8Array or ArrayBuffer -> unicode string -> utf8 ArrayBuffer

posted by 右京 | javascript

巨大な配列から文字列へ変換する場合はnativeで変換すると圧倒的に速い

つまりこういうことです。
var bb = new (window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder || window.BlobBuilder),
fr = new FileReader;
bb.append(bytes.buffer);
fr.onloadend = function() {
//何か処理
};
fr.readAsBinaryString(bb.getBlob());

これは一例ですが、ArrayからArrayBuffer作るのも、部分的なArrayBufferを作るのもネイティブでできるので大体のケースでつかえるんじゃないですかね?

for文とネイティブの比較:
http://jsperf.com/bytes-to-string-test
posted by 右京 | javascript

emscriptenでzpipeを変換する過程をcodestre.amで撮ってみた

ちょっとvim操作が不自由なんだけど、撮ってみたよ。linuxの人は割と簡単にできるので試してみるといいかもね。

http://codestre.am/22d71745d4dbb5d7a3dc6018e
posted by 右京 | javascript

meteorいじってみた

Meteorで簡単な画像投稿サイトを作ってみた。こんなに簡単に作れるとは・・・。Collectionが作りたい放題、改ざんし放題なのはちょっと気になるけど。

DEMO: droppicture(画像ファイルをドロップしてね)

javascript
(function(window){

var Pictures = new Meteor.Collection('pictures');

if (Meteor.is_client) {
Template.hello.pictures = function(){
var limit = 10;
//まだ実装されてない
//return Pictures.find({}, {sort: {created: -1}, limit: limit});
return Pictures.find({}, {sort: {created: -1}}).fetch().slice(0, limit);
};

function cancel(e) {
var ev = e.originalEvent;
ev.preventDefault && ev.preventDefault();
return false;
}

var ext = {
gif: true,
jpg: true,
png: true
};

function postImage(e) {
var file = e.originalEvent.dataTransfer.files[0];

if(ext[file.name.split('.').pop()]) {
var image = new Image,
URL = window.URL || window.webkitURL;
image.onload = function() {
var canvas = $('<canvas>')[0],
ctx, width = 300, height;
height = ~~(image.height * width / image.width);
canvas.width = width;
canvas.height = height;
ctx = canvas.getContext('2d');
ctx.drawImage(image, 0, 0, width, height);
Pictures.insert({
name: file.name,
dataurl: canvas.toDataURL(),
created: +new Date
});
};
image.src = URL.createObjectURL(file);
}

cancel(e);
}

$(window)
.bind('dragover', cancel)
.bind('dragenter', cancel)
.bind('drop', postImage);
}

if (Meteor.is_server) {
Meteor.startup(function () {
// code to run on server at startup
});
}

})(this);

html
<head>
<title>droppicture</title>
</head>

<body>
{{> hello}}
</body>

<template name="hello">
<div class="container"><h1>Drop a picture here</h1></div>
<div class="container">
{{#each pictures}}
<img src="{{dataurl}}" alt="{{name}}">
{{/each}}
</div>
</template>

css
/* CSS declarations go here */
body {
margin: 0;
padding: 0;
background-color: #eee;
}

.container {
width: 320px;
text-align: center;
margin: auto;
}

h1 {
font-size: 16px;
color: #494949;
}

img {
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ddd;
background-color: #fdfdfd;
}
posted by 右京 | javascript

javascriptのundefined判定の比較

undeftest.png

予想ではどのブラウザでもlocalのundefinedが速いと思ったんだけど、実際はFirefoxだけだったりして。typeofで判定するときは文字列が同じかどうか比較するから遅いらしい。最も安定しているのはvoid 0。というわけで、for文とかの中でundefined判定をする場合はx === void 0がタイプ数的にも速度的にもいいんじゃないかな(初めてみた人はなんじゃこりゃっていいそう)。

"Type of undefined" vs "=== undefined" ・ jsPerf
posted by 右京 | javascript

こんな感じのTypedArrayのmixinが欲しい

すでに誰かがやってそうだけど。

posted by 右京 | javascript

google-code-prettifyで行番号が表示されないと思ったら

もともとHTMLのbrタグは改行扱いされない。で、この間のseesaaブログのアップデートで改行が削除されるようになったのかな?対策は簡単で、prettyprintクラス内のbrを改行に変えれてからprettyPrintを呼べばOK。以下参考。

Issue 188 - google-code-prettify - New lines created with <br> aren't retained when copying and pasting in IE9 - syntax highlighting of code snippets in a web page - Google Project Hosting
posted by 右京 | javascript

jsziptools 2.0

変更点
・deflateをemscriptenで変換したものを使うようにしました。
・inflateをpdf.jsのものを使うようにしました。
・上2つによりライセンス微妙?だったのが大丈夫になりました。
・jz.zip.packは基本的に非同期(ajax使うときはこちらを使ってね)でファイルを読み込むようにしました。
・なんかかっこいいページができました。Jsziptools by ukyo
TODO
・ちゃんとしたドキュメント

容量は108KBくらい(だいたいemscripten)になりましたが許容範囲ですよね?テキストだからgzip圧縮すればそこそこ縮みますよ、多分。
posted by 右京 | javascript

emscriptenのファイルIO

emscriptenのファイルIOってどうなってるんじゃと思って調べてみた。

手順的にはこんな感じ。
1. file IOを行うcファイル(file.c)を作る
2. emscriptenで生成したファイルが事前に読み込むjsファイル(pre.js)を作る
3. ラップする(header.js, footer.js)

まずはc言語で簡単なファイルIOを行うプログラムを書いてみる。inputというファイルからデータを読み取りoutputというファイルにデータを書き込む。
#include <stdio.h>

int main(void){
FILE *i, *o;
int c;

i = fopen("input", "r");
o = fopen("output", "w");

while((c = fgetc(i)) != EOF) fputc(c, o);
fclose(i);
fclose(o);

return 0;
}


次にpre.js。emscriptenではファイルシステムAPIを用いて仮想のファイルシステムにアクセスできる。そのAPIを用いてinput,outputにアクセスする。詳しくはFilesystem Guide ・ kripken/emscripten Wikiをみてね。
Module['preRun'] = function(){
FS.createDataFile(
'/',
'input',
Module['input'], //引数から入力できるようにするためのもの
true,
true
);
FS.createDataFile(
'/',
'output',
null,
true,
true
);
Module['ret'] = function(){
return FS.findObject("/output").contents; //最終的に返り値になる
};
};

最後にラップしてようやくブラウザから使える。こんな感じ。なんとなくわかるよね。
header.js
function fileio(input){
var Module = { //さきにModule作っちゃう
input: input //pre.jsで読み込まれる
};
arguments = [];//こうしないとmain関数のargvとして読み込まれるので注意

footer.js
return Module.ret();
}

最後に生成しておわり。
emcc -O2 file.c -o file.raw.js --pre-js pre.js
cat header.js file.raw.js footer.js > file.js

使い方:
var xhr = new XMLHttpRequest;
xhr.open("GET", url);
xhr.responseType = "arratbuffer";
xhr.onload = function(){
var a = fileio(new Uint8Array(xhr.response));
//なにか処理
};
xhr.send();

参考:
azakai: HOWTO: Port a C/C++ Library to JavaScript (xml.js)
posted by 右京 | javascript
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。