0

如何将多个图像从一个画布拖放到另一个画布?我的经理给了我这个任务,已经 3 天了,我无法做到这一点,因为我是 HTML5 的新手。我已经搜索了谷歌,但只适用于一张图片。请在这件事上帮助我。

这是我从一张图片中得到的:

<pre>
<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
            context1.clearRect(0,0,canvas1.width,canvas1.height);
            context2.clearRect(0,0,canvas2.width,canvas2.height);

            //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    = 'images/logo.png';
        state.offsetX      = 0;
        state.offsetY      = 0;


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

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

1 回答 1

2

在 2 个画布之间拖放多个项目

以下是代码的作用:

  • 单击以从顶部源画布中选择一个或多个图像
  • 再次单击图像以打开/关闭其选择
  • 完成所有选择后,从顶部画布拖动到底部画布
  • 您的选择将移动到底部画布

在此处输入图像描述

关于代码的一些解释:

  • 每个图像都存储在一个名为 Images 的数组中
  • 每个图像的 item-object 存储在一个名为 items 的数组中
  • item-object 包含一个 item 的描述、image-url、一个 isSelected 标志和一个 isDropped 标志。
  • 顶部源画布的 mouseup 事件处理程序检查图像上的命中并切换它们的 isSelected 标志。
  • mouseup 事件处理程序响应拖放到底部放置画布上。它检查选定的项目并通过设置它们的 isDropped 标志将它们记录为已丢弃。
  • drawContainer 函数根据它们的 isDropped 标志在源画布和放置画布之间分配项目(isDropped==false 在顶部源画布中绘制 - isDropped==true 在底部放置画布中绘制)

这是代码和小提琴:http: //jsfiddle.net/m1erickson/3KqgX/

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

<style>
    body{ background-color: ivory; padding:10px; }
    canvas{border:1px solid red;}
    #canvas { 
    }
    #canvas:active { 
        cursor: move;
    }
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var drop=document.getElementById("dropzone");
    var dropCtx=drop.getContext("2d");

    var canvasOffset=$("#canvas").offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;

    var mouseIsDown=false;
    var frameWidth=128;
    var frameHeight=128;
    // checkmark for selected
    var checkmark=document.createElement("img");
    checkmark.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/smallCheckmark.png";

    var images=[];
    var items=[];
    items.push({description:"House#1",url:"https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house1.jpg",isSelected:false,isDropped:false,x:0,y:0});
    items.push({description:"House#2",url:"https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house2.jpg",isSelected:false,isDropped:false,x:0,y:0});
    items.push({description:"House#3",url:"https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house3.jpg",isSelected:false,isDropped:false,x:0,y:0});


    var imgLoadCount=0;
    for(var i=0;i<items.length;i++){
        images[i]=document.createElement("img");
        images[i].onload=function(){
            if(++imgLoadCount>=items.length){ draw(); }
        }
        images[i].src=items[i].url;
    }

    function draw(){

        ctx.clearRect(0,0,canvas.width,canvas.height);
        dropCtx.clearRect(0,0,drop.width,drop.height);

        var canvasX=0;
        var dropX=0;
        // 
        for(var i=0;i<items.length;i++){
            if(items[i].isDropped){
                x=dropX*160+10;
                drawContainer(dropCtx,i,x,20);
                dropX++;
                items[i].x=x;
            }else{
                x=canvasX*160+10;
                drawContainer(ctx,i,x,20);
                canvasX++;
                items[i].x=x;
            }
        }
    }


    // draw image container
    function drawContainer(context,index,x,y){

        context.beginPath();
        context.rect(x,y+frameHeight,frameWidth,30);
        context.fillStyle="black";
        context.fill();
        context.beginPath();
        context.fillStyle="white";
        context.font="10pt Verdana";
        context.fillText(items[index].description,x+10,y+frameHeight+18);

        // draw a thumbnail of the image
        var img=images[index];
        if(img.width>=img.height){
            context.drawImage(img,0,0,img.width,img.height,
                x,y,128,128*img.height/img.width);
        }else{
            context.drawImage(img,0,0,img.width,img.height,
                x,y,128*img.width/img.height,128);  // edited s/b [,128], not [/128]
        }

        // outer frame (green if selected)
        context.beginPath();
        context.rect(x-2,y-2,frameWidth+4,frameHeight+30+4);
        context.lineWidth=3;
        context.strokeStyle="lightgray";
        if(items[index].isSelected){
            context.strokeStyle="green";
            context.drawImage(checkmark,x+frameWidth-30,y+frameHeight+3);
        }
        context.stroke();

    }

    function handleMouseDown(e){
        mouseX=parseInt(e.clientX-offsetX);
        mouseY=parseInt(e.clientY-offsetY);

        // Put your mousedown stuff here
        mouseIsDown=true;
    }

    function handleMouseUp(e){
      mouseIsDown=false;
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseup stuff here
      for(var i=0;i<items.length;i++){
          var item=items[i];
          // have we clicked on something?
          if(!item.isDropped && mouseX>=item.x && mouseX<=item.x+frameWidth){
              // if so, toggle its selection
              items[i].isSelected=!(items[i].isSelected);
              draw();
          }
      }
    }

    function handleMouseOut(e){
      if(!mouseIsDown){return;}
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mouseOut stuff here
    }

    function handleMouseMove(e){
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousemove stuff here

    }

    function handleDrop(e){
        for(var i=0;i<items.length;i++){
            if(items[i].isSelected){
                items[i].isDropped=true;
                items[i].isSelected=false;
                console.log(i);
            }
        }
        draw();
    }

    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});
    $("#dropzone").mouseup(function(e){handleDrop(e);});

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

