JavaScript で Number を拡張して色を扱えるようにする方法

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

最近, カラーコードを素敵に扱うビット演算という記事を見つけて ふと昔作ってたやつを思い出したのでサンプルとしてざっくりとまとめてみました.

SAMPLE

今回制作したサンプルはこちらです.

CODE

<!DOCTYPE html> 
<html lang="ja"> 
    <head> 
        <meta charset="utf-8"> 
        <title>Number を拡張して色を扱えるようにする方法</title>
        
        <script>
            
            (function(){
                Number.prototype.getA = function() {
                    // ここキモ
                    return (this & 0xff000000) >>> 24;
                };
                Number.prototype.getR = function() {
                    return (this & 0xff0000) >> 16;
                };
                Number.prototype.getG = function() {
                    return (this & 0xff00) >> 8;
                };
                Number.prototype.getB = function() {
                    return (this & 0xff);
                };
                Number.prototype.toCSSValueRGB = function() {
                    return "rgb("+ this.getR() +","+ this.getG() +","+ this.getB() +")";
                };
                Number.prototype.toCSSValueRGBA = function() {
                    return "rgba("+ this.getR() +","+ this.getG() +","+ this.getB() +","+ this.getA() +")";
                };
            })();
            
            window.onload = function() {
                var white = 0xffffffff;
                console.group("white");
                console.log(white.toCSSValueRGB()); // rgb(255,255,255)
                console.log(white.toCSSValueRGBA());// rgba(255,255,255,255)
                console.groupEnd();
                
                var red = 0xf0ff0000;
                console.group("red");
                console.log(red.toCSSValueRGB());   // rgb(255,0,0)
                console.log(red.toCSSValueRGBA());  // rgba(255,0,0,240)
                console.groupEnd();
                
                var green = 0x0f00ff00;
                console.group("green");
                console.log(green.toCSSValueRGB());   // rgb(0,255,0)
                console.log(green.toCSSValueRGBA());  // rgba(0,255,0,15)
                console.groupEnd();
                
                var blue = 0x000000ff;
                console.group("blue");
                console.log(blue.toCSSValueRGB());   // rgb(0,0,255)
                console.log(blue.toCSSValueRGBA());  // rgba(0,0,255,0)
                console.groupEnd();
            };
            
        </script>

    </head>
    
    <body>
        <h1>Number を拡張して色を扱えるようにする方法</h1>
    </body>
</html>

TIPS

Number を拡張

数値は内部的に Number クラスとして扱われています. なので, Number.prototype を拡張することで数値にメンバを追加することができます.

上手く使えば色々と便利になります. ですが, 1つだけ注意点. Number はコアなクラスなので拡張するメンバが重複していないか 必ずチェックしましょう. さっそくサンプルではそんなの無視していますが…

singed 32bit を unsigned 32bit に変換する

JavaScript では 整数は基本32bitとして扱われます. そのため 0xf0000000 のような先頭ビットが立った値を代入すると 負数になったりします.

今回は 32bit フルに使って色を表現しているので普通にビット演算でアルファ値を取得しても正常な値を取得することができません.

そこで使うのが 符号なし右シフト演算子(>>>)です.下記のように0ビットでこの演算子を使えば値を変えずに, unsigned 32bit に変換することができます.

var color = 0xf0f0f0f0;
color = color >>> 0;

今回のサンプルでは, getA メソッドで符号なし右シフト演算子を使用しています.

この仕様はあまり知られていないのか, 結構ネット上で間違ってるサンプルが転がってたりします. ご注意を.

DOM との連携

サンプルで toCSSValueRGB と toCSSValueRGBA というメソッドを追加しています.

これを要素のスタイルに代入すれば簡単に色として設定することが可能です.

elm.style.color = (0xffff0000).toCSSValueRGBA();

Reference

こういうの作ってると Win API とか DirectX 使ってた頃を思い出すなぁ~. まぁ仕事柄, 今でもたまに(嫌々)使うこともあるんですけどね.

近々ゲーム系のそこそこ大きめのライブラリを公開予定です. よかったら遊んで下さい.

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT