2014年07月31日

gulpでJadeをコンパイル

基本は「タスクランナーgulp入門 - to-R」を参考に。

以下がgulpでJadeをコンパイルする為の処理。

gulp.task('jade', function () {
gulp.src('htdocs/jade/**/*.jade')
.pipe(jade())
.pipe(gulp.dest('htdocs/'));
});


ただし、このままだとincludeファイルなども書き出してしまう。

以下のようにすると_付きのファイルは出力されなくなります。

gulp.task('jade', function () {
gulp.src(['htdocs/jade/**/*.jade','!htdocs/jade/**/_*.jade'])
.pipe(jade())
.pipe(gulp.dest('htdocs/'));
});
タグ:JADE GULP
posted by ねこまんま at 15:36 | Comment(0) | TrackBack(0) | gulp | 更新情報をチェックする

2014年07月30日

QUnit入門

JavaScriptテストフレームワークの「QUnit」について解説します。

まずはQUnitのJSファイルとCSSファイルを読み込みます。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUnit Example</title>
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.14.0.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="http://code.jquery.com/qunit/qunit-1.14.0.js"></script>
<script>
//コード
</script>
<script>
//テストコード
</script>
</body>
</html>


以下、コードとテストコードの別けて解説していきます。

QUnitではQUnit.test( )でテストを定義できます。第1引数にテストの名前、第2引数にコールバック関数としてテストの内容を記述します。

QUnit.test( "hello test", function( assert ) {
assert.ok( 1 == "1", "Passed!" );
});


コールバック関数内ではassertオブジェクトを利用できます。

assert.ok()では第1引数でstate(boolean値に変換されたもの)、第2引数にメッセージを指定できます。

以下のサンプルでは最初に2つのassert.ok( )以外は失敗を返します。

QUnit.test( "hello test", function( assert ) {
assert.ok( true, "true succeeds" );
assert.ok( "non-empty", "non-empty string succeeds" );
assert.ok( false, "false fails" );
assert.ok( 0, "0 fails" );
assert.ok( NaN, "NaN fails" );
assert.ok( "", "empty string fails" );
assert.ok( null, "null fails" );
assert.ok( undefined, "undefined fails" );
});


他にもassert.deepEqual()で第1引数と第2引数に与えられたオブジェクトが同一の値を持つか確認したり、

QUnit.test( "deepEqual test", function( assert ) {
var obj = { foo: "bar" };
assert.deepEqual( obj, { foo: "bar" }, "Two objects can be the same in value" );
});


assert.equal()で値が同じかどうか確認できます。

QUnit.test( "equal test", function( assert ) {
assert.equal( 0, 0, "Zero, Zero; equal succeeds" );
assert.equal( "", 0, "Empty, Zero; equal succeeds" );
assert.equal( "", "", "Empty, Empty; equal succeeds" );
assert.equal( "three", 3, "Three, 3; equal fails" );
assert.equal( null, false, "null, false; equal fails" );
});


expect()でテストの回数を指定できます。expect( 2 )と指定すると2回assertがsuccessを返さなければ失敗とみなします。

QUnit.test( "a test", function( assert ) {
expect( 2 );
function calc( x, operation ) {
return operation( x );
}
var result = calc( 2, function( x ) {
assert.ok( true, "calc() calls operation function" );
return x * x;
});
assert.equal( result, 4, "2 squared equals 4" );
});


イベントの確認はtriggerを利用して確認。

QUnit.test( "a test", function( assert ) {
expect( 1 );
var $body = $( "body" );
$body.on( "click", function() {
assert.ok( true, "body was clicked!" );
});
$body.trigger( "click" );
});


非同期のテストはQUnit.asyncTest()QUnit.start()を利用する。

QUnit.asyncTest( "asynchronous test: one second later!", function( assert ) {
expect( 1 );
setTimeout(function() {
assert.ok( true, "Passed and ready to resume!" );
QUnit.start();
}, 1000);
});


タグ:テスト QUnit test
posted by ねこまんま at 20:20 | Comment(0) | TrackBack(0) | test | 更新情報をチェックする

WebRTCで通信を中断させる

WebRTCで通信を中断させる方法。ストリームの送信側のRTCPeerConnectionオブジェクトからlocalStreamを取り出し、removeStream()を利用してストリームを取り出します。そうすると送信先のストリームオブジェクトにメディアストリームが除かれる形になり、addStream()でストリームを復元することができる。

var localStream = peer.getLocalStreams()[0];
$(".stop").click(function(){
peer.removeStream(localstream);
});
$(".start").click(function(){
peer.addStream(localstream);
});
タグ:WebRTC HTML5
posted by ねこまんま at 14:35 | Comment(0) | TrackBack(0) | HTML5 | 更新情報をチェックする

2014年07月17日

Knockout-es5でrateLimitを設定する

Knockout-ES5はKnockout.jsをES5のgetter/setterに対応してくれる便利なプラグイン。ただrateLimitなどの標準の機能を利用しようとするとちょっと工夫が必要。

