canvas教程

Canvas的使用样例14(图形增加鼠标点击、拖动交互)

字号+ 作者:H5之家 来源:H5之家 2017-12-03 13:07 我要评论( )

Canvas是一种非保留性的绘图界面,即不会记录过去执行的绘图操作,而是保持最终结果(构成图像的彩色像素)。 如果想让Canvas变得具有交互性,比如用户可以选择

Canvas是一种非保留性的绘图界面,即不会记录过去执行的绘图操作,而是保持最终结果(构成图像的彩色像素)。

如果想让Canvas变得具有交互性,比如用户可以选择、拖动画布上的图形。那么我们必须记录绘制的每一个对象,才能在将来灵活的修改并重绘它们,实现交互。


1,鼠标点击选择图形对象

(1)下面样例中点击“添加圆圈”按钮可以在画布上增加位置、大小、颜色都是随机的圆圈。

(2)点击“清空画布”按钮可以清除画布上所有圆圈。

(3)鼠标点击任意圆圈,该圆圈会出现黑色边框,表示选中。

添加圆圈 清空画布

代码说明:

(1)为了能够将圆圈对象保存起来,我们定义了一个叫 Circle() 的函数类创建自定义对象。同时要让这个对象能够保持数据,要使用关键字 this 来创建属性。

(2)drawCircles() 函数用来根据当前圆圈的集合来填充画布。每次程序刷新画布时,会先使用 clearRect() 方法清除画布上的所有内容。但不用当心这样会造成画布闪烁,即画布上的圆圈一下子全部消失,然后一下子又重新出现。

因为Canvas针对这个问题进行了优化,会在所有绘图逻辑执行完毕后才清除或绘制所有内容,保证最终结果的流畅。

(3)要实现鼠标选中某个图像,就要用到碰撞检测。即计算鼠标点击的那个点是否落在某个形状里。对于圆圈而言,只要计算单击点与圆心的直线距离即可。

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>hangge.com</title> <style> canvas { cursor: pointer; border: 1px solid black; } </style> <script> // 这个方法用来储存每个圆圈对象 function Circle(x, y, radius, color) { this.x = x; this.y = y; this.radius = radius; this.color = color; this.isSelected = false; } // 保存画布上所有的圆圈 var circles = []; var canvas; var context; window.onload = function() { canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); canvas.onmousedown = canvasClick; }; function addRandomCircle() { // 为圆圈计算一个随机大小和位置 var radius = randomFromTo(10, 60); var x = randomFromTo(0, canvas.width); var y = randomFromTo(0, canvas.height); // 为圆圈计算一个随机颜色 var colors = ["green", "blue", "red", "yellow", "magenta", "orange", "brown", "purple", "pink"]; var color = colors[randomFromTo(0, 8)]; // 创建一个新圆圈 var circle = new Circle(x, y, radius, color); // 把它保存在数组中 circles.push(circle); // 重新绘制画布 drawCircles(); } function clearCanvas() { // 去除所有圆圈 circles = []; // 重新绘制画布. drawCircles(); } function drawCircles() { // 清除画布,准备绘制 context.clearRect(0, 0, canvas.width, canvas.height); // 遍历所有圆圈 for(var i=0; i<circles.length; i++) { var circle = circles[i]; // 绘制圆圈 context.globalAlpha = 0.85; context.beginPath(); context.arc(circle.x, circle.y, circle.radius, 0, Math.PI*2); context.fillStyle = circle.color; context.strokeStyle = "black"; if (circle.isSelected) { context.lineWidth = 5; } else { context.lineWidth = 1; } context.fill(); context.stroke(); } } var previousSelectedCircle; function canvasClick(e) { // 取得画布上被单击的点 var clickX = e.pageX - canvas.offsetLeft; var clickY = e.pageY - canvas.offsetTop; // 查找被单击的圆圈 for(var i=circles.length-1; i>=0; i--) { var circle = circles[i]; //使用勾股定理计算这个点与圆心之间的距离 var distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2)) // 判断这个点是否在圆圈中 if (distanceFromCenter <= circle.radius) { // 清除之前选择的圆圈 if (previousSelectedCircle != null) previousSelectedCircle.isSelected = false; previousSelectedCircle = circle; //选择新圆圈 circle.isSelected = true; //更新显示 drawCircles(); //停止搜索 return; } } } //在某个范围内生成随机数 function randomFromTo(from, to) { return Math.floor(Math.random() * (to - from + 1) + from); } </script> </head> <body> <canvas> </canvas> <div> <button>添加圆圈</button> <button>清空画布</button> </div> </body> </html>
2,鼠标拖动图形对象
下面做个功能改进,允许用户在画布上拖动圆圈。只要监听Canvas的 onMouseMove 事件,相应地修改圆圈的坐标,然后再调用 drawCircle() 函数重绘画布即可。

