イナヅマTVログ

2012.04.27
22:46
author: taikiken
1件のコメント

jQuery 1.4.3~1.4.4でreadyイベントが2回発生する

今日のバグ情報。

簡単なお仕事のはずがはまってしまったお話です。

既にjQuery 1.4.3がリンクされているHTMLを渡されました。
えっ、古!とは思いましたがjQueryにしてもライブラリが最新で無いソースを渡されることは良くあるので気にせず作業開始。

要件はすぐに実装できたのでテストに入りました。

一番心配していたIE6でも無事に動作したようです。
やれやれといったところなんですが、念のため実行状況を出力しておくことにしました。

うん?
なんか2回実行されているような。

いやいや、気のせいかもしれない。

もう一度…

やっぱり、2回実行されてる。

他のブラウザは、1回だけ。
う〜〜ん。

IE6だけdom ready後にゴニョゴニョってしてるのが2回走っている様子。

(function($){
    $(function(){
        // do something
    });
}(jQuery));

こんな感じだけどIE6だけ2回…

まず自分を疑うよね。
何度もコードを見直した。
最後に上記のようにほぼ空っぽの状態にしても発生。

次は、プロジェクトメンバー。
ここから、かなり嫌なやつ。
先にJS貼付けてるやつが何かしてないか調べだす。
これかも、あれかも。

問題なさそう。
疑ってごめんなさい。

まさかと思いjQuryサイトを調べるとバグ情報ががが!
BLOG » JQUERY 1.4.4 RELEASE CANDIDATE 2 RELEASED の#7247
Ticket #7247
もうfix済みだけど、1.4.4までは存在するらしい。
2010年かぁ、この頃jQuery使ってないから細かい情報に疎いんだよなぁ。

だれだよjQuery 1.4.3なんか使おうとしたやつ。

今や1.7.xの時代です。
最新版を使っていれば回避できてた問題です。
いい教訓、かなー?

自分だったらあんな古いライブラリなんか絶対使わない!
いやライブラリ自体は使うから問題回避にはならないか。

でも新規案件なのにわざわざ古いライブラリを持ち出すことはないと思います。
何かの事情で以前のバージョンを引っ張りだす時はよく調べてstableじゃないとね。

あまりお役に立たない古い古いバグ情報でした。

2012.04.26
10:58
author: taikiken
1件のコメント

超個人的メモ, JavaScript関連の投稿リンクをまとめておく

昨年後半からポツポツ投稿したJavaScriptに関する投稿リンクをまとめておきます。
関連投稿リンクがうまく働いて無いせいですけど…

category: JavaScript

2011 年 10 月 22 日
JavaScriptでOOP – Classみたいなの

2011 年 10 月 23 日
「ハイパフォーマンスJavaScript」の教え-ノンブロッキングパターン

2011 年 10 月 23 日
JavaScript, 匿名関数の実行そして関数と変数の隠匿

2011 年 10 月 23 日
JavaScriptでOOP – privateぽい関数と変数, staticなやつ

2011 年 10 月 23 日
JavaScriptでOOP – Classみたいなのにprivateな関数と変数

2011 年 10 月 24 日
ECMAScript 5, Browserサポート状況

2012 年 2 月 13 日
JavaScript, 名前空間の汚染問題を考える

2012 年 5 月 16 日
jQueryを使わなくてもDom readyで処理したい

2012 年 5 月 22 日
JavaScriptでstyleタグをheadに挿入

2012 年 6 月 6 日
ECMAScript 5, Array.isArrayを非対応ブラウザでも使いたい

2012 年 6 月 25 日
jQuery, checkboxやradioがチェックされているかを調べる

2012 年 6 月 29 日
JavaScript, querySelectorとquerySelectorAllを使いましょ

2012 年 7 月 8 日
JavaScript, requestAnimationFrameを下位互換実装するために

2012 年 7 月 20 日
jQueryを使わないMouseEvent(click)処理とEvent委譲(delegate)

