html5中canvas繪製箭頭
阿新 • • 發佈:2018-12-07
網頁端程式碼
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>canvas滑鼠畫圖</title> <style> body { background-color:yellow;} #c1 { background-color: white; } </style> <script type="text/javascript" src="draw.js"></script> </head> <body> <canvas id="c1" width="800px" height="800px"> <span>該瀏覽器不支援canvas內容</span> </canvas> </body> </html>
js程式碼
function Position(x, y){ this.x = x; this.y = y; } var Vector = function (x, y) { var vec = { vx: x, vy: y, // 縮放 scale: function (scale) { vec.vx *= scale; vec.vy *= scale; }, //加 另一個向量 add: function (vec2) { vec.vx += vec2.vx; vec.vy += vec2.vy; }, //減 另一個向量 sub: function (vec2) { vec.vx -= vec2.vx; vec.vy -= vec2.vy; }, //相反方向 negate: function () { vec.vx = -vec.vx; vec.vy = -vec.vy; }, //向量長度 length: function () { return Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy); }, //向量長度的平方 lengthSquared: function () { return vec.vx * vec.vx + vec.vy * vec.vy; }, //標準化 normalize: function () { var len = Math.sqrt(vec.vx * vec.vx + vec.vy * vec.vy); if (len) { vec.vx /= len; vec.vy /= len; } return len; }, //旋轉 rotate: function (angle) { var vx = vec.vx, vy = vec.vy, cosVal = Math.cos(angle), sinVal = Math.sin(angle); vec.vx = vx * cosVal - vy * sinVal; vec.vy = vx * sinVal + vy * cosVal; }, //除錯 toString: function () { return '(' + vec.vx.toFixed(3) + ',' + vec.vy.toFixed(3) + ')'; } }; return vec; }; function Draw(context){ this.context = context; } function Circle(context, center){ Draw.call(this, context); this.center = center; this.radius = 10.0; this.draw = function(){ //外圓 context.fillStyle = "#555555"; context.strokeStyle = "#333333"; context.beginPath(); context.arc(this.center.x, this.center.y, this.radius, 0, 2*Math.PI, true); context.closePath(); context.stroke(); context.fill(); //內圓 context.fillStyle = "#888888"; context.beginPath(); context.arc(this.center.x, this.center.y, this.radius * 0.5, 0, 2*Math.PI, true); context.closePath(); context.fill(); } } Circle.prototype = new Draw(); function Line(context, startPosition, endPosition){ Draw.call(this, context); this.startPosition = startPosition; this.endPosition = endPosition; this.draw = function(){ context.strokeStyle = "#00ff00"; this.context.lineWidth = 5; this.context.moveTo(this.startPosition.x, this.startPosition.y); this.context.lineTo(this.endPosition.x, this.endPosition.y); this.context.stroke(); } } Line.prototype = new Draw(); function Arrow(context, startPosition, endPosition){ Draw.call(this, context); this.startPosition = startPosition; this.endPosition = endPosition; this.draw = function(){ var step = 15; var dir = Vector((this.endPosition.x - this.startPosition.x), (this.endPosition.y - this.startPosition.y)); dir.normalize(); context.strokeStyle = "#0000ff"; this.context.save(); this.context.translate(this.endPosition.x - step * dir.vx, this.endPosition.y - step * dir.vy); this.context.moveTo(-step * dir.vy , step * dir.vx); this.context.lineTo(step * dir.vx, step * dir.vy); this.context.lineTo(step * dir.vy , -step * dir.vx); this.context.stroke(); this.context.restore(); } } Arrow.prototype = new Draw(); function Belt(context, startPosition, endPosition){ Draw.call(this, context); this.circle = new Circle(context, startPosition); this.line = new Line(context, startPosition, endPosition); this.arrow = new Arrow(context, startPosition, endPosition); this.draw = function(){ this.circle.draw(); this.line.draw(); this.arrow.draw(); } this.select = function(position){ //position.x - startPosition.x } } Belt.prototype = new Draw(); window.onload = function() { var draws = []; var mouseFlag = false; var startPosition = null; var endPosition = null; var canvas = document.getElementById('c1'); var clientWidth = canvas.clientWidth; var clientHeight = canvas.clientHeight; var context = canvas.getContext('2d'); var curBelt = null; canvas.onmousedown = function(ev) { var ev = ev || window.event; startPosition = new Position(ev.clientX-canvas.offsetLeft,ev.clientY-canvas.offsetTop); mouseFlag = true; }; canvas.onmousemove = function(ev) { if(mouseFlag){ var ev = ev || window.event;//獲取event物件 endPosition = new Position(ev.clientX-canvas.offsetLeft,ev.clientY-canvas.offsetTop); context.clearRect(0,0,clientWidth,clientHeight); curBelt = new Belt(context, startPosition, endPosition); curBelt.draw(); for(var index=0; index<draws.length; ++index){ draws[index].select(ev.clientX-canvas.offsetLeft,ev.clientY-canvas.offsetTop); draws[index].draw(); } } }; canvas.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; mouseFlag = false; draws.push(curBelt); context.clearRect(0,0,clientWidth,clientHeight); for(var index=0; index<draws.length; ++index){ draws[index].draw(); } }; canvas.onmousemove = function(ev) { if(mouseFlag){ var ev = ev || window.event;//獲取event物件 endPosition = new Position(ev.clientX-canvas.offsetLeft,ev.clientY-canvas.offsetTop); context.clearRect(0,0,clientWidth,clientHeight); curBelt = new Belt(context, startPosition, endPosition); curBelt.draw(); for(var index=0; index<draws.length; ++index){ draws[index].draw(); } } }; };