ko.track(this);
ko.getObservable(this, 'fuga').extend({ rateLimit: 100 });


ko.track()した後にko.getObservable()でrateLimitを設定したいオブジェクトを取得してからextendで機能拡張を行うとOK。
posted by ねこまんま at 15:13 | Comment(0) | TrackBack(0) | Knockout.js | 更新情報をチェックする

Socket.IOでクライアントサイドのデバッグを行う

Socket.IOでのデバッグが以外と面倒臭かったのでメモ書き。

以下のようにsocket.on()のコールバック関数内でエラーが出ても、JavaScriptコンソール内にエラーが表示されない。謎にSocket.IOが新しいコネクションを張ります。

socket.on('fuga', function (data) {
//ここでJavaScriptエラー
});


ソースコード中に以下のようにlocalStorage.debugに*を入れておくとコンソール上に様々な情報が表示されるようになる。

localStorage.debug = '*';


ただ、表示されるログは非常に多いので以下のようにすると絞り込むことができる。(ただ、まだ多い)

localStorage.debug = 'socket.io-client:socket';


これにどのコールバック関数でエラーが出ているか、どのようなエラーが出ているかが含まれているのでそれを参考にデバッグ。行数とか教えてくれないので想像力をかなり働かせなくてはエラーが見つけられないので注意。
タグ:socket.io
posted by ねこまんま at 15:08 | Comment(0) | TrackBack(0) | HTML5 | 更新情報をチェックする

2014年07月09日

Knockout入門2

Knockout入門1の続き、Knockout : Computed Observablesの内容を確認していく。

以下のようにAppViewModelコンストラクタを使ってインスタンスをko.applyBindings()で監視。

<span data-bind="text: firstName"></span>
<span data-bind="text: lastName"></span>
<script>
function AppViewModel() {
this.firstName = ko.observable('Bob');
this.lastName = ko.observable('Smith');
}
ko.applyBindings(new AppViewModel());
</script>


以下のようにko.computed()を使ってfirstNameとlastNameからfullNameというプロパティを作成する。

function AppViewModel() {
this.firstName = ko.observable('Bob');
this.lastName = ko.observable('Smith');
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName();
}, this);
}
ko.applyBindings(new AppViewModel());


次のようにthisを変数selfの中に入れておいて参照することも可能。

function AppViewModel() {
var self = this;
self.firstName = ko.observable('Bob');
self.lastName = ko.observable('Smith');
self.fullName = ko.computed(function() {
return self.firstName() + " " + self.lastName();
});
}
ko.applyBindings(new AppViewModel());


次のように指定することも可能。

function AppViewModel() {
this.firstName = ko.observable('Bob');
this.lastName = ko.observable('Smith');
}
var myViewModel = new AppViewModel()
myViewModel.fullName = ko.computed(function() {
return myViewModel.firstName() + " " + myViewModel.lastName();
})
ko.applyBindings(myViewModel);
myViewModel.firstName("fuga");


このままではfullName()はあくまで読み取り専用である。以下のようにすることで書き込みも可能になる。
(lastIndexOf()で半角スペースがあるか判定してsubstring()でその前後を抽出)

function MyViewModel() {
this.firstName = ko.observable('Planet');
this.lastName = ko.observable('Earth');
this.fullName = ko.computed({
read: function () {
return this.firstName() + " " + this.lastName();
},
write: function (value) {
var lastSpacePos = value.lastIndexOf(" ");
if (lastSpacePos > 0) { // Ignore values with no space character
this.firstName(value.substring(0, lastSpacePos)); // Update "firstName"
this.lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
}
},
owner: this
});
}
var myViewModel = new MyViewModel();
ko.applyBindings(myViewModel);
myViewModel.fullName("hoge fuga");


ここからは別サンプル。formattedPriceは数値を$123.00といったフォーマットに整形して表示する機能。toFixed()で少数表示に対応している。priceプロパティにはあくまで数値が格納されているがformattedPriceでそれを$表記に変更して出力している。

