HTML5 Canvas笔记——橡皮筋式绘图二
2020-04-22 本文已影响0人
没昔
编程实现:橡皮筋式绘图。
参考书目:《HTML5 Canvas核心技术 图形、动画与游戏开发》
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
body {
background: #dddddd;
}
#canvas {
margin-left: 10px;
margin-top: 10px;
cursor: pointer;
background: #ffffff;
-webkit-webkit: box shadow 4px;
-moz-webkit: box shadow 4px;
-ms-webkit: box shadow 4px;
-o-webkit: box shadow 4px;
box-shadow: 4px 4px 8px raga(0, 0, 0, 0.5);
}
</style>
</head>
<body>
<canvas id="canvas" width="600" height="400">Canvas not suported!</canvas>
<div id='controls'>
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">purple</option>
</select> Draw shape:
<select id='strokeShapeSelect'>
<option value="circle">circle</option>
<option value="line">line</option>
<option value="rect">rect</option>
</select> Line style:
<select id='lineStyleSelect'>
<option value="solid">solid</option>
<option value="virtual">virtual</option>
</select>Gide wires:
<input type="checkbox" checked id="guidewireCheckbox">
<input type="button" value="Erase all" id="eraseAllButton">
</div>
<script src="2-16.js"></script>
</body>
</html>
2-16.js
var canvas = document.getElementById("canvas")
var context = canvas.getContext("2d")
var eraseAllButton = document.getElementById('eraseAllButton')
var guidewireCheckbox = document.getElementById('guidewireCheckbox')
var strokeStyleSelect = document.getElementById('strokeStyleSelect')
var strokeShapeSelect = document.getElementById('strokeShapeSelect')
var lineStyleSelect = document.getElementById('lineStyleSelect')
var strokeShape = strokeShapeSelect.value;
var lineStyle = lineStyleSelect.value;
var drawingSurfaceImageData;
var mousedown = {}
var rubberbandRect = {}
var dragging = false
var guidewires = guidewireCheckbox.checked
function drawGrid(color, stepx, stepy) {
context.save()
context.setLineDash([])
context.strokeStyle = color;
context.lineWidth = 0.5;
for (var i = stepx + 0.5; i < canvas.width; i += stepx) {
context.beginPath();
context.moveTo(i, 0);
context.lineTo(i, canvas.height);
context.stroke();
}
for (var i = stepy + 0.5; i < canvas.height; i += stepy) {
context.beginPath();
context.moveTo(0, i);
context.lineTo(canvas.width, i);
context.stroke();
}
context.restore()
}
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 restoreDrawingSurface() {
context.putImageData(drawingSurfaceImageData, 0, 0);
}
function updateLocation(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 drawLine(loc) { //画线条
context.beginPath();
context.moveTo(mousedown.x, mousedown.y);
context.lineTo(loc.x, loc.y);
context.stroke();
}
function drawRect(loc) { //画矩形
context.beginPath();
context.rect(mousedown.x, mousedown.y, loc.x - mousedown.x, loc.y - mousedown.y);
context.stroke();
}
function drawCircle(loc) { //画圆
context.beginPath();
X = (loc.x - mousedown.x);
Y = (loc.y - mousedown.y);
context.arc(mousedown.x + X / 2, mousedown.y + Y / 2, Math.sqrt(X * X + Y * Y) / 2, 0, Math.PI * 2);
context.stroke();
}
function updateRubberband(loc) {
updateLocation(loc);
switch (strokeShape) {
case "line":
drawLine(loc);
break;
case "rect":
drawRect(loc);
break;
case "circle":
drawCircle(loc);
break;
default:
break;
}
}
function drawHorizontalLine(y) {
context.beginPath();
context.moveTo(0, y + 0.5);
context.lineTo(context.canvas.width, y + 0.5);
context.stroke();
}
function drawVerticalLine(x) {
context.beginPath();
context.moveTo(x + 0.5, 0);
context.lineTo(x + 0.5, context.canvas.height);
context.stroke();
}
function drawGuidewires(x, y) {
context.save();
context.setLineDash([])
context.strokeStyle = 'rgba(0.0,20,0.4)';
context.lineWidth = 0.5;
drawVerticalLine(x);
drawHorizontalLine(y);
context.restore();
}
canvas.onmousedown = function(e) {
var loc = windowToCanvas(e.clientX, e.clientY);
e.preventDefault();
saveDrawingSurface();
mousedown.x = loc.x;
mousedown.y = loc.y;
dragging = true;
}
canvas.onmousemove = function(e) {
var loc;
if (dragging) {
e.preventDefault();
loc = windowToCanvas(e.clientX, e.clientY);
restoreDrawingSurface();
updateRubberband(loc);
if (guidewires) {
drawGuidewires(loc.x, loc.y);
}
}
}
canvas.onmouseup = function(e) {
loc = windowToCanvas(e.clientX, e.clientY);
restoreDrawingSurface();
updateRubberband(loc);
dragging = false;
}
eraseAllButton.onclick = function() {
context.clearRect(0, 0, canvas.width, canvas.height);
saveDrawingSurface();
drawGrid('lightgray', 10, 10);
}
strokeStyleSelect.onchange = function() {
context.strokeStyle = strokeStyleSelect.value;
}
strokeShapeSelect.onchange = function() {
strokeShape = strokeShapeSelect.value;
}
lineStyleSelect.onchange = function() {
lineStyle = lineStyleSelect.value;
if (lineStyle == "virtual") {
context.setLineDash([8, 8])
} else {
context.setLineDash([])
}
}
guidewireCheckbox.onchange = function() {
guidewires = guidewireCheckbox.checked;
}
drawGrid('lightgray', 10, 10);
context.strokeStyle = strokeStyleSelect.value;