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

最近在学习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();
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值