2012 年 10 月 5 日
Ajax, jQueryでXMLをParseそしてAccess-Control-Allow-Originについて

2012 年 10 月 6 日
JavaScript, Singleton Patternを作ってみた

2012 年 10 月 7 日
JavaScript 1.6, Array.indexOfを下位互換実装する

2012 年 10 月 30 日
[JavaScript]Memo, navigator.geolocation.getCurrentPosition API

2012 年 12 月 1 日
Memo, margin: 0 autoを指定したDOMのmargin-leftをJavaScriptで取得したら

2011年中ほどからJavaScript関連のお仕事が増えたのもありますが、なんか色々と書いてました、内容の薄いオレオレなメモです。
ちゃんと全体を構成して書いていれば資料として価値も出るのでしょうけど…
まぁこれでも自分の役には立ちます。

HTML5関連のAPIはほとんどJavaScriptで制御なので、Web関連のお仕事ではしばらく需要がありそうです。
間違ってこの記事にたどり着いた方、ごめんなさい、超個人的私的メモです。

【参考書籍】
JavaScript: The Good Parts

JavaScriptパターン

ハイパフォーマンスJavaScript

この3冊は外せない。

あとこれも。

2012.04.26
10:07
author: taikiken
0件のコメント

Canvas始めました – 移動しましょ

移動するの巻。

setTransformでも行えるが、引数を簡略化した関数としてtranslateが用意されている。

translate(x, y)

HTML

<canvas id='canvas'></canvas>

JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = '#0000ff';
context.fillRect(10,10,50,100);
 
context.translate(50,0);
context.fillStyle = '#ff0000';
context.fillRect(10,10,50,100);
 
context.translate(50,0);
context.fillStyle = '#00ff00';
context.fillRect(10,10,50,100);
 
context.setTransform(1,0,0,1,0,0);

上記のコードをsetTransformを使うと以下の様になる。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = '#0000ff';
context.fillRect(10,10,50,100);
 
context.setTransform(1,0,0,1,50,0);
//context.translate(50,0);
context.fillStyle = '#ff0000';
context.fillRect(10,10,50,100);
 
context.setTransform(1,0,0,1,100,0);
//context.translate(50,0);
context.fillStyle = '#00ff00';
context.fillRect(10,10,50,100);
 
context.setTransform(1,0,0,1,0,0);

Canvas translate

translateを使うとMatrixが変更されてるので初期化せずに続けて使う時はそれを考慮して使用する。

update 2012-04-28
setTransform(Matrix)を理解するには野中先生のActionScriptの解説が良くわかります。
「変換行列」って聞くと数学嫌いにはちょっと手が出せない感じになりますが、丁寧に詳しく解説されているのでお勧めです。
ActionScriptと言ってもCanvas APIと同じように動作・使用できるので苦手意識をお持ちの方は是非お読みください。

変換行列を数学的に捉える
Matrixクラス
2次元平面の座標を変換する行列 - Matrixクラス
MatrixTransformerクラスによりインスタンスを任意の座標で回す
数学的なベクトルと行列からMatrix/Matrix3Dクラスを理解する

2012.04.25
17:11
author: taikiken
0件のコメント

Canvas始めました – 拡大・縮小とかやってみる

拡大・縮小するの巻。

setTransformでも行えるが、引数を簡略化した関数としてscale: 拡大・縮小が用意されている。

HTML

<canvas id='canvas'></canvas>

拡大(scale)
JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = '#0000ff';
context.fillRect(10,10,50,50);
 
context.setTransform(1,0,0,1,0,0);
context.scale(2,2);
context.fillStyle = '#ff0000';
context.fillRect(10,10,50,50);
 
context.setTransform(3,0,0,3,0,0);
context.fillStyle = '#00ff00';
context.fillRect(10,10,50,50);
 
context.setTransform(1,0,0,1,0,0);

canvas scale +

scale
horizontal scale:float, vertical scale:float