</head>

<body>
    <p>Click an item to toggle it's selection</p>
    <p>Drag from top to bottom canvas to drop selected items</p>
    <canvas id="canvas" width=500 height=200></canvas><br>
    <canvas id="dropzone" width=500 height=200></canvas>
</body>
</html>

[补充:按删除顺序对底部画布进行排序的替代代码]

    function handleDrop(e){
        for(var i=items.length-1;i>=0;i--){
            if(items[i].isSelected){
                items[i].isDropped=true;
                items[i].isSelected=false;
                // sort the bottom canvas by order dropped
                var move=items[i];
                items.splice(i,1);
                items.push(move);
            }
        }
        draw();
    }

[编辑以在 KineticJS 中提出解决方案]

这是代码和小提琴:http: //jsfiddle.net/m1erickson/bSpBF/

<!DOCTYPE html>
<html>
<head>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>
<style>
    body{ background-color: ivory; padding:10px;}
    #container1,#container2{
      border:solid 1px #ccc;
      margin-top: 10px;
      width:300px;
      height:100px;
    }
    #container2{
      height:300px;
    }
</style>        
<script>
$(function(){

    var highlightWidth=8;

    var stage = new Kinetic.Stage({
        container: 'container1',
        width: 300,
        height: 100
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);


    var dropzone = new Kinetic.Stage({
        container: 'container2',
        width: 300,
        height: 300
    });
    var dropLayer = new Kinetic.Layer();
    dropzone.add(dropLayer);


    // these must go after the creation of stages & layers
    addBackground(stage,layer,dropLayer);
    layer.draw();
    addBackground(dropzone,dropLayer,layer);
    dropLayer.draw();


    // get images & then trigger start()
    var images={};
    var URLs = {
      house1: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg',
      house2: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg',
      house3: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg'
    };
    loadImages(URLs,start);


    function start(){
        var house1=kImage(images.house1,10,10,50,50,layer);
        var house2=kImage(images.house2,75,10,50,50,layer);
        var house3=kImage(images.house3,140,10,50,50,layer);
        layer.draw();
    }


    function swapStagesIfSelected(sourceLayer,destinationLayer,startX,startY){

        // get all elements on the source layer
        var elements=sourceLayer.get("Image");

        // don't let dropped elements fall off the stage
        var totalWidth=0;
        var maxHeight=-999;
        var layerWidth=destinationLayer.getStage().getWidth();
        var layerHeight=destinationLayer.getStage().getHeight();
        for(var i=0;i<elements.length;i++){
            if(elements[i].isSelected){
                totalWidth+=elements[i].getWidth();
                maxHeight=Math.max(elements[i].getHeight(),maxHeight);
            }
        }
        if(startX+totalWidth>layerWidth){
            startX=layerWidth-totalWidth-15; 
        }
        if(startY+maxHeight>layerHeight){
            startY=layerHeight-maxHeight-15; 
        }

        // move all selected images 
        // to the clicked x/y of the destination layer
        for(var i=0;i<elements.length;i++){
            var element=elements[i];
            if(element.isSelected){
                var img=element.getImage();
                kImage(img,startX,startY,element.getWidth(),element.getHeight(),destinationLayer);
                startX+=element.getWidth()+10;
                element.remove();
            }
        }
        sourceLayer.draw();
        destinationLayer.draw();
    }


    // build the specified KineticJS Image and add it to the specified layer
    function kImage(image,x,y,width,height,theLayer){
        var image=new Kinetic.Image({
            image:image,
            x:x,
            y:y,
            width:width,
            height:height,
            strokeWidth:0.1,
            stroke:"green",
            draggable:true
        });
        image.myLayer=theLayer;
        image.isSelected=false;
        image.on("click",function(){
            highlight(this);
            this.myLayer.draw();
        });
        image.myLayer.add(image);
        return(image);
    }


    // build a background image and add it to the specified stage
    function addBackground(theStage,theLayer,otherLayer){

        var background = new Kinetic.Rect({
          x: 0,
          y: 0,
          width: theStage.getWidth(),
          height: theStage.getHeight(),
          fill: "white",
          stroke: "green",
          strokeWidth: 1
        });
        background.on("click",function(){
            var pos=theStage.getMousePosition();
            var mouseX=parseInt(pos.x);
            var mouseY=parseInt(pos.y);
            swapStagesIfSelected(otherLayer,theLayer,mouseX,mouseY);
        });
        theLayer.add(background);
    }


    /////////////  Image loader

          function loadImages(URLs, callback) {
            var loaded = 0;
            var needed = 0;
            for(var url in URLs) { needed++; console.log(url); }
            for(var url in URLs) {
              images[url] = new Image();
              images[url].onload = function() {
                if(++loaded >= needed) {
                  callback(images);
                }
              };
              images[url].src = URLs[url];
            }
          }

    /////////////  Toggle Highlighting

    function highlight(element,setStrokeWidth){
        if(setStrokeWidth){
                element.setStrokeWidth(setStrokeWidth);
        }else{
            if(element.getStrokeWidth()>5){
                element.setStrokeWidth(0.1);
                element.isSelected=false;
            }else{
                element.setStrokeWidth(highlightWidth);
                element.isSelected=true;
            }
        }
    }


}); // end $(function(){});

</script>       
</head>

<body>
    <p>Click on image(s) to toggle selection</p>
    <p>Then click in the other canvas to drop</p>
    <div id="container1"></div>
    <div id="container2"></div>
    <button id="clear">Clear Hightlights</button>
    <button id="swap">Swap Selected</button>
</body>
</html>
于 2013-06-22T00:32:45.583 回答