canvas translate 移动坐标系实现图形拖拽

平移变换实质上是平移坐标系, 而对于translate()传入的参数,是新坐标系相对于旧坐标系的偏移量。

方法一:

平移坐标系并绘制图形后,恢复状态,将坐标系平移回原点(即重新以canvas的左上角为坐标系原点)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>canvas拖拽</title>
</head>
<canvas id="myCanvas" width="400" height="400"></canvas>  
<body>
<script>
var Draw={
		translateX: 45,
		translateY:45,
		coordinateX:0,
		coordinateY:0,
		w:70,
		h:70,
		color:"red",
         init:function(){
        	 this.targetCanvas = document.getElementById("myCanvas");
             this.cObj=this.targetCanvas.getContext("2d");
             this.event()
             this.draw.prototype=this
             this.p=new  this.draw(this.coordinateX, this.coordinateY)
         },
         draw:function(coordinateX, coordinateY){        	  
        	 this.cObj.save();
                 //clearRect()方法清空当前画布
        	 this.cObj.clearRect(0,0, this.targetCanvas.offsetWidth, this.targetCanvas.offsetHeight); 
        	 this.coordinateX = coordinateX;
        	 this.coordinateY = coordinateY;
        	 this.cObj.translate(this.coordinateX, this.coordinateY);
        	 this.cObj.beginPath();
        	 this.cObj.moveTo(0, 0);
        	 this.cObj.lineTo(30,0);
        	 this.cObj.moveTo(0, 0);
        	 this.cObj.lineTo(0,30);
        	 this.cObj.stroke();
        	 
        	 this.cObj.strokeStyle=this.color;
        	 this.cObj.strokeRect(this.translateX, this.translateY, this.w, this.h);
        	 this.cObj.restore(); //恢复状态,将坐标系平移回原点(即重新以canvas的左上角为坐标系原点)
         },
         OnMouseMove:function(evt){
             if(this.p.isDown){
                //把(evt.offsetX,evt.offsetY)移动过程中的鼠标点作为矩形的中心点
                 var coordinateX = evt.offsetX - this.p.w/2 - this.translateX;
                 var coordinateY = evt.offsetY- this.p.h/2 - this.translateY;
                 this.draw(coordinateX, coordinateY);                
             }
  
         },
         OnMouseDown:function(evt){
             var X=evt.offsetX;
             var Y=evt.offsetY;
             var rectOffsetX = X - this.coordinateX - this.translateX;
             var rectOffsetY = Y - this.coordinateY - this.translateY;
             if( rectOffsetX >0 && rectOffsetX <this.w){
            	 if(rectOffsetY >0 && rectOffsetY <this.h){
            		 this.p.isDown=true;
            	 }
             }else{
            	 this.p.isDown=false;
             }
             
         },
         OnMouseUp:function(){
             this.p.isDown=false
         },
         event:function(){
             var canvas=document.getElementById("myCanvas")
             canvas.addEventListener("mousedown",this.OnMouseDown.bind(this),false);
             canvas.addEventListener("mousemove",this.OnMouseMove.bind(this),false);
             canvas.addEventListener("mouseup",this.OnMouseUp.bind(this),false);
         }
     }
      Draw.init()
</script>
</body>
</html>

方法二:

使用变量coordinateX、coordinateY 记录每次移动后坐标系原点相对canvas左上角的坐标,不使用save()、restore()恢复状态。

canvas translate博客中有谈到在移动坐标系后,要不要恢复状态的问题。其实不恢复状态也是可以的,用变量保存新坐标系原点的相对坐标就行。

在该方法中,也不再使用移动过程中的鼠标点作为矩形的中心点,而是计算得出鼠标在移动过程中的偏移量,并把该偏移量作为坐标系的偏移量,即translate()的参数。

这个计算坐标系偏移的算法显然更有现实意义。鼠标在矩形内就可进行拖拽,拖拽完成后鼠标在矩形内的位置应该不变,而不是变成矩形的中心。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>canvas拖拽</title>
</head>
<canvas id="myCanvas" width="1200" height="400"></canvas>  
<body>
<script>
//移动坐标系,不使用save()、restore()恢复状态
//通过使用coordinateX、coordinateY记录坐标系原点相对canvas左上角的坐标

var Draw={
		coordinateX:0,  //记录坐标系原点相对canvas左上角的坐标
		coordinateY:0,
		translateX: 45,  //矩形相对坐标系原点的偏移量,固定值
		translateY:45,
		w:70,  //矩形宽度,固定值
		h:70,
		color:"red",
         init:function(){
        	 this.targetCanvas = document.getElementById("myCanvas");
             this.ctx=this.targetCanvas.getContext("2d");
             this.event()
             this.draw.prototype=this
             this.p=new  this.draw()
         },
         translate: function(x, y, disablePlot) {   //移动坐标系
             this.coordinateX += x;  //加上坐标系的偏移量,coordinateX得到的是新坐标系的原点相对canvas左上角的坐标
             this.coordinateY += y;   
             this.ctx.translate(x, y);  //坐标系的偏移量等于鼠标的偏移量
           },
         draw:function(){        	  
        	 var canvasWidth = this.targetCanvas.offsetWidth, canvasHeight = this.targetCanvas.offsetHeight;
        	 this.ctx.clearRect(-canvasWidth, -canvasHeight, canvasWidth*2, canvasHeight*2);
        	 this.ctx.strokeStyle=this.color;
        	 this.ctx.beginPath();
        	 this.ctx.moveTo(0, 0);
        	 this.ctx.lineTo(30,0);
        	 this.ctx.moveTo(0, 0);
        	 this.ctx.lineTo(0,30);
        	 this.ctx.stroke();       	        	 
        	 this.ctx.strokeRect(this.translateX, this.translateY, this.w, this.h);
         },
         OnMouseMove:function(evt){
             if(this.p.isDown){
                 var mouseOffsetX = evt.offsetX - this.p.mouseStartPoint.x;
                 var mouseOffsetY = evt.offsetY - this.p.mouseStartPoint.y;  //记录鼠标在移动过程中的偏移量
                 this.p.mouseStartPoint = {x: evt.offsetX, y: evt.offsetY}; //重置鼠标偏移量的开始点
                 this.translate(mouseOffsetX, mouseOffsetY);
                 this.draw();                
             }
  
         },
         OnMouseDown:function(evt){
             var X=evt.offsetX;
             var Y=evt.offsetY;
             var rectOffsetX = X - this.coordinateX - this.translateX;
             var rectOffsetY = Y - this.coordinateY - this.translateY;
             if( rectOffsetX >0 && rectOffsetX <this.w){
            	 if(rectOffsetY >0 && rectOffsetY <this.h){
            		 this.p.isDown=true;
            		 this.p.mouseStartPoint = {x:X, y:Y};
            	 }
             }else{
            	 this.p.isDown=false;
             }
             
         },
         OnMouseUp:function(){
             this.p.isDown=false
         },
         event:function(){
             var canvas=document.getElementById("myCanvas")
             canvas.addEventListener("mousedown",this.OnMouseDown.bind(this),false);
             canvas.addEventListener("mousemove",this.OnMouseMove.bind(this),false);
             canvas.addEventListener("mouseup",this.OnMouseUp.bind(this),false);
         }
     }
      Draw.init()
</script>
</body>
</html>

最终效果:



  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值