scaleさせるとPosition(x座標, y座標)値も同様にscaleされるので注意が必要。
context.setTransform(2,0,0,2,0,0) と context.scale(2,2)は等価。

縮小(scale)
JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = '#0000ff';
context.fillRect(10,10,150,150);
 
context.setTransform(1,0,0,1,0,0);
context.scale(0.5,0.5);
context.fillStyle = '#ff0000';
context.fillRect(10,10,150,150);
 
context.scale(0.5,0.5);
context.fillStyle = '#00ff00';
context.fillRect(10,10,150,150);
 
context.setTransform(1,0,0,1,0,0);

canvas scale -

setTransform(1,0,0,1,0,0)せずにscaleを続けると前回のscale値と掛け合わされるので注意。
まめにsetTransform(1,0,0,1,0,0)するが吉。

上記のコードをcontext.setTransform(1,0,0,1,0,0)を挟む形に書き換えると以下のようになる。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = '#0000ff';
context.fillRect(10,10,150,150);
 
context.setTransform(1,0,0,1,0,0);
context.scale(0.5,0.5);
context.fillStyle = '#ff0000';
context.fillRect(10,10,150,150);
 
context.setTransform(1,0,0,1,0,0);
context.scale(0.25,0.25);
context.fillStyle = '#00ff00';
context.fillRect(10,10,150,150);
 
context.setTransform(1,0,0,1,0,0);

以下の2つのコードは同じ結果になる。

context.setTransform(1,0,0,1,0,0);
context.scale(0.5,0.5);
context.scale(0.5,0.5);
context.setTransform(1,0,0,1,0,0);
context.scale(0.5,0.5);
 
context.setTransform(1,0,0,1,0,0);
context.scale(0.25,0.25);

2012.04.21
03:00
author: taikiken
1件のコメント

Canvas始めました – 矩形を回転させる

矩形を回転させるの巻。

Canvasでのオブジェクトの移動や回転はめんどい。
FlashのDisplayObjectを回転させるのに慣れているとなんでこんなに面倒なのかとぼやきたくなる。

まず描画した矩形を回転させるのではなく、回転しているのは描画のもとCanvasそのものだと考えるようにしました。

HTML

<canvas id='canvas'></canvas>

JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
 
context.save();
 
context.fillStyle = '#0000ff';
context.fillRect(100,100,50,50);
 
context.setTransform(1,0,0,1,0,0);
var radian = 45 * Math.PI / 180;
context.rotate(radian);
context.fillStyle = '#ff0000';
context.fillRect(100,100,50,50);
 
context.fillStyle = '#00ff00';
context.fillRect(200,200,50,50);
 
context.restore();

rotate後にfillRectした矩形は思いもよらないところに描かれてしまいます。

save, restore
saveは現在の状態を保存し、restoreで復元します。
データは配列状態で保存されるようでsaveでpushされrestoreでshiftされるみたいです。
なんかめんどくさい。

setTransformはActionScriptのMatrixに相当するものだと思います。
回転させる前にsetTransformで定義してrotateするのかな。

上記のコードでsave, restoreを使わないときはrestoreの所を次のようにすれば同じ結果になります。

context.setTransform(1,0,0,1,0,0);

context.rotate(0);
context.rotate(0); は必要ない。

後から描く赤い矩形を座標[100, 100]で回転させるには少々工夫が必要になります。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
 
context.save();
 
context.fillStyle = '#0000ff';
context.fillRect(100,100,50,50);
 
context.setTransform(1,0,0,1,0,0);
var radian = 45 * Math.PI / 180;
var x=100,y=100,w=50,h=50;
context.translate(x+0.5*w,y+0.5*h);
context.rotate(radian);
context.fillStyle = '#ff0000';
context.fillRect(-0.5*w,-0.5*h,w,h);
 
context.restore();

translateを使い移動させて回転させる。

ActionScriptでMatrixを使い中心点に関係なく回転させるやり方と同じ。

