【实例】html5-canvas绘制线段、矩形和圆
2015-08-15 19:50
756 查看
关键点
鼠标按住之后实现绘图的预览,松手之后才真正画在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.width function drawHorizontalLine(y) { context.beginPath(); context.moveTo(0, y); context.lineTo(canvas.width, y); context.stroke(); } //绘制竖直线,竖直线只有x坐标会变,纵坐标一直是从0到canvas.height function 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轴距离也设置成distY if(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方法应该更容易一吧。
相关文章推荐
- html5 说明
- 【学习Egret】第一个H5小游戏,人人来打产品汪
- 基于Html5缓存的页面P2P技术可行性探讨
- H5实现支付宝的集成
- Java EE HTML5 WebSocket 示例
- html5 canvas
- HTML5元素、属性和格式化
- HTML5 重力感应效果,实现摇一摇效果
- H5页面性能优化
- 脚本化CSS类-HTML5 classList属性
- 24个 HTML5 & CSS3 下拉菜单制作教程
- HTML5基础
- Html5 Canvas笔记(2)-Canvas绘图
- H5填坑笔记--持续更新
- 为什么学习html5
- Notepad++巨大灾难!史诗级错误~
- html5 -- canvas画图
- html5 touch引发的一个应用以及营销
- HTML5简介
- 基于iSroll插件实现html5页面上拉加载更多