您的位置:首页 > Web前端 > JavaScript

js实现canvas绘制的图形的拖动效果

2017-07-07 14:32 971 查看
最近在学习canvas突然发现canvas的元素也可以实现拖动,原来写过DOM元素的拖动效果,感觉挺简单的,所以自己试着写了一个在canvas里拖动绘制图形的效果。
首先得先在canvas里绘制一个我们想要操作的图形,这时候就要用canvas的绘制功能了,绘制代码如下:


<canvas width="400" height="400" id="cvs"></canvas>
var oldPosition = {'x':100,'y':100};//图形的起始点
var area = {'w' : 50 , 'h' : 50};//绘制图形的宽高
var cvs = document.getElementById('cvs');
drawing : function(){
var ctx = this.canvas.getContext('2d');//得到画笔
ctx.clearRect(0,0,this.canvas.width,this.canvas.height);//每次绘制前先清除之前绘制的图形
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.fillRect(this.oldPosition.x,this.oldPosition.y,this.area.w,this.area.h);
ctx.closePath();
}


绘制完后网页上就有了一个蓝色的小方块:



图形绘制完了,下一步就要考虑的问题就是怎样去定位到canvas里绘制的元素。和DOM元素不同,DOM元素可以通过getElementById或者getElementsByTagName等方法获得DOM元素,然后通过鼠标事件对其进行操作。在canvas里就要通过边界的临界值判断绘制方块咋canvas里的位置。
当我们通过鼠标点击页面的时候,浏览器通过事件对象传递给监听器一个鼠标的坐标,而此坐标是窗口的坐标,不是相对与canvas的坐标。大部分情况下,我们需要知道发生点击事件的点相对于canvas的位置,而不是在窗口的位置。so,我们需要一个方法将鼠标的坐标转换成canvas上的坐标,下面的方法就实现了转换的功能:


window2Canvas : function(x,y){
var bbox = this.canvas.getBoundingClientRect();
return {x : x-bbox.left ,y : y-bbox.top}
}


做好了坐标转换,下一步就要去判断绘制图形的位置了,下面的方法则是实现了判断绘制图形位置功能:


isInRect : function(e){
var position = this.window2Canvas(e.clientX,e.clientY);
if(position.x < this.oldPosition.x || position.x > this.oldPosition.x+this.area.w){
return false;
}
if(position.y < this.oldPosition.y || position.y > this.oldPosition.y+this.area.h){
return false;
}
return true;
}


找到了绘制的图形,下一步就是让他动起来。拖动主要用到三个鼠标事件,分别是mousedown、mousemove、mouseup。通过上述的三个事件就可以实现拖动的效果了。实现事件的方法如下:


cursorMouseMove : function(e){//当鼠标移到绘制图形上的时候改变鼠标的状态
if(this.isInRect(e)){
this.canvas.style.cursor = 'move';
}else{
this.canvas.style.cursor = 'default';
}
},
mouseDown : function(e){//当鼠标按下时调用
if(this.isInRect(e)){
var startPosition = this.window2Canvas(e.clientX,e.clientY);

var startPositionX = startPosition.x - this.oldPosition.x;
var startPositionY = startPosition.y - this.oldPosition.y;

var _this = this;
this.canvas.onmousemove = function(e){//鼠标移动的时候
var newPosition = _this.window2Canvas(e.clientX,e.clientY);
_this.oldPosition.x = newPosition.x - startPositionX;
_this.oldPosition.y = newPosition.y - startPositionY;
//判断绘制的图形是否超出canvas的边界
if(_this.oldPosition.x < 0) _this.oldPosition.x = 0;

if(_this.oldPosition.x + _this.area.w > _this.canvas.width)
_this.oldPosition.x = _this.canvas.width - _this.area.w;

if(_this.oldPosition.y < 0 ) _this.oldPosition.y = 0;

if(_this.oldPosition.y + _this.area.h > _this.canvas.height)
_this.oldPosition.y = _this.canvas.height - _this.area.h;
//边移动边在新的位置绘制图形
_this.drawing();
}
}
},
mouseUp : function(e){//鼠标抬起的时候调用
var _this = this;
this.canvas.onmousemove = null;
this.canvas.onmousemove = function(e){
_this.cursorMouseMove(e);
}
}


