drag and drop multiple images from one canvas to other

前端 未结 1 1744
野的像风
野的像风 2021-01-07 16:07

How do I drag and drop multiple images from one canvas to another? My manager has given me this task, it\'s been 3 days and I am not able to do this as I\'m new to HTML5. I\

相关标签:
1条回答
  • 2021-01-07 16:34

    Drag/Drop multiple items between 2 canvases

    Here’s what the code does:

    • Click to select one or more images from the top source canvas
    • Click an image again to toggle its selection on/off
    • Once you have made all your selections, drag from the top canvas to the bottom canvas
    • Your selections will be moved to the bottom canvas

    enter image description here

    Some explanation about the code:

    • Each image is stored in an array called Images
    • An item-object for each image is stored in an array called items
    • The item-object contains an item’s description, image-url, an isSelected flag and an isDropped flag.
    • The mouseup event handler of the top source canvas checks for hits on images and toggles their isSelected flags.
    • The mouseup event handler responds to drops onto the bottom drop canvas. It checks for selected items and records them as dropped by setting their isDropped flags.
    • The drawContainer function distributes items between the source and drop canvas based on their isDropped flags (isDropped==false are drawn in the top source canvas – isDropped==true are drawn in the bottom drop canvas)

    Here is code and a Fiddle: 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>
    

    [Addition: Alternate code to sort bottom canvas by order dropped]

        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();
        }
    

    [ Edited to present a solution in KineticJS ]

    Here is code and a Fiddle: 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>
    
    0 讨论(0)
提交回复
热议问题