项目的新要求是动态生成矩形框,单击并拖动鼠标以更改矩形框的位置,然后可以调整大小。
我之前做了一个小演示。要求类似,但是画布上只有一个矩形框。拖动以移动。那时,我记得使用isPointInPath()直接确定鼠标是否在矩形框中。新要求的矩形框数量为n。经过测试,isPointinPath的实现中存在一个错误,它无法准确定位在画布上单击的某个矩形框。经过一系列的头脑风暴,我想出了一个解决方案,结果却发现这是最简单的方法,但是当我想到它时就通过了。参见代码:
html:
<body> <canvas id="canvas" width="400" height="300"> canvas> body>
小型演示,不做其他装饰,只需编写逻辑即可。
js:
第一步是创建一个容器来存储在“画布”中绘制的元素点。 Canvas是一个非保持性的绘图界面,也就是说,它不会记录过去执行的绘图操作,但是会保留最终结果(构成图像的彩色像素)。
例如,如果您希望Canvas是交互式的,则用户可以选择并拖布上的图形。然后,我们必须记录每个绘制的对象,以便将来可以灵活地修改和重绘它们以实现交互。
1 // canvas 矩形框集合 2 var rects=[]; 3 function rectar(x,y,width,height){ 4 this.x = x; 5 this.y = y; 6 this.width = width; 7 this.height = height; 8 this.isSelected = false; 9 };
绘制一个矩形框:
1 function drawRect() { 2 // 清除画布,准备绘制 3 context.clearRect(0, 0, canvas.width, canvas.height); 4 5 // 遍历所有矩形框 6 for(var i=0; i) { 7 var rect = rects[i]; 8 9 // 绘制矩形 10 context.strokeStyle="#FF0000"; 11 context.strokeRect(rect.x,rect.y,rect.width,rect.height,rect.color); 12 13 if (rect.isSelected) { 14 context.lineWidth = 50; 15 } 16 else { 17 context.lineWidth = 10; 18 } 19 } 20 }
这是一个绘制函数,因为Canvas中的所有操作都被重新绘制(先清除,然后绘制)。程序每次刷新画布时,都会使用clearRect()方法清除画布上的所有内容。 。但是不要小心,这会导致画布闪烁,也就是说,画布上的所有圆圈会一次全部消失,然后立即全部重新出现。因为Canvas针对此问题进行了优化,所以它将在执行所有绘制逻辑后清除或绘制所有内容,以确保最终结果的平滑性。然后遍历矩形数组的x,y,宽度和高度以绘制矩形。
*我的项目是根据病变位置动态生成的矩形框。每次生成矩形框时,都必须将其位置信息添加到数组中。在这里,矩形框是直接创建的,您可以根据需要对其进行修改。
1 function addRandomRect() { 2 var x=10; 3 var y=10; 4 var width=100; 5 var height=100; 6 // 创建一个新的矩形对象 7 var rect=new rectar(x,y,width,height); 8 9 // 把它保存在数组中 10 rects.push(rect); 11 // 重新绘制画布 12 drawRect(); 13 };
*画布点击事件
1 var SelectedRect; 2 var x1; 3 var y1; 4 var right=false; 5 var widthstart,widthend; 6 var heightstart,heightend; 7 8 function canvasClick(e) { 9 // 取得画布上被单击的点 10 var clickX = e.pageX - canvas.offsetLeft; 11 var clickY = e.pageY - canvas.offsetTop; 12 13 // 查找被单击的矩形框 14 for(var i=rects.length-1; i>=0; i--) { 15 var rect = rects[i]; 16 17 widthstart=rect.x; 18 widthend=rect.x+rect.width; 19 20 heightstart=rect.y; 21 heightend=rect.y+rect.height; 22 23 // 判断这个点是否在矩形框中 24 if ((clickX>=widthstart&&clickX<(widthend-20))&&(clickY>=heightstart)&&(clickY<(heightend-20))) { 25 console.log(clickX); 26 // 清除之前选择的矩形框 27 if (SelectedRect != null) SelectedRect.isSelected = false; 28 SelectedRect = rect; 29 x1=clickX-SelectedRect.x; 30 y1=clickY-SelectedRect.y; 31 //选择新圆圈 32 rect.isSelected = true; 33 34 // 使圆圈允许拖拽 35 isDragging = true; 36 37 //更新显示 38 drawRect(); 39 //停止搜索 40 return; 41 }; 42 /* 43 设置拉伸的界限。 44 */ 45 // if ((clickX>=(widthend-20))&&(clickY>=(heightend-20))) 46 // { 47 // SelectedRect = rect; 48 // right=true; 49 // }
//18-02-01改
if ((clickX>=(widthend-20)&&((clickX<=(widthend+20)))&&(clickY>=(heightend-20))&&(clickY>=(heightend+20)))
{
SelectedRect = rect;
right=true;
}
50 }
51 }
代码中的23个行为决定了单击哪个元素。实际上非常简单。我已经待了很长时间了。直接判断鼠标单击是否在矩形框中非常简单。不管它是哪个矩形框,都只需要放在矩形框中即可。在其中,将当前矩形框设置为单击的矩形框。第29行确定鼠标单击点相对于矩形框的位置。第42-49行是判断鼠标拉伸以更改大小的行。您可以将矩形的四个角设置为拉伸,但是我认为它太复杂了。仅保留右下角的点击判断,操作更加简单。
响应事件:
function dragRect(e) { // 判断矩形是否开始拖拽 if (isDragging == true) { // 判断拖拽对象是否存在 if (SelectedRect != null) { // 取得鼠标位置 var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; // 将圆圈移动到鼠标位置 SelectedRect.x= x-x1; SelectedRect.y= y-y1; // 更新画布 drawRect(); } }
//判断是否开始拉伸 if (right) {
//设置拉伸最小的边界 if ((e.pageX - canvas.offsetLeft-SelectedRect.x)>50) { SelectedRect.width=e.pageX - canvas.offsetLeft-SelectedRect.x; } else { SelectedRect.width=50; } console.log(SelectedRect.width); if((e.pageY - canvas.offsetTop-SelectedRect.y)>50){ SelectedRect.height=e.pageY - canvas.offsetTop-SelectedRect.y; } else { SelectedRect.height=50; } drawRect(); } };
上面已经完成了矩形框的基本操作,然后添加了onmouseup函数和调用函数:
var isDragging = false; function stopDragging() { isDragging = false; right=false; };
function clearCanvas(){
//删除所有矩形
rects = [];
//重新绘制画布。
drawCircles();
}
window.onload = function() { canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); canvas.onmousedown = canvasClick; canvas.onmouseup = stopDragging; canvas.onmouseout = stopDragging; canvas.onmousemove =dragRect;
; };
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/bofangqi/article-376785-1.html
五年后
你就必须像萨达姆那样不怕死
再踢你一脚