原文:https://html5.litten.com/how-to-drag-and-drop-on-an-html5-canvas/

下面作者的原始的版本会抖动一下(鼠标刚点下去的时候,位置会发生一下突变,不是很友好), 我修改了 一下。

var xDown , yDown;
function myDown(e){
if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 +
canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop){
xDown = e.pageX - canvas.offsetLeft;
yDown = e.pageY - canvas.offsetTop;
dragok = true;
canvas.onmousemove = myMove;
}
}
这样就不会了。

-----------------------------------------------------------------------------------------------

How to Drag and Drop on an HTML5 Canvas

We explored using keyboard input to move a shape on an HTML5 canvas here http://html5.litten.com/moving-shapes-on-the-html5-canvas-with-the-keyboard/. Now we’ll take a look at using input from the mouse. With a few simple calculations, you can drag and drop shapes on the canvas with your mouse.

UPDATE: I’ve added a companion post for IE compatibility.

IE Compatible Canvas Drag and Drop With jQuery and ExCanvas

This example is coded for readability and not for optimized operation. All you need is a text editor like notepad and an HTML5 friendly browser (I’m using Firefox 3.6).

Here is the code listing that we will be discussing.


<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>Canvas Drag and Drop Test</title>
</head>
<body>
<section> <div>
<canvas id="canvas" width="400" height="300">
This text is displayed if your browser does not support HTML5 Canvas.
</canvas>
</div> <script type="text/javascript"> var canvas;
var ctx;
var x = 75;
var y = 50;
var WIDTH = 400;
var HEIGHT = 300;
var dragok = false; function rect(x,y,w,h) {
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
} function clear() {
ctx.clearRect(0, 0, WIDTH, HEIGHT);
} function init() {
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
return setInterval(draw, 10);
} function draw() {
clear();
ctx.fillStyle = "#FAF7F8";
rect(0,0,WIDTH,HEIGHT);
ctx.fillStyle = "#444444";
rect(x - 15, y - 15, 30, 30);
} function myMove(e){
if (dragok){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
}
} function myDown(e){
if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 +
canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
dragok = true;
canvas.onmousemove = myMove;
}
} function myUp(){
dragok = false;
canvas.onmousemove = null;
} init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp; </script> </section>
</body>
</html>

You can copy this code and paste it into a new file called something like draganddrop.html and when you open it with an HTML5 friendly browser like Firefox 3.6 it will display the canvas with a draggable square on it.

The details of how we create a canvas and draw our shape on it can be found in this previous post http://html5.litten.com/simple-animation-in-the-html5-canvas-element/.

In this example we draw a 30×30 pixel square which we can click on and drag around the canvas. Let’s look at the draw() function.


function draw() {
clear();
ctx.fillStyle = "#FAF7F8";
rect(0,0,WIDTH,HEIGHT);
ctx.fillStyle = "#444444";
rect(x - 15, y - 15, 30, 30);
}

We create our draggable square with this call to rect()


rect(x-15, y-15, 30, 30);

rect(x, y, width, height)
The x and y parameters define the coordinate of the top left corner of the new rectangular path. width and height define the width and the height of the rectangle.

We want our x and y to be at the center of our square so we use

  rect(x - 15, y - 15, 30, 30); 

instead of

  rect(x, y, 30, 30);

Now we need to add event listeners to detect when the mouse button is pressed down so we can begin dragging and when the mouse button is released so we can drop.

After calling init(), in which we create our canvas object, we attach event listeners to the new canvas object with


init();
canvas.onmousedown = myDown;
canvas.onmouseup = myUp;

When the user clicks their mouse on the canvas the canvas.onmousedown event is triggered and calls the function myDown(). myDown receives an event object e that has properties about the event. This event has, amongst others, the properties pageX and pageY which hold the values of the mouse’s current x and y coordinates on the page (not the window but the whole page).


function myDown(e){
if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 +
canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop){ x = e.pageX ;
y = e.pageY ;
dragok = true;
canvas.onmousemove = myMove;
}
}

Our first question to ask when the mouse is clicked on the canvas is, “Is this click on our draggable square?”.

We check with this test.


if (e.pageX < x + 15 + canvas.offsetLeft && e.pageX > x - 15 +
canvas.offsetLeft && e.pageY < y + 15 + canvas.offsetTop &&
e.pageY > y -15 + canvas.offsetTop)

Remember that we created our square so that (x,y) is at the center. To determine if the click was on the x axis inside the square, we look at the x value of the mouse click e.pageX and see if it is within 15 pixels of our square’s x value using the canvas objects offset since e.pageX is the value of the mouses x coordinate on the page not on the canvas.

We also test the e.pageY value against our square’s y value. If our point is within the x and y values of our square then we set the variable dragok to true. Setting our square’s central (x,y) to (e.pageX - canvas5.offsetLeft, e.pageY - canvas5.offsetTop) makes it easy for us to move it (this is a very simple example).


x = e.pageX - canvas5.offsetLeft;
y = e.pageY - canvas5.offsetTop;
dragok = true;

Now that we know the mouse button is down while it is over our draggable object, we can start listening for mouse movement (dragging).


canvas.onmousemove = myMove;

Here’s our myMove() function


function myMove(e){
if (dragok){
x = e.pageX - canvas.offsetLeft;
y = e.pageY - canvas.offsetTop;
}
}

We check to make sure that we are dragging something dragok = true and if we are, we update the x and y coordinates of our square with e.pageX and e.pageY adjusted with the offset values of our canvas.

