0

コードを手動で編集するのではなく、ボタンをクリックするだけでキャンバスに新しい画像を生成できるようにしたいと考えています。

複数のキャンバス間で画像をドラッグ アンド ドロップできるようにする次の HTML5/JavaScript コードがあり、必要なものに完全に対応しています。

私がやっていること:

<canvas style="float: left" height="125" width="400" id="cvs1">[No canvas support]</canvas>
<canvas style="float: left; margin-left: 100px" height="125" width="400" id="cvs2">[No canvas support]</canvas>

<script src="http://www.rgraph.net/libraries/RGraph.common.core.js" ></script>

<script>
    window.onload = function ()
    {
        var canvas1 = document.getElementById("cvs1");
        var canvas2 = document.getElementById("cvs2");
        var context1 = canvas1.getContext('2d');
        var context2 = canvas2.getContext('2d');
        var imageXY  = {x: 5, y: 5};




        /**
        * This draws the image to the canvas
        */
        function Draw ()
        {
            //Clear both canvas first
            canvas1.width = canvas1.width
            canvas2.width = canvas2.width
            
            //Draw a red rectangle around the image
            if (state && state.dragging) {
                state.canvas.getContext('2d').strokeStyle = 'red';
                state.canvas.getContext('2d').strokeRect(imageXY.x - 2.5,
                                                         imageXY.y - 2.5,
                                                         state.image.width + 5,
                                                         state.image.height + 5);
            }
            
            // Now draw the image
            state.canvas.getContext('2d').drawImage(state.image, imageXY.x, imageXY.y);
        }




        canvas2.onclick =
        canvas1.onclick = function (e)
        {
            
            if (state && state.dragging) {
                state.dragging = false;
                Draw();
                return;
            }





            var mouseXY = RGraph.getMouseXY(e);

            state.canvas    = e.target;
            
            if (   mouseXY[0] > imageXY.x
                && mouseXY[0] < (imageXY.x + state.image.width)
                && mouseXY[1] > imageXY.y
                && mouseXY[1] < (imageXY.y + state.image.height)) {

                state.dragging       = true;
                state.originalMouseX = mouseXY[0];
                state.originalMouseY = mouseXY[1];
                state.offsetX         = mouseXY[0] - imageXY.x;
                state.offsetY         = mouseXY[1] - imageXY.y;

            }
        }

        canvas1.onmousemove =
        canvas2.onmousemove = function (e)
        {

            if (state.dragging) {
            
                state.canvas = e.target;
                
                var mouseXY = RGraph.getMouseXY(e);
                
                // Work how far the mouse has moved since the mousedon event was triggered
                var diffX = mouseXY[0] - state.originalMouseX;
                var diffY = mouseXY[1] - state.originalMouseY;

                imageXY.x = state.originalMouseX + diffX - state.offsetX;
                imageXY.y = state.originalMouseY + diffY - state.offsetY;
                
                Draw();
                
                e.stopPropagation();
            }
        }

        /**
        * Load the image on canvas1 initially and set the state up with some defaults
        */
        state = {}
        state.dragging     = false;
        state.canvas       = document.getElementById("cvs1");
        state.image        =  new Image();
        state.image.src    = 'http://www.rgraph.net/images/logo.png';
        state.offsetX      = 0;
        state.offsetY      = 0;

        state.image.onload = function ()
        {
            Draw();
        }
    }
</script>

これは、このJS Fiddleでも見られます (注: ドラッグする前に画像をクリックする必要があります)。

私が抱えている問題:

キャンバスに画像を追加して、作成することを選択した多くのキャンバス間で任意の画像をドラッグ アンド ドロップできるようにしたいと考えています。

ページにキャンバスを簡単に追加してドラッグ アンド ドロップすることはできますが、キャンバスに画像を追加/生成する場合は、それを機能させることができません。

これを行うことができると考える唯一の方法は、Draw()追加されるすべての画像に対して関数を繰り返すことです。つまり、たとえば、30 個の画像を 10 個の異なるキャンバス間でドラッグ アンド ドロップできるようにするには、Draw()関数を 30 回繰り返す必要があります。確かにそれはこれを行うための最良の方法ではないでしょうか?

非常に明白な何かが欠けていない限り、これを行う別の方法がわかりませんか?

4

1 に答える 1

3

複数のオブジェクトを作成し、キャンバス間でクリック アンド ドラッグするようにコードを構成する方法を次に示します。

デモ: http://jsfiddle.net/m1erickson/Bnb6A/

ここに画像の説明を入力

新しいドラッグ可能なオブジェクトを作成し、すべての新しいオブジェクトを配列に配置するオブジェクト ファクトリ関数をコーディングします。