<p>Enter bid price: <input data-bind="value: formattedPrice"/></p>
<script>
function MyViewModel() {
this.price = ko.observable(25.99);
this.formattedPrice = ko.computed({
read: function () {
return '$' + this.price().toFixed(2);
},
write: function (value) {
// Strip out unwanted characters, parse as float, then write the raw data back to the underlying "price" observable
value = parseFloat(value.replace(/[^\.\d]/g, ""));
this.price(isNaN(value) ? 0 : value); // Write to underlying storage
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
</script>


次のサンプルは入力フォーム(attemptedValue)の値が数値の場合はlastInputWasValid()がfalseをそうでない場合あtrueを返す

<p>Enter a numeric value: <input data-bind="value: attemptedValue"/></p>
<div data-bind="visible: !lastInputWasValid()">That's not a number!</div>
<script>
function MyViewModel() {
this.acceptedNumericValue = ko.observable(123);
this.lastInputWasValid = ko.observable(true);
this.attemptedValue = ko.computed({
read: this.acceptedNumericValue,
write: function (value) {
if (isNaN(value))
this.lastInputWasValid(false);
else {
this.lastInputWasValid(true);
this.acceptedNumericValue(value); // Write to underlying storage
}
},
owner: this
});
}
ko.applyBindings(new MyViewModel());
</script>
タグ:KNOCKOUT
posted by ねこまんま at 06:38 | Comment(0) | TrackBack(0) | Knockout.js | 更新情報をチェックする

Knockout入門1

Knockoutをお仕事で使うのでメモ。

Knockout入門1ではKnockout : Observablesを読みながら基本機能の確認。

まず、以下のようにCDNからサクッと読み込める

<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.0.0.js"></script>


最新の3.1は以下のCDNで配布されている。

<script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/3.1.0/knockout-min.js"></script>


まずは基本のko.applyBindings()を使ってみる。ko.applyBindings()はオブジェクトの内容をDOMに反映させるメソッド。

<span data-bind="text: personName"></span>
<span data-bind="text: personAge"></span>
<script>
var myViewModel = {
personName: 'Bob',
personAge: 123
};
ko.applyBindings(myViewModel);
</script>


上記のように記述するとspanの内容が以下のように書き換えられる。

<span data-bind="text: personName">Bob</span>
<span data-bind="text: personAge">123</span>


つぎにデータバインディングの醍醐味であるko.observable()。上記のスクリプトを下記のように変更。

最初は画面にBobと表示される。myViewModel.personName()のように引数に何も入れなければプロパティの取得が可能で、myViewModel.personName("Tomy")のように引数に値を入れればプロパティの内容の変更が可能。変更を行うと即座にHTML上に反映させられる。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
alert(myViewModel.personName());
myViewModel.personName("Tomy");


subscribe()で変更をscript側で感知することも可能

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
myViewModel.personName("Tomy");


変更直前にスクリプトを実行したい場合は以下のように第3引数に"beforeChange"を記述する。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
myViewModel.personName.subscribe(function(oldValue) {
alert("The person's previous name is " + oldValue);
}, null, "beforeChange");
myViewModel.personName("Tomy");


ちなみに第2引数にはコールバック関数内のthisで利用するオブジェクトが指定できる。以下のように指定をすると「hogeBob」とアラートが表示される。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
myViewModel.personName.subscribe(function(oldValue) {
alert(this.fuga + oldValue);
}, {"fuga":"hoge"}, "beforeChange");
myViewModel.personName("Tomy");


バインドしたsubscribeイベントはdispose();で破棄することができる。"Tomy1"への変更の時点ではアラートがでるが"Tomy2"への変更ではアラートが表示されない。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
var subscription = myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
myViewModel.personName("Tomy1");
subscription.dispose();
myViewModel.personName("Tomy2");


subscribeイベントは基本的には変更があった場合に発火する。たとえば次のケースではpersonNameをBob→Bobに変更しているので変更がないとみなされてアラートは表示されない。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
var subscription = myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
myViewModel.personName("Bob");


ただし、この挙動はextend({ notify: 'always' })を指定することで変更でき、同じ値でもsubscribeイベントを発火させることができる。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
myViewModel.personName.extend({ notify: 'always' });
var subscription = myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
myViewModel.personName("Bob");


他にも、extend({ rateLimit: Number })などがある。これは変更のタイミングを制御するための機能です(Knockout 3.1より追加)。

以下のように記述するとsubscribeイベントは4回発火する。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
var subscription = myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
myViewModel.personName("Bob1");
myViewModel.personName("Bob2");
myViewModel.personName("Bob3");
myViewModel.personName("Bob4");


これを以下のようにextend({ rateLimit: 50 })を追加すると変更のタイミングは50ms秒後になり、アラートは「Bob4」のみが表示されるようになる。

var myViewModel = {
personName: ko.observable('Bob'),
personAge: ko.observable('123')
};
ko.applyBindings(myViewModel);
var subscription = myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
myViewModel.personName.extend({ rateLimit: 50 });
myViewModel.personName("Bob1");
myViewModel.personName("Bob2");
myViewModel.personName("Bob3");
myViewModel.personName("Bob4");


ひとまず、Knockout入門1はこんなかんじでKnockout入門2に続く。
タグ:KNOCKOUT
posted by ねこまんま at 06:05 | Comment(0) | TrackBack(0) | Knockout.js | 更新情報をチェックする

2014年07月04日

video要素の内容をcanvasを使って画像に変換する

次のような感じでvideo要素の内容をcanvasに変換してからData URIに変換する

var getVideoCapture = function(video){
var canvas = document.createElement("canvas");
canvas.width = video.width;
canvas.height = video.height;
var context = canvas.getContext("2d");
context.drawImage(video, 0, 0, canvas.width, canvas.height);
var getVideoCaptureURL = canvas.toDataURL();
delete canvas;
return getVideoCaptureURL;
}
posted by ねこまんま at 16:32 | Comment(0) | TrackBack(0) | HTML5 | 更新情報をチェックする