【实例】html5-canvas绘制线段、矩形和圆

来源:互联网 发布:脂肪坏处 知乎 编辑:程序博客网 时间:2024/05/22 13:05

关键点

  • 鼠标按住之后实现绘图的预览,松手之后才真正画在canvas中
  • 绘制圆形的时候需要对圆的大小方位进行控制
  • 需要对当前鼠标的坐标进行精准的定位

代码实现

<!DOCTYPE html><html><head><meta charset="utf-8"><title></title><style type="text/css">#canvas {border: thin solid black;cursor: crosshair;}</style></head><body><div id="controls">辅助线间距<input id="step" type="number"/>辅助线颜色<select id="color"><option value="rgba(255,0,0,0.2)">红</option><option value="rgba(0,255,0,0.2)">绿</option><option value="rgba(0,0,255,0.2)">蓝</option></select><input type="button" value="生成" id="createButton">类型:<label for="line">线段<input type="radio" name="drawType" id="line" value="line" checked="checked" onclick="drawType='line'"/></label> <label for="rect">长方形<input type="radio" name="drawType" id="rect" value="rect"  onclick="drawType='rect'"/></label> <label for="circle">圆形<input type="radio" name="drawType" id="circle" value="circle"  onclick="drawType='circle'"/></label><p id="message"></p></div><canvas id="canvas" width="1200" height="800"></canvas></body><script type="text/javascript">var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");//当前绘制线段的起点var startPoint = {};//是否进行绘制的开关var isDraw = false;//保存鼠标拖动之前canvas的数据var contextDate = null;//绘制的图形,默认是线段var drawType = "line";var createButton = document.getElementById("createButton");createButton.onclick = function() {var step = document.getElementById("step").value;var color = document.getElementById("color").value;drawGuidesLine(parseInt(step), color);}//绘制水平线,水平线只有y坐标会变,横坐标一直是从0到canvas.widthfunction drawHorizontalLine(y) {context.beginPath();context.moveTo(0, y); context.lineTo(canvas.width, y);context.stroke();}//绘制竖直线,竖直线只有x坐标会变,纵坐标一直是从0到canvas.heightfunction drawVerticalLine(x) {context.beginPath();context.moveTo(x, 0);context.lineTo(x, canvas.height);context.stroke();}//绘制辅助线function drawGuidesLine(step ,color) {context.clearRect(0, 0, canvas.width, canvas.height);context.strokeStyle = color;for(var i = 0; i < canvas.height; i+=step) {drawHorizontalLine(i+0.5);}for(var i = 0; i < canvas.width; i+=step) {drawVerticalLine(i+0.5);}}function getLocation(e) {var bbox = document.getElementById("canvas").getBoundingClientRect();return {x: e.clientX - bbox.left * (canvas.width/bbox.width),y: e.clientY - bbox.top * (canvas.height/bbox.height)};}function drawLine(startPoint,  endPoint) {context.save();context.beginPath();context.moveTo(startPoint.x, startPoint.y);context.lineTo(endPoint.x, endPoint.y);context.stroke();context.closePath();}//绘制矩形方法function drawRect(startPoint, endPoint) {context.save();context.beginPath();context.strokeRect(startPoint.x, startPoint.y, endPoint.x-startPoint.x, endPoint.y-startPoint.y);context.stroke();context.closePath();}//绘制圆形方法function drawCircle(startPint, endPoint) {context.save();context.beginPath();//按照windows自带的画图工具的样子//先假想画出一个正方形//实际绘制的是与这个矩形四条边都相切的圆形//我想到了arcTo//坐标转换,因为画的是正圆形,所以虚拟的那个矩形就只能是正方形,我们画出来的线段应该是正方形的对角线//可如果不能满足正方形对角线的条件的话,我们就得转化了。//转化方式是以画出矩形的最短的那个边为正方形的边,绘制新的正方形(虚拟)//起始点和终止点之间横纵坐标的差值var distX = Math.abs(endPoint.x - startPoint.x);var distY = Math.abs(endPoint.y - startPoint.y);if(distX > distY) {//我们需要把起点到终点的X轴距离也设置成distYif(endPoint.x > startPoint.x) {//终点在起点之后endPoint.x = startPint.x + distY;} else {//终点在起点之前endPoint.x = startPoint.x - distY;}} else {if(endPoint.y > startPoint.y) {//终点在起点之后endPoint.y = startPint.y + distX;} else {//终点在起点之前endPoint.y = startPoint.y - distX;}}//drawRect(startPoint, endPoint);//此时我们才有了真正需要的正方形的坐标(其实是他的对角线)var radius = Math.abs(endPoint.x - startPoint.x) / 2;if(startPoint.x > endPoint.x) {context.moveTo(startPoint.x - radius, startPoint.y);} else {context.moveTo(startPoint.x + radius, startPoint.y);}context.arcTo(endPoint.x, startPoint.y, endPoint.x, endPoint.y, radius);context.arcTo(endPoint.x, endPoint.y, startPoint.x, endPoint.y, radius);context.arcTo(startPoint.x, endPoint.y, startPoint.x, startPoint.y, radius);if(startPint.x > endPoint.x) {context.arcTo(startPoint.x, startPoint.y, startPoint.x - radius, startPoint.y, radius);} else {context.arcTo(startPoint.x, startPoint.y, startPoint.x + radius, startPoint.y, radius);}context.stroke();context.closePath();}//保存当前画布的数据,主要用来在鼠标按住拖动的时候恢复到鼠标按下时时的样子,防止在鼠标拖动过程中绘制图像上去function saveImageData() {contextDate = context.getImageData(0, 0, canvas.width, canvas.height);}function restoreImageData() {context.putImageData(contextDate, 0, 0);}canvas.onmousedown = function(e) {context.strokeStyle = "black";startPoint = getLocation(e);isDraw = true;saveImageData();};canvas.onmousemove = function(e) {if(isDraw) {restoreImageData();//通过对drawType来辨别应该画什么图形if(drawType == "line") {drawLine(startPoint, getLocation(e));} else if(drawType == "rect"){drawRect(startPoint, getLocation(e));} else if(drawType == "circle") {drawCircle(startPoint, getLocation(e));}}};canvas.onmouseup = function(e) {isDraw = false;};</script></html>
在线演示
其实这个Demo没什么技术含量,其中绘制圆形的时候我不是通过arc而是先假想的绘制出一个正方形,之后在那个正方形中内切一个圆形来实现的。现在想想用arc方法应该更容易一吧。
0 0