添加圆圈 清空画布

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>hangge.com</title> <style> canvas { cursor: pointer; border: 1px solid black; } </style> <script> // 这个方法用来储存每个圆圈对象 function Circle(x, y, radius, color) { this.x = x; this.y = y; this.radius = radius; this.color = color; this.isSelected = false; } // 保存画布上所有的圆圈 var circles = []; var canvas; var context; window.onload = function() { canvas = document.getElementById("canvas"); context = canvas.getContext("2d"); canvas.onmousedown = canvasClick; canvas.onmouseup = stopDragging; canvas.onmouseout = stopDragging; canvas.onmousemove = dragCircle; }; function addRandomCircle() { // 为圆圈计算一个随机大小和位置 var radius = randomFromTo(10, 60); var x = randomFromTo(0, canvas.width); var y = randomFromTo(0, canvas.height); // 为圆圈计算一个随机颜色 var colors = ["green", "blue", "red", "yellow", "magenta", "orange", "brown", "purple", "pink"]; var color = colors[randomFromTo(0, 8)]; // 创建一个新圆圈 var circle = new Circle(x, y, radius, color); // 把它保存在数组中 circles.push(circle); // 重新绘制画布 drawCircles(); } function clearCanvas() { // 去除所有圆圈 circles = []; // 重新绘制画布. drawCircles(); } function drawCircles() { // 清除画布,准备绘制 context.clearRect(0, 0, canvas.width, canvas.height); // 遍历所有圆圈 for(var i=0; i<circles.length; i++) { var circle = circles[i]; // 绘制圆圈 context.globalAlpha = 0.85; context.beginPath(); context.arc(circle.x, circle.y, circle.radius, 0, Math.PI*2); context.fillStyle = circle.color; context.strokeStyle = "black"; if (circle.isSelected) { context.lineWidth = 5; } else { context.lineWidth = 1; } context.fill(); context.stroke(); } } var previousSelectedCircle; function canvasClick(e) { // 取得画布上被单击的点 var clickX = e.pageX - canvas.offsetLeft; var clickY = e.pageY - canvas.offsetTop; // 查找被单击的圆圈 for(var i=circles.length-1; i>=0; i--) { var circle = circles[i]; //使用勾股定理计算这个点与圆心之间的距离 var distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2) + Math.pow(circle.y - clickY, 2)) // 判断这个点是否在圆圈中 if (distanceFromCenter <= circle.radius) { // 清除之前选择的圆圈 if (previousSelectedCircle != null) previousSelectedCircle.isSelected = false; previousSelectedCircle = circle; //选择新圆圈 circle.isSelected = true; // 使圆圈允许拖拽 isDragging = true; //更新显示 drawCircles(); //停止搜索 return; } } } //在某个范围内生成随机数 function randomFromTo(from, to) { return Math.floor(Math.random() * (to - from + 1) + from); } var isDragging = false; function stopDragging() { isDragging = false; } function dragCircle(e) { // 判断圆圈是否开始拖拽 if (isDragging == true) { // 判断拖拽对象是否存在 if (previousSelectedCircle != null) { // 取得鼠标位置 var x = e.pageX - canvas.offsetLeft; var y = e.pageY - canvas.offsetTop; // 将圆圈移动到鼠标位置 previousSelectedCircle.x = x; previousSelectedCircle.y = y; // 更新画布 drawCircles(); } } } </script> </head> <body> <canvas> </canvas> <div> <button>添加圆圈</button> <button>清空画布</button> </div> </body> </html>

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • html5的canvas的学习笔记

    html5的canvas的学习笔记

    2017-12-03 10:42

  • 基于HTML5 Canvas的图表插件Chart.js

    基于HTML5 Canvas的图表插件Chart.js

    2017-12-01 10:07

  • 基于HTML5 Canvas 实现商场监控

    基于HTML5 Canvas 实现商场监控

    2017-12-01 10:04

  • html5 Canvas画图3:1像素线条模糊问题

    html5 Canvas画图3:1像素线条模糊问题

    2017-11-29 14:08

网友点评