Now we need to be able to drop the object by releasing the mouse button. When we do this we trigger our listener for the onmouseup event of our canvas (try moving your mouse off the canvas while dragging and observe the behavior of onmouseup. You will see that if you release the mouse while off of the canvas, it does not trigger the onmouseup event listener on the canvas. This can be useful in designing games.)


canvas.onmouseup = myUp;

The myUp() function simply sets dragok back to false and removes the onmousemove listener (we only need it when we are dragging).


function myUp(){
dragok = false;
canvas.onmousemove = null;
}

Here is our canvas in action…

 

Have fun with the code as that is the easiest way to learn.

Please leave a comment if you have any questions or corrections.

在canvas上面拖拽对象。的更多相关文章

  1. canvas 图片拖拽旋转之二——canvas状态保存(save和restore)

    引言 在上一篇日志“canvas 图片拖拽旋转之一”中,对坐标转换有了比较深入的了解,但是仅仅利用坐标转换实现的拖拽旋转,会改变canvas坐标系的状态,从而影响画布上其他元素的绘制.因此,这个时候需 ...

  2. jQuery UI =>jquery-ui.js中sortable方法拖拽对象位置偏移问题

    今天要处理sortable方法处理的对象,拖拽的时候,位置偏移的问题. 按理应该是鼠标在哪,对象就跟着在哪的 百度了一下问题,http://blog.csdn.net/samed/article/de ...

  3. HTML5新特性之Canvas+drag(拖拽图像实现图像反转)

    1.什么是canvas 在网页上使用canvas元素时,会创建一块矩形区域,默认矩形区域宽度300px,高度150px.. 页面中加入canvas元素后,可以通过javascript自由控制.可以在其 ...

  4. 使用原生JavaScript的Canvas实现拖拽式图形绘制,支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多边形和圆形,不依赖任何库和插件,有演示demo

    前言 需要用到图形绘制,没有找到完整的图形绘制实现,所以自己实现了一个 - - 一.实现的功能 1.基于oop思想构建,支持坐标点.线条(由坐标点组成,包含方向).多边形(由多个坐标点组成).圆形(包 ...

  5. 原生js实现Canvas实现拖拽式绘图,支持画笔、线条、箭头、三角形和圆形等等图形绘制功能,有实例Demo

    前言 需要用到图形绘制,没有找到完整的图形绘制实现,所以自己实现了一个 - - 演示地址:查看演示DEMO 新版本支持IE5+(你没看错,就是某软的IE浏览器)以上任意浏览器的Canvas绘图:htt ...

  6. canvas 图片拖拽旋转之一——坐标转换translate

    引言 对canvas中绘制的图片进行旋转操作,需要使用ctx.translate变换坐标系,将图片旋转的基点设为坐标系的原点,然后ctx.rotate旋转. 这个时候,因为canvas坐标系发生了旋转 ...

  7. html --- canvas --- javascript --- 拖拽圆圈

    代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <tit ...

  8. jquery.dad.js实现table的垂直拖拽(并取到当前拖拽对象)

    http://sc.chinaz.com/jiaoben/161202572210.htm 1.首先官网实例,实现的都是div为容器的元素拖拽,示例如下: 2.最近的项目,要实现tbody的每一行tr ...

  9. 如何实现Canvas图像的拖拽、点击等操作

    上一篇Canvas的博文写完后,有位朋友希望能对Canvas绘制出来的图像进行点击.拖拽等操作,因为Canvas绘制出的图像能很好的美化.好像是想做炉石什么的游戏,我也没玩过. Canvas在我的理解 ...

随机推荐

  1. RN调试

    https://facebook.github.io/react-native/docs/debugging.html 热加载 RN的目标是极致的开发体验,修改文件后能在1秒内看到变化,通过以下三个特 ...

  2. History Api以及hash操作

    https://segmentfault.com/a/1190000002447556#articleHeader12 https://developer.mozilla.org/zh-CN/docs ...

  3. Vue—事件修饰符

    Vue事件修饰符 Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation(). Vue. ...

  4. mysql 慢查询日志 pt-query-digest 工具安装

    介绍:pt-query-digest是用于分析mysql慢查询的一个工具,它可以分析binlog.General log.slowlog,也可以通过SHOWPROCESSLIST或者通过tcpdump ...

  5. 我的Python分析成长之路10

    matplot数据可视化基础 制作提供信息的可视化(有时称作绘图)是数据分析中最重要任务之一. 1.图片(画布)与子图 plt.figure :创建一张空白的图片,可以指定图片的大小.像素. figu ...

  6. ZOJ 3469 区间DP Food Delivery

    题解 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm ...

  7. 10大vim插件

    Taglist taglist是一个用于显示定位程序中各种符号的插件,例如宏定义.变量名.结构名.函数名这些东西 我们将其称之为符号(symbols),而在taglist中将其称之为tag.显然,要想 ...

  8. TOJ 2446: Mint

    2446: Mint Time Limit(Common/Java):2000MS/20000MS     Memory Limit:65536KByteTotal Submit: 4         ...

  9. CSU-1803: 2016 ,同余定理!

    int main() {     int n,m;     while(~scanf("%d%d",&n,&m))     {         int r1=n/2 ...

  10. 【Luogu】P3708Koishi的数字游戏(数论)

    题目链接 考虑f(i)=i%1+i%2+i%3+.....+i%n f(i+1)=(i+1)%1+(i+1)%2+......+(i+1)%n 其中不是i+1的因数的部分在f(i+1)的地方都加了1. ...