首先是html代码:
<div id="control">
Stroke color:
<select id="strokeStyleSelect">
<option value="red">red</option>
<option value="green">green</option>
<option value="blue">blue</option>
<option value="orange">orange</option>
<option value="cornflowerblue">cornflowerblue</option>
<option value="goldenrod">goldenrod</option>
<option value="navy">navy</option>
<option value="purple"selected>purple</option>
</select>
fill color:
<select id="fillStyleSelect">
<option value="rgba(255,0,0,0.5)">red</option>
<option value="rgba(0,255,0,0.5)">green</option>
<option value="rgba(0,0,255,0.5)">blue</option>
<option value="rgba(255,165,0,0.5)"selected>orange</option>
<option value="rgba(100,149,237,0.5)">cornflowerblue</option>
<option value="rgba(218,165,32,0.5)">goldenrod</option>
<option value="rgba(0,0,128,0.5)">navy</option>
<option value="rgba(160,32,240,0.5)">purple</option>
<option value="rgba(0,0,0,0.5)">black</option>
</select>
sides:
<select id="sidesSelect">
<option value="3"selected>3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
start angle:
<select id="startAngleSelect">
<option value="0" selected>0</option>
<option value="15">15</option>
<option value="30">30</option>
<option value="45">45</option>
<option value="60">60</option>
<option value="75">75</option>
<option value="90">90</option>
<option value="0">105</option>
<option value="15">120</option>
<option value="30">135</option>
<option value="45">150</option>
<option value="60">165</option>
<option value="75">180</option>
</select>
Fill:
<input id="fillCheckbox" type="checkbox" checked/>
Edit:
<input id="editCheckbox" type="checkbox"/>
<input id="eraseAllButton" type="button" value="erase all"/>
</div>
<canvas id='canvas'width=1200 height=650>
can't use canvas
</canvas>
js实现代码:
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
eraseAllButton = document.getElementById('eraseAllButton'),
strokeStyleSelect = document.getElementById('strokeStyleSelect'),
fillStyleSelect = document.getElementById('fillStyleSelect'),
fillcheckbox = document.getElementById('fillCheckbox'),
editcheckbox = document.getElementById('editCheckbox'),
drawingSurfaceImageData,
mousedown = {},
rubberbandRect = {},
dragging = false,
draggingOffsetX,
draggingOffsetY,
sidesSelect = document.getElementById('sidesSelect'),
startAngleSelect = document.getElementById('startAngleSelect'),
returnToLast = document.getElementById('returnToLast'),
sides = 3,
startAngle = 0,
guidewire = true,
editing =false,
polygons = [],
Point = function(x, y){
this.x = x;
this.y = y;
};
var Polygon = function(centerX, centerY, radius, sides,startAngle,
strokeStyle, fillStyle, filled){
this.x = centerX;
this.y = centerY;
this.radius = radius;
this.sides = sides;
this.startAngle = startAngle;
this.strokeStyle = strokeStyle;
this.fillStyle = fillStyle;
this.filled = filled;
}
Polygon.prototype = {
getPoints: function(){
var points = [],
angle = this.startAngle|| 0;
for(var i = 0; i < this.sides; i++){
points.push(new Point(this.x+ this.radius* Math.sin(angle),
this.y- this.radius* Math.cos(angle)));
angle+= 2* Math.PI/ this.sides;
}
return points;
},
createPath: function(context){
var points= this.getPoints();
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for(var i= 1; i< this.sides; i++){
context.lineTo(points[i].x, points[i].y);
}
context.closePath();
},
stroke: function(context){
context.save();
this.createPath(context);
context.strokeStyle= this.strokeStyle;
context.stroke();
context.restore();
},
fill: function(context){
context.save();
this.createPath(context);
context.fillStyle= this.fillStyle;
context.fill();
context.restore();
},
move: function(x, y){
this.x= x;
this.y= y;
}
};
function windowToCanvas(x, y){
var bbox = canvas.getBoundingClientRect();
return {x: x - bbox.left * (canvas.width / bbox.width),
y: y - bbox.top * (canvas.height / bbox.height)};
}
function saveDrawingSurface(){
drawingSurfaceImageData = context.getImageData(0, 0,
canvas.width, canvas.height);
}
function restoreDrawingface(){
context.putImageData(drawingSurfaceImageData, 0, 0);
}
function drawPolygon(polygon){
context.beginPath();
polygon.createPath(context);
polygon.stroke(context);
if(fillcheckbox.checked){
polygon.fill(context);
}
}
function updateRubberbandRectangle(loc){
rubberbandRect.width= Math.abs(loc.x- mousedown.x);
rubberbandRect.height= Math.abs(loc.y- mousedown.y);
if(loc.x> mousedown.x) rubberbandRect.left= mousedown.x;
else rubberbandRect.left= loc.x;
if(loc.y> mousedown.y) rubberbandRect.top= mousedown.y;
else rubberbandRect.top= loc.y;
}
function drawRubberbandShape(loc, sides, startAngle){
var polygon= new Polygon(mousedown.x, mousedown.y,
rubberbandRect.width, parseInt(sidesSelect.value),
(Math.PI/ 180)* parseInt(startAngleSelect.value),
context.strokeStyle,
context.fillStyle,
fillcheckbox.checked);
drawPolygon(polygon);
if(!dragging)
polygons.push(polygon);
}
function updateRubberband(loc, sides, startAngle){
updateRubberbandRectangle(loc);
drawRubberbandShape(loc, sides, startAngle);
}
function drawPolygons(){
polygons.forEach(function(polygon){
drawPolygon(polygon);
});
}
function startDragging(loc){
saveDrawingSurface();
mousedown.x= loc.x;
mousedown.y= loc.y;
}
function stopEditing(){
canvas.style.cursor= 'crosshair';
editing= false;
}
function startEditing(){
canvas.style.cursor= 'pointer';
editing= true;
}
canvas.onmousedown= function (e){
var loc= windowToCanvas(e.clientX, e.clientY);
e.preventDefault();
if(editing){
polygons.forEach(function(polygon){
polygon.createPath(context);
if(context.isPointInPath(loc.x, loc.y)){
startDragging(loc);
dragging= polygon;
draggingOffsetX= loc.x- polygon.x;
draggingOffsetY= loc.y- polygon.y;
return;
}
});
}
else{
startDragging(loc);
dragging= true;
}
};
canvas.onmousemove= function(e){
var loc= windowToCanvas(e.clientX, e.clientY);
e.preventDefault();
if(editing && dragging){
dragging.x= loc.x - draggingOffsetX;
dragging.y= loc.y - draggingOffsetY;
context.clearRect(0, 0, canvas.width, canvas.height);
drawPolygons();
}
else{
if(dragging){
restoreDrawingface();
updateRubberband(loc, sides, startAngle);
}
}
};
canvas.onmouseup= function(e){
var loc= windowToCanvas(e.clientX, e.clientY);
dragging= false;
if(editing){
}
else{
restoreDrawingface();
updateRubberband(loc);
}
};
eraseAllButton.onclick= function(e){
context.clearRect(0, 0, canvas.width, canvas.height);
polygons= [];
saveDrawingSurface();
};
strokeStyleSelect.onchange=function(e){
context.strokeStyle= strokeStyleSelect.value;
};
fillStyleSelect.onchange = function(e){
context.fillStyle = fillStyleSelect.value;
};
editcheckbox.onchange = function(e){
if(editcheckbox.checked){
startEditing();
}
else
stopEditing();
};
context.lineWidth= 20;
context.strokeStyle = strokeStyleSelect.value;
context.fillStyle = fillStyleSelect.value;