透過画像のアルファ値を検出するJavascript

透過PNGなどのアルファ値(透過度)を調べるJavascriptを作ってみました。

透過部分がどんなにあっても画像は矩形なので、リンクを付けたりした際、透過部分をクリックしても反応します。単純な図形ならイメージマップでリンクを設定することもできますが、その場合個別にエフェクトをかけたりができません。
(CSS3のborder-radiusを使えば丸みを制御することはできます。)

クリック領域が広いのは悪いことじゃないので、普通はそのままでも問題ないのですが、特殊なコンテンツなどで特定領域のみをクリックできるようにしたい(例えば「キャラクター画像をクリックしたら台詞をしゃべる」みたいな)、といったときにHTMLとCSSではどうしようありません。

なので、Javascriptでなんとかできないかなと思って作ってみました。
まずはサンプルをどうぞ。

See the Pen AlphaPicker Sample by uco (@escapism) on CodePen.9630

HTML5 Canvasの機能を利用しているので、Canvasに対応していないブラウザでは動きません。
最近のブラウザなら大抵動くと思います。

あと、同一生成元ポリシーのためローカルでは動きません。起動オプションを追加するなどの回避方法をとる必要があります。

使い方

まずは読み込みます。
jQueryなどのライブラリは必要ありません。

<script src="alphapicker.js"></script>

スクリプトを書いていきます。
なんらかの方法でimg要素を取得して、それをAlphaPicker()に渡してあげます。

/* IDで指定する場合の例 */
var img = document.getElementById("hoge"),
	alpha = AlphaPicker(img);

/* jQueryを使う場合の例 */
var img = $("img"),
	alpha = AlphaPicker(img[0]);

返ってくるAlphaPickerオブジェクトのメソッドを使って、クリック時の動作などを設定することが出来ます。

/* 非透過部をクリックするとアラートが出る例 */
alpha.click(function(e) {
	if(e.alpha) {
		alert("click!");
	}
});

AlphaPicker.click()はクリックイベントにイベントリスナを登録することができます。イベントリスナに渡されるイベントオブジェクトのalphaプロパティで、クリックした場所のアルファ値を0〜255の範囲で見ることができるので、この値で条件分岐させることで、透過していない場所だけ反応するようにしています。

jQueryのようにメソッドチェーンも可能です。

alpha.click(function(e) {
	if(e.alpha) {
		alert("click!");
	}
}).mousemove(function(e) {
	if(e.alpha) {
		this.className = "hover";
	} else {
		this.className = "";
	}
});

クリックイベントと同時に、マウスオーバー時にhoverクラスを付与するようにしています。リスナ内のthisは元のimg要素を指しています。

リスナ内で自己のAlphaPickerオブジェクトを参照したい場合は、イベントオブジェクトのalphaPickerプロパティで可能です。イベントオブジェクトには他にもいくつかプロパティがあるので、コンソールなどで覗いてください。

他にもAlphaPicker.contextでCanvasを操作したりもできますが、Canvasの話になってしまうので割愛します。以下に色を変換するサンプルを置いているので、気になる方はソースを見てみてください。

See the Pen Color Change with AlphaPicker by uco (@escapism) on CodePen.9630

メソッド

addEventListener(type, fn, useCapture) 使い方はDOMのaddEventListenerとほぼ同じです。useCaptureは省略可能です(省略時はfalse)。
removeEventListener(type, fn, useCapture) こちらもDOMのremoveEventListenerと同様ですが、AlphaPicker.addEventListenerで登録したイベントリスナーはこのAlphaPicker.removeEventListenerでないと削除できません。
load(fn)
click(fn)
mousedown(fn)
mouseup(fn)
mousemove(fn)
mouseout(fn)
それぞれAlphaPicker.addEventListener(***, fn)のショートカットです。
reset() AlphaPickerオブジェクトが保持する画像のサイズ等の情報をリセットします。
画像に変更を加えた場合等にリセットしないと、うまく動かない可能性があります。

同一の画像に対して複数のAlphaPickerオブジェクトを生成した場合、一方で追加したイベントリスナーを他方で削除できない問題があります。jQueryはこの辺をうまく処理しているみたい。うーん。

ダウンロード

コードとデモサンプルをZipでまとめてます。ご自由にどうぞ。
GitHubに置きました。
ライセンスはMITです。

GitHub

ちょっと改造すればカラーピッカーなんかも作れると思います。

どうでもいい話

艦これで艦娘つついてるときに思いつきました。

雲龍さんの細かい式神もしっかり反応します

前はクリック領域が矩形だったはずなんですが、いつの間にかマスクされるようになってたんですよね。
Flashだとこういう処理は簡単なんでしょうか?

Comments