【回転】
Canvas state 保存
tarnsformation Matrixを初期化(identity)する, context.setTransform(1,0,0,1,0,0);
translateで移動
rotateで回転
fillRect座標を矩形の幅と高さの半分をネガティブ側へオフセットさせて描く
Canvas state  復元

【Matrix】関連関数
translate: 移動, rotate: 回転以外にscale: 拡大・縮小が用意されている。

【参考資料】
W3C: http://www.w3.org/TR/2010/WD-2dcontext-20100624/#transformations

MatrixはAdobeのActionScrit 3.0 リファレンスガイドが詳しい。
Matrix

update 2012-04-27
複数の矩形を回転させてみた。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
 
var x=20,y=20,w=50,h=50, r=15;
 
function circle (x, y) {
    var r = 10;
    context.beginPath();
    context.arc(x+r, y+r, r, (Math.PI/180)*0, (Math.PI/180)*360, false);
    context.fillStyle = 'yellow';
    context.fill();
 
    context.closePath();
    context.fillStyle = 'rgba(255,0,0,0.5)';
}
 
context.fillStyle = '#0000ff';
context.fillRect(x,y,w,h);
circle(x, y);
 
context.setTransform(1,0,0,1,0,0);
var radian = 45 * Math.PI / 180;
context.translate(x+0.5*w,y+0.5*h);
context.rotate(radian);
context.fillStyle = 'rgba(255,0,0,0.5)';
context.fillRect(-0.5*w,-0.5*h,w,h);
circle(-0.5*w,-0.5*h);
 
context.setTransform(1,0,0,1,0,0);
x += 100;
context.translate(x+0.5*w,y+0.5*h);
context.rotate(90 * Math.PI / 180);
context.fillRect(-0.5*w,-0.5*h,w,h);;
circle(-0.5*w,-0.5*h);
 
context.setTransform(1,0,0,1,0,0);
x += 100;
context.translate(x+0.5*w,y+0.5*h);
context.rotate(135 * Math.PI / 180);
context.fillRect(-0.5*w,-0.5*h,w,h);
circle(-0.5*w,-0.5*h);
 
context.setTransform(1,0,0,1,0,0);
x += 100;
context.translate(x+0.5*w,y+0.5*h);
context.rotate(180 * Math.PI / 180);
context.fillRect(-0.5*w,-0.5*h,w,h);
circle(-0.5*w,-0.5*h);
 
context.setTransform(1,0,0,1,0,0);

canvas rotates

lighter

2012.04.20
12:22
author: taikiken
0件のコメント

Canvas始めました – 図形の重なり描画方法を設定する

context.globalCompositeOperationを使った重なり描画方法。

Photoshopレイヤーの「合成」みたいなもんかなぁ。
Canvasにはレイヤー概念はないので後に描いたものが上に乗っかる。
初期Photoshop時代のレイヤーが無くて、描けばその時点でそれ以前に存在した画像と一体化し一枚のBitmapになったのを思い出します。
イメージ > 演算 を使って様々な効果をつけてたけどそんな感じもする。

globalCompositeOperationはプロパティ。文字列:String を与える。

Default: source-over
globalCompositeOperationで”source-over”以外を与えたら必要がなくなったら”source-over”を再設定しないと前の設定が残っちゃう。

source-over, source-atop, source-in, source-out,
destination-over, destination-atop, destination-in, destination-out,
lighter, copy, xor

11種類の設定ができる。
続きを読む →

2012.04.19
19:45
author: taikiken
2件のコメント

LaunchBar 5.2(909)で日本語ファイル名アプリを表示する

ランチャーアプリとしてLaunchBarを愛用しています。

昨日LaunchBarをアップデートすると今までsearchで表示できていた「日本語ファイル名」アプリが表示されなくなりました。
検索文字として日本語はもともと入力できないのですが、例えば「辞書」だと”D”とタイプすると候補リストに出てくるので矢印キーで選択して[enter]で起動可能でした。

LaunchBar5.2(909)にアップデートすると突然表示されなくなりました。
サポートにバグではないかとメールをすると迅速に丁寧なメールが返信されました。

