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/

在此处输入图像描述

编写一个对象工厂函数,该函数创建新的可拖动对象并将所有新对象放入一个数组中。

保留有关每个可拖动对象的信息:

  • dragging (true/false) 指示当前是否正在拖动此对象
  • 图像:此对象的图像
  • 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 回答