事件处理方法完了,下面对事件方法进行初始化就可以了。初始化代码如下:


initEvent : function(){
var _this = this;
this.canvas.onmousemove = function(e){_this.cursorMouseMove(e);};
this.canvas.onmousedown = function(e){_this.mouseDown(e);}
this.canvas.onmouseup = function(e){_this.mouseUp(e);}
}


拖动所需要的方法基本上就写完了,下面对整个拖动的功能同意来个初始化方法就可以了,初始化的代码如下:


init : function(){
this.drawing();
this.initEvent();
}


好了,基本就这些,下面让我们去new一个就可以了


var drag = new Drag(oldPosition,area,'steelblue',cvs);
drag.init();


完成!上面的代码有点乱,下面附上完整的js代码:


var oldPosition = {'x':100,'y':100};//图形的起始点
var area = {'w' : 50 , 'h' : 50};//绘制图形的宽高
var cvs = document.getElementById('cvs');

var Drag = function(oldPosition,area,color,canvas){
this.oldPosition = oldPosition;
this.area = area;
this.color = color;
this.canvas = canvas;
}
Drag.prototype = {
init : function(){
this.drawing();
this.initEvent();
},
drawing : function(){
var ctx = this.canvas.getContext('2d');//得到画笔
ctx.clearRect(0,0,this.canvas.width,this.canvas.height);//每次绘制前先清除之前绘制的图形
ctx.beginPath();
ctx.fillStyle = this.color;
ctx.fillRect(this.oldPosition.x,this.oldPosition.y,this.area.w,this.area.h);
ctx.closePath();
},
window2Canvas : function(x,y){
var bbox = this.canvas.getBoundingClientRect();
return {x : x-bbox.left ,y : y-bbox.top}
},
isInRect : function(e){
var position = this.window2Canvas(e.clientX,e.clientY);
if(position.x < this.oldPosition.x || position.x > this.oldPosition.x+this.area.w){
return false;
}
if(position.y < this.oldPosition.y || position.y > this.oldPosition.y+this.area.h){
return false;
}
return true;
},
initEvent : function(){
var _this = this;
this.canvas.onmousemove = function(e){_this.cursorMouseMove(e);};
this.canvas.onmousedown = function(e){_this.mouseDown(e);}
this.canvas.onmouseup = function(e){_this.mouseUp(e);}
},
cursorMouseMove : function(e){//当鼠标移到绘制图形上的时候改变鼠标的状态
if(this.isInRect(e)){
this.canvas.style.cursor = 'move';
}else{
this.canvas.style.cursor = 'default';
}
},
mouseDown : function(e){//当鼠标按下时调用
if(this.isInRect(e)){
var startPosition = this.window2Canvas(e.clientX,e.clientY);

var startPositionX = startPosition.x - this.oldPosition.x;
var startPositionY = startPosition.y - this.oldPosition.y;

var _this = this;
this.canvas.onmousemove = function(e){//鼠标移动的时候
var newPosition = _this.window2Canvas(e.clientX,e.clientY);
_this.oldPosition.x = newPosition.x - startPositionX;
_this.oldPosition.y = newPosition.y - startPositionY;
//判断绘制的图形是否超出canvas的边界
if(_this.oldPosition.x < 0) _this.oldPosition.x = 0;

if(_this.oldPosition.x + _this.area.w > _this.canvas.width)
_this.oldPosition.x = _this.canvas.width - _this.area.w;

if(_this.oldPosition.y < 0 ) _this.oldPosition.y = 0;

if(_this.oldPosition.y + _this.area.h > _this.canvas.height)
_this.oldPosition.y = _this.canvas.height - _this.area.h;
//边移动边在新的位置绘制图形
_this.drawing();
}
}
},
mouseUp : function(e){//鼠标抬起的时候调用
var _this = this;
this.canvas.onmousemove = null;
this.canvas.onmousemove = function(e){
_this.cursorMouseMove(e);
}
}
}
var drag = new Drag(oldPosition,area,'steelblue',cvs);
drag.init();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  canvas dom javascript