LaunchBar > Preference > Advanced
“Append English filename if different from localized name”にチェック

これで今まで通りに”D”で「辞書」が候補に出るようになりました。
感謝!

LaunchBarはランチャーだけでなくクリップボード・マネージメントなど優れた機能をもつアプリでお勧めです。
http://www.obdev.at/products/launchbar/index.html

2012.04.19
14:36
author: taikiken
0件のコメント

Canvas始めました – 円を描いてみる

円を描くの巻。

HTML

<canvas id='canvas'></canvas>

JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
 
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#ff0000';
context.arc(100,50,40,(Math.PI/180)*0,(Math.PI/180)*360,false);
context.stroke();
context.closePath();

beginPathからclosePathの間にコードを書く。

arc
x position:int, y position:int, radius:uint, 開始角度(radians), 終点角度(radians), 描画方向

円の内側を塗る

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
 
context.beginPath();
context.lineWidth = 8;
context.strokeStyle = '#ff0000';
context.arc(100,50,40,(Math.PI/180)*0,(Math.PI/180)*360,false);
context.stroke();
 
context.fillStyle = '#333333';
context.fill();
 
context.closePath();

塗りは fillStyle で色を設定して fill() を実行する。

描画方向
false

context.arc(100,50,40,(Math.PI/180)*0,(Math.PI/180)*90,false);
Canvas arc false

Canvas arc false

true

context.arc(100,50,40,(Math.PI/180)*0,(Math.PI/180)*90,true);
Canvas arc true

Canvas arc true

flaseで時計回り。
trueで反時計回り。

W3C
http://www.w3.org/TR/2010/WD-2dcontext-20100624/#dom-context-2d-arc

2012.04.19
02:18
author: taikiken
1件のコメント

Canvas始めました – キャプチャ画像を書出し

Canvasをキャプチャして画像書出しするの巻。

HTML

<canvas id='canvas'></canvas>

JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = "#ff0000";
context.fillRect(50,30,250,100);
 
window.open(canvas.toDataURL(),
    "canvasOutput","left=0,top=0,
    width="+canvas.width+",height="+canvas.height+",
    toolbar=0,resizable=0");

toDataURL([data Type:String]):String
data TypeデフォルトはPNG, image/png

戻り値(Data URI形式)
data:image/png;base64,…

書出し画像タイプはPNGとJPEGが選択可能。
[PNG]
toDataURL() と toDataURL(‘image/png’) は等価。
[JPEG]
toDataURL(image/jpeg[, 圧縮率:float 0.0 ~ 1.0])
JPEG書出しのときは引数が2つ。
第2引数はオプション。

画像の書出しは驚くほど簡単。
Data URIのおかげ、ネイティブ実装ってステキ。

W3C
http://www.w3.org/TR/2011/WD-html5-20110405/the-canvas-element.html

2012.04.18
11:26
author: taikiken
0件のコメント

Canvas始めました – 画像を読込んで表示

外部画像を読込んで表示するの巻。

HTML

<canvas id='canvas'></canvas>

JavaScript

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
 
var img = new Image();
img.src = 'images/example.png';
img.onload = function () {
    context.drawImage(img,0,0);
}

Image instance imgを作成
img srcプロパティに画像パスを設定
画像のonload後にCanvasへ描画

drawImage
Image instance:Image, x position:int, y position:int

*drawImageの引数はなんかめんどくさい
http://www.w3.org/TR/2010/WD-2dcontext-20100624/#images

context . drawImage(image, dx, dy)
context . drawImage(image, dx, dy, dw, dh)
context . drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)

引数の数でできることが変わる、Cのオーバーロード(だったっけ)みたいなんかなぁ。
表示をクロップさせたり、スケールさせたりできるみたい。

Note: This specification does not define the algorithm to use when scaling the image, if necessary.

でもこんな注意書きがあるから画質の保証は無いらしい。
スケールは避けた方が良さげかな。