HTML5 Canvas Drag and Drop Item

2019-09-07 01:29发布

Been struggling to get this work work. Here's my code:

<canvas id="graphCanvas" ondrop="drop(event)" ondragover="allowDrop(event)" height=600 width=1000 style="border:1px solid #000000;"></canvas>
                        <img id="img1" src="./images/arrow_up.svg" draggable="true" onmousedown="get_pos(event)" ondragstart="drag(event)"/>
                    <script type="text/javascript">
                        function init() {
                            var canvas = document.getElementById("graphCanvas");
                            var context = canvas.getContext("2d");

                            context.lineWidth = 2;
                            }
                            var pos;
                            function allowDrop(ev) {
                                ev.preventDefault();
                            }
                            function get_pos(ev){
                                pos = [ev.pageX, ev.pageY];
                            }
                            function drag(ev) {
                                ev.dataTransfer.setData("Text",ev.target.id);
                            }

                            function drop(ev) {
                                ev.preventDefault();
                                var offset = ev.dataTransfer.getData("text/plain").split(',');
                                var data=ev.dataTransfer.getData("Text");

                                var img = canvas = document.getElementById("img1");
                                var dx = pos[0] - img.offsetLeft;
                                var dy = pos[1] - img.offsetTop;
                                document.getElementById("graphCanvas").getContext("2d").drawImage(document.getElementById(data), ev.pageX - dx, ev.pageY - dy);
                            }
                    </script>

It's suppose to be a draggable image that I can drop into a canvas. Once the image is in the canvas, the user can then move that image around. Unfortunately I can not seem to get it work. The image should appear if you drop it in near the top left, but the image appears near the bottom right.

How can I fix this problem?

1条回答
老娘就宠你
2楼-- · 2019-09-07 02:20

You can use html5 draggable to drop an image element on canvas.

Then you can drawImage a copy of that image on the canvas.

You need this info to draw a copy of the draggable image on the canvas:

  • The mouse position relative to the draggable image (see mousedown below)

  • The canvas position relative to the document (canvasElement.offsetLeft & canvasElement.offsetTop).

  • The mouse position relative to the document at the drop ( dropEvent.clientX & dropEvent.clientY )

  • The Id of the draggable element (stored and retrieved in dragEvent.dataTransfer)

With this info you can drawImage a copy of the draggable element like this:

function drop(ev) {
    ev.preventDefault();

    var dropX=ev.clientX-canvasLeft-startOffsetX;
    var dropY=ev.clientY-canvasTop-startOffsetY;
    var id=ev.dataTransfer.getData("Text");
    var dropElement=document.getElementById(id);

    // draw the drag image at the drop coordinates
    ctx.drawImage(dropElement,dropX,dropY);
}

Here's example code and a Demo: http://jsfiddle.net/m1erickson/WyEPh/

<!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:20px; }
    #graphCanvas{border:1px solid #000000;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("graphCanvas");
    var ctx=canvas.getContext("2d");
    var canvasLeft=canvas.offsetLeft;
    var canvasTop=canvas.offsetTop;
    canvas.ondrop=drop;
    canvas.ondragover=allowDrop;
    //
    var img=document.getElementById("img1");
    img.onmousedown=mousedown;
    img.ondragstart=dragstart;

    // this is the mouse position within the drag element
    var startOffsetX,startOffsetY;

    function allowDrop(ev) {
        ev.preventDefault();
    }

    function mousedown(ev){
        startOffsetX=ev.offsetX;
        startOffsetY=ev.offsetY;
    }

    function dragstart(ev) {
        ev.dataTransfer.setData("Text",ev.target.id);
    }

    function drop(ev) {
        ev.preventDefault();

        var dropX=ev.clientX-canvasLeft-startOffsetX;
        var dropY=ev.clientY-canvasTop-startOffsetY;
        var id=ev.dataTransfer.getData("Text");
        var dropElement=document.getElementById(id);

        // draw the drag image at the drop coordinates
        ctx.drawImage(dropElement,dropX,dropY);
    }


}); // end $(function(){});
</script>
</head>
<body>
    <canvas id="graphCanvas" height=300 width=300></canvas>
    <img id="img1" src="house32x32.png" draggable="true" />        
</body>
</html>

However...images drawn on the canvas are just painted pixels and therefore not draggable

You can use a canvas library like KineticJS to create "retained" images that can be dragged after they are drawn on the canvas.

Here's a Demo using KineticJS to allow dropped images to later be dragged around the canvas:

http://jsfiddle.net/m1erickson/LuZbV/

查看更多
登录 后发表回答