ドラッグ可能な各オブジェクトに関する次の情報を保持します。

  • このオブジェクトが現在ドラッグされているかどうかを示すドラッグ (true/false)
  • image: このオブジェクトの画像
  • x,y: このオブジェクトの現在の左上の位置
  • width,height: このオブジェクトのサイズ
  • offsetX,offsetY: このオブジェクトの左上を基準にしてマウスがクリックされた場所を示します
  • draw: (関数) このオブジェクトがそれ自体を描画できるようにします (ドラッグされている場合は、赤い四角形で囲まれます)

クリック時:

  • マウスの位置を取得する
  • 両方のキャンバスをクリア
  • オブジェクト配列を反復処理する
  • オブジェクトがドラッグされている場合は、ドラッグ フラグの設定を解除します
  • オブジェクトが選択されている場合は、ドラッグ フラグを設定し、このオブジェクトに対する開始マウス位置の offsetX、offsetY を設定します。
  • すべてのオブジェクトを再描画

マウス移動時:

  • マウスの位置を取得する
  • 両方のキャンバスをクリア
  • オブジェクト配列を反復処理する
  • オブジェクトがドラッグされている場合は、マウスの位置に移動します (x、y をオフセットに合わせて調整します)。
  • すべてのオブジェクトを再描画

コード:

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:20px; }
    canvas{ border: 1px solid #808080; }
</style>

<script>
    $(function(){

        var canvas1 = document.getElementById("cvs1");
        var canvas2 = document.getElementById("cvs2");

        var contexts=[];
        contexts.push(canvas1.getContext('2d'));
        contexts.push(canvas2.getContext('2d'));


        function clearAll(){
            //Clear both canvas first
            canvas1.width = canvas1.width
            canvas2.width = canvas2.width
        }

        canvas1.onclick=function(e){ handleClick(e,1); };
        canvas2.onclick=function(e){ handleClick(e,2); };
        //
        function handleClick(e,contextIndex){
            e.stopPropagation();

            var mouseX=parseInt(e.clientX-e.target.offsetLeft);
            var mouseY=parseInt(e.clientY-e.target.offsetTop);

            clearAll();

            for(var i=0;i<states.length;i++){

                var state=states[i];

                if(state.dragging){
                    state.dragging=false;
                    state.draw();
                    continue;
                }

                if ( state.contextIndex==contextIndex
                    && mouseX>state.x && mouseX<state.x+state.width
                    && mouseY>state.y && mouseY<state.y+state.height)
                {
                    state.dragging=true;
                    state.offsetX=mouseX-state.x;
                    state.offsetY=mouseY-state.y;
                    state.contextIndex=contextIndex;
                }

                state.draw();
            }
        }

        canvas1.onmousemove = function(e){ handleMousemove(e,1); }
        canvas2.onmousemove = function(e){ handleMousemove(e,2); }
        //
        function handleMousemove(e,contextIndex){
            e.stopPropagation();

            var mouseX=parseInt(e.clientX-e.target.offsetLeft);
            var mouseY=parseInt(e.clientY-e.target.offsetTop);

            clearAll();

            for(var i=0;i<states.length;i++){

                var state=states[i];

                if (state.dragging) {
                    state.x = mouseX-state.offsetX;
                    state.y = mouseY-state.offsetY;
                    state.contextIndex=contextIndex;
                }
                state.draw();
            }
        }


        var states=[];

        var img=new Image();
        img.onload=function(){
            states.push(addState(0,0,img));
        }
        img.src="http://www.rgraph.net/images/logo.png";




        function addState(x,y,image){
                state = {}
                state.dragging=false;
                state.contextIndex=1;
                state.image=image;
                state.x=x;
                state.y=y;
                state.width=image.width;
                state.height=image.height;
                state.offsetX=0;
                state.offsetY=0;
                state.draw=function(){
                    var context=contexts[this.contextIndex-1];
                    if (this.dragging) {
                        context.strokeStyle = 'red';
                        context.strokeRect(this.x,this.y,this.width+5,this.height+5)
                    }
                    context.drawImage(this.image,this.x,this.y);
                }
                state.draw();
                return(state);
        }

        $("#more").click(function(){
            states.push(addState(states.length*100,0,img));
        });


    }); // end $(function(){});
</script>

</head>

<body>
  <button id="more">Add Image</button><br>
  <canvas height="125" width="300" id="cvs1">[No canvas support]</canvas><br>
  <canvas height="125" width="300" id="cvs2">[No canvas support]</canvas>
</body>
</html>
于 2013-11-21T19:09:24.957 に答える