HTML5 Canvas笔记 -- 2

来源:互联网 发布:现在的淘宝太坑了女孩 编辑:程序博客网 时间:2024/05/01 20:44

   今天写一下Canvas上可拖拽矩形的实现。

   算法流程:

          1)定义矩形对象,对象含有矩形左上角位置和长宽信息,以及矩形标号标签,和createPath函数(为检测isPointInPath()使用)。

                声明矩形对象数组,将矩形实例压入数组。

          2)绘制矩形,并为canvas添加鼠标监听函数(mousedown, mousemove, mouseup)。

          3)mousedown时,使用isPointInPath(),循环检测矩形数组中的每个矩形实例,当mousedown在某个矩形内时,dragNum为当前矩形的标号,结束循环。

          4)若mouseup,若 typeof mouseMoveInCanvasLoc.x=="undefined" 不做矩形位置更新,但dragNum重置为-1;

          5)若mouremove,记录鼠标位置,使用clearRect()清除画布,循环检测每个矩形实例,若为被拖拽的矩形,则按X和Y的偏移量更新矩形的top,left位置,

                重绘数组中所有矩形。

          6)mouseup,更新被拖拽矩形的位置信息,重置dragNum,重置mouseMoveInCanvasLoc。


    这里是JS代码:

    

//dragPolygonCanvas  var dragNum = -1;  function polygon(loc,num){ this.polyloc = {left:loc.left,top:loc.top,                  width:loc.width,height:loc.height}; this.num = num; } polygon.prototype={ createPath:function (context) {      context.beginPath();      context.rect(this.polyloc.left,this.polyloc.top,                  this.polyloc.width,this.polyloc.height);      context.closePath();   } }  var Polygons = new Array(); var polygon1 = new polygon({left:50,top:50,width:100,height:100},0); var polygon2 = new polygon({left:150,top:150,width:50,height:50},1); Polygons.push(polygon1); Polygons.push(polygon2);  var dragCanvas = document.getElementById("dragPolygonCanvas"); var dragContext = dragCanvas.getContext("2d");  dragCanvas.style.background="rgba(8,5,67,0.5)"; dragContext.fillStyle = "cornflowerblue"; dragContext.shadowColor="rgba(0,0,0,0.7)"; dragContext.shadowOffsetX = 4; dragContext.shadowOffsetY = 4; dragContext.shadowBlur = 2;  dragContext.beginPath(); dragContext.rect(Polygons[0].polyloc.left,Polygons[0].polyloc.top,                  Polygons[0].polyloc.width,Polygons[0].polyloc.height); dragContext.rect(Polygons[1].polyloc.left,Polygons[1].polyloc.top,                  Polygons[1].polyloc.width,Polygons[1].polyloc.height); dragContext.fill(); dragContext.closePath();  var mouseDownInCanvasLoc = {}; var mouseMoveInCanvasLoc = {}; var handle3 = function(event){ switch(event.type){ case "mousedown": event.preventDefault();  mouseDownInCanvasLoc = convertWindowToCanvasPos( event.clientX, event.clientY + getScrollTop());  Polygons.forEach(function(ploygon){ ploygon.createPath(dragContext); if(dragContext.isPointInPath(mouseDownInCanvasLoc.x,mouseDownInCanvasLoc.y)){ dragNum = ploygon.num; } }); break; case "mousemove":; if(dragNum!=-1){ event.preventDefault(); mouseMoveInCanvasLoc = convertWindowToCanvasPos( event.clientX, event.clientY + getScrollTop());  dragContext.clearRect(0, 0, dragCanvas.width, dragCanvas.height);  dragContext.beginPath(); Polygons.forEach(function(ploygon){ if(ploygon.num!=dragNum){   dragContext.rect(ploygon.polyloc.left,ploygon.polyloc.top,                  ploygon.polyloc.width,ploygon.polyloc.height); } if(ploygon.num==dragNum){   var pleft = ploygon.polyloc.left+mouseMoveInCanvasLoc.x-mouseDownInCanvasLoc.x;   var ptop = ploygon.polyloc.top+mouseMoveInCanvasLoc.y-mouseDownInCanvasLoc.y;   dragContext.rect(pleft,ptop,                  ploygon.polyloc.width,ploygon.polyloc.height); } }); dragContext.fill(); } break; case "mouseup": Polygons.forEach(function(ploygon){ if(ploygon.num==dragNum && !(typeof mouseMoveInCanvasLoc.x=="undefined")){   ploygon.polyloc.left = ploygon.polyloc.left+mouseMoveInCanvasLoc.x-mouseDownInCanvasLoc.x;   ploygon.polyloc.top = ploygon.polyloc.top+mouseMoveInCanvasLoc.y-mouseDownInCanvasLoc.y;   mouseMoveInCanvasLoc={};   return; } }); dragNum = -1; break; default:break; } }  function convertWindowToCanvasPos(x, y) {   var bbox = dragCanvas.getBoundingClientRect();   return { x: x - bbox.left,            y: y - bbox.top - getScrollTop()};}  dragCanvas.addEventListener("mousedown",handle3,false); dragCanvas.addEventListener("mousemove",handle3,false); dragCanvas.addEventListener("mouseup",handle3,false);

   注意在mousemove时,重绘所有矩形时,beginPath()的位置。另,更新矩形位置信息时,在mouseup时更新。上述都是因为Canvas绘图机制为immediate-mode(即时模式)。

   效果图: