解放区在住氷翠 緑の閃光
【解放区在住氷翠】氷翠のお気楽日記

キーワードはWEBGLとJQUERY

2015-10-01

こんにちは、氷翠です。

いやもう、忘れないうちにメモっておこうかと思って。

現在、WEBサイトの中で大きな画像を表示、それをドラッグによって自由に動かし、マウスホイールで拡大縮小ができるようにしたい。

これが希望。

とりあえず、HTMLの中には、

<div class="ad_all">
    <div class="ad-left">
        <div class="frames">
            <canvas id="koukoku"></canvas>
        </div>
    </div>
    <div class="ad-right">
        <div class="ad-right-inner">
            <h3>リスト</h3>
            <ul>
                <li url="画像名" zoom="拡大率">画像の名称</li>
                <li url="画像名" zoom="拡大率">画像の名称</li>
                <li url="画像名" zoom="拡大率">画像の名称</li>
                <li url="画像名" zoom="拡大率">画像の名称</li>
            </ul>
        </div>
    </div>
</div>

こんな感じになっています。
「ad-right-inner」の下にある「li」タグをクリックすると、画像が表示される仕組み。
その画像を拡大、縮小などさせたい、。

まずは、画像をここに表示されるように。差表示させる先は「.ad-left」の中にある「CANVAS」に画像を反映させる。これをJavascriptで組んでいくしかない。
さらに、Queryのなかでいろんなメソッドを使いたいので、

jquery-2.1.4.min.js

を用意。さらに画像はドラッグによる移動ができるようにしないといけないので、

jquery-ui.min.js

も準備しておく。
画像はマウスのホイールで拡大縮小をさせたいので、

jquery.mousewheel.js

というプラグインも準備。とりあえず、あとはプログラムでなんとかなる。

基本的にJqueryの様式で記述する。で、クリックなどのイベントもJqueryで行うため、

$(function(){
    ~~~
});

これを記述しておく。この中でプログラムを書いていく。

まずはリストをクリックしたときの動きとしては…
イベントが「クリック」だということ。
次に、画像はWEBGLを利用するということで、「<canvas>タグ」を使います。
実際には、この「canvas」に画像を貼りつけて、このタグを動かすという理屈。

$(".ad-right li").click(function(){
    imgFile = "image.jpg?" + new Date().getTime();
    sizeWH  = $(this).attr("zoom");
    x = 0;
    y = 0;
    $('<img/>').attr('src', imgFile)
        .load(function() {
            images = new Image();
            images.src = imgFile;
            total = images.length;
            console.log(imgFile + "/loading complete.");
            var img = new Image();
            img.src = imgFile;
            var w = 0, h = 0;
            w = img.naturalWidth;
            h = img.naturalHeight;
            if(img.naturalWidth === undefined){
                w = img.width;
                h = img.height;
            }
            canvas = document.getElementById('koukoku');
            $("#koukoku").css({"top":0, "left":0});
            newW = w * sizeWH;
            newH = h * sizeWH;
            canvas.width = newW;
            canvas.height = newH;
            var frameWidth  = $(".frames").width();
            var frameHeight = $(".frames").height();
            x = (frameWidth / 2) - (newW / 2);
            y = (frameHeight / 2) - (newH / 2);
            console.log(frameWidth + "/" + frameHeight);
            var ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0, newW, newH);
            $(canvas).draggable({
                scroll: true,
                cursor: "crosshair"
            });
       });
});

これがCanvasに画像を貼りつけるプログラム。意外と短い。
で、最後のほうにある四行、「$(canvas).draggable…」の部分が画像を動かすためのメソッド。

$(".frames").mousewheel(function(eo, delta, deltaX, deltaY) {
    if(eo.preventDefault) { eo.preventDefault(); }
    // 元画像の実際の大きさ
    var w, h;
    w = images.naturalWidth;
    h = images.naturalHeight;
    if(images.naturalWidth === undefined){
        w = images.Width;
        h = images.Height;
    }
    console.log("orig size w = " + w + " / h =" + h);
    console.log("deltaY : " + deltaY);
    var dummySize = (deltaY / 10); // 倍率
    console.log("dummySize : " + dummySize);
    var size = parseFloat(sizeWH) + dummySize;
    console.log("sizeWH : " + sizeWH); // 最初のサイズ指定
    console.log("size = " + size); // これから変更するサイズ
    var newW = w * size; // 元のサイズから計算する
    var newH = h * size;
    console.log("new size w : " + newW + " / h : " + newH);
    sizeWH = size;
    console.log("new sizeWH : " + sizeWH); // 変更後のサイズ
    if(sizeWH > maxS || sizeWH < minS) {
        if(sizeWH > maxS) { sizeWH = maxS; } else { sizeWH = minS; }
        console.log("max over or min under");
    }
    console.log("top : " + $("canvas").css("top") + " / left : " + $("canvas").css("left"));
    var top = $("canvas").css("top");
    var left = $("canvas").css("left");
    canvas.width  = newW; // 新しいキャンバスの大きさ
    canvas.height = newH;
    console.log("canvas size w : " + canvas.width + " / h : " + canvas.height);
    img = new Image();
    img.src = images.src;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(img, 0, 0, newW, newH); // 新しい大きさで再描画
    console.log("=======================================================================================");
});

そして、これがマウスホイールを動かしたときのプログラム。ホイールを回したとき、イベントの返り値は「1」か「-1」が返ってくる。この返り値を利用して、画像を再描画させるというもの。
そのため、最後の方にある「img = new Image();」の以降は最初の記述と同じものだ。ただ表示させる大きさが違うというだけ。

ちなみに、ところどころにある「console.log();」というのは、ブラウザのコンソールに文字列を出力させるもの。
途中で値がどのようになっているのかを確認するためにこうして出力しているだけです。
これを見ながらだと処理はおそくなるのだけど、隠せば、通常通りの処理速度になるのであまりきにすることもありません。

でも、ここまではできましたが、まだ不完全なもの。
氷翠が完全と思えるところまではまだ先がありそうなのです。

追加

実は、画像をドラッグした後に拡大縮小をしようとしても何も起こらない、画像が荒くなったりといった変化があるだけ…これではなんの意味もない。
で、つい先ほど解決。

実はドラッグしたときに、Jqueryのほうで、このCanvasタグのstyle属性にwidthとheightが設定されてしまう。これが拡大縮小をしても大きさが変化しない、画像が荒くなったりする原因だったのです。

そこで、拡大縮小をするとき、上記のプログラムでいうと、

if(eo.preventDefault) { eo.preventDefault(); }

この部分、これはこれ以降のプログラムを実行するとき、それ以外のアクションの実行を止めるというもの。つまり、これを使って、マウスホイールを動かしたときに、画面がスクロールしてしまうのを防いでいたのです。
この次の行で

$(canvas).css({"width":"", "height":""});

canvasタグのstyle属性の中にあるwidthとheightをなくしてしまう。
単純に考えると、これさえなければいいのです。だからなくしてしまう。
そうすれば、ホイールしてもスクロールせず、拡大縮小が優先される。

そんなわけでようやく出来上がった!

コメントを残す

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