參考書目:《HTML5 Canvas核心技術(shù) 圖形、動(dòng)畫與游戲開發(fā)》
使用浮云DIV元素來實(shí)現(xiàn)橡皮筋式選取框
1-9.html
<!DOCTYPE html>
<html>
? <head>
? ? <title>
? ? ? ? Rubberbands with getImageData() and putImageData()
? ? </title>
? ? ? <style>
? ? ? ? body {
? ? ? ? ? ? background: rgba(100, 145, 250, 0.3);
? ? ? ? }
? ? ? ? #canvas {
? ? ? ? ? ? margin-left: 20px;
? ? ? ? ? ? margin-right: 0;
? ? ? ? ? ? margin-bottom: 20px;
? ? ? ? ? ? border: thin solid #aaaaaa;
? ? ? ? ? ? cursor: crosshair;
? ? ? ? }
? ? ? ? #controls {
? ? ? ? ? ? margin: 20px 0px 20px 20px;
? ? ? ? }
? ? ? </style>
? </head>
? <body>
? ? ? <div id='controls'>
? ? ? ? <input type='button' id='resetButton' value='Reset'/>
? ? ? </div>
? ? ? <canvas id='canvas' width='800' height='520'>
? ? ? ? Canvas not supported
? ? ? </canvas>
? ? <script src='1-10.js'></script>
? </body>
</html>
1-10.js
var canvas = document.getElementById('canvas'),
? ? context = canvas.getContext('2d'),
? ? resetButton = document.getElementById('resetButton'),
? ? image = new Image(),
? ? imageData,
? ? imageDataCopy = context.createImageData(canvas.width, canvas.height),
? ? mousedown = {},
? ? rubberbandRectangle = {},
? ? dragging = false;
function windowToCanvas(canvas, x, y) {
? var canvasRectangle = canvas.getBoundingClientRect();
? return {
? ? ? ? ? ? x: (x - canvasRectangle.left)*(canvas.width / canvasRectangle.width),
? ? ? ? ? ? y: (y - canvasRectangle.top) *(canvas.height / canvasRectangle.height)
? ? ? ? ? };
}
function copyCanvasPixels() {
? var i=0;
? for (i=0; i < 3; i++) {
? ? ? imageDataCopy.data[i] = imageData.data[i];
? }
? for (i=3; i < imageData.data.length - 4; i+=4) {
? ? ? imageDataCopy.data[i]? = imageData.data[i] / 2; // Alpha: more transparent
? ? ? imageDataCopy.data[i+1] = imageData.data[i+1]; // Red
? ? ? imageDataCopy.data[i+2] = imageData.data[i+2]; // Green
? ? ? imageDataCopy.data[i+3] = imageData.data[i+3]; // Blue
? }
}
function captureCanvasPixels() {
? imageData = context.getImageData(0, 0, canvas.width, canvas.height);
? copyCanvasPixels();
}
function restoreRubberbandPixels() {
? var deviceWidthOverCSSPixels = imageData.width / canvas.width,
? ? ? deviceHeightOverCSSPixels = imageData.height / canvas.height;
? context.putImageData(imageData, 0, 0);
? context.putImageData(imageDataCopy, 0, 0,
? ? ? (rubberbandRectangle.left + context.lineWidth),
? ? ? (rubberbandRectangle.top + context.lineWidth),
? ? ? (rubberbandRectangle.width - 2*context.lineWidth) * deviceWidthOverCSSPixels,
? ? ? (rubberbandRectangle.height - 2*context.lineWidth) * deviceHeightOverCSSPixels);
}
function setRubberbandRectangle(x, y) {
? rubberbandRectangle.left = Math.min(x, mousedown.x);
? rubberbandRectangle.top = Math.min(y, mousedown.y);
? rubberbandRectangle.width = Math.abs(x - mousedown.x),
? rubberbandRectangle.height = Math.abs(y - mousedown.y);
}
function drawRubberband() {
? var deviceWidthOverCSSPixels = imageData.width / canvas.width,
? ? ? deviceHeightOverCSSPixels = imageData.height / canvas.height;
? context.strokeRect(rubberbandRectangle.left + context.lineWidth,
? ? ? ? ? ? ? ? ? ? ? rubberbandRectangle.top + context.lineWidth,
? ? ? ? ? ? ? ? ? ? ? rubberbandRectangle.width - 2*context.lineWidth,
? ? ? ? ? ? ? ? ? ? ? rubberbandRectangle.height - 2*context.lineWidth);
}
function rubberbandStart(x, y) {
? mousedown.x = x;
? mousedown.y = y;
? rubberbandRectangle.left = mousedown.x;
? rubberbandRectangle.top = mousedown.y;
? rubberbandRectangle.width = 0;
? rubberbandRectangle.height = 0;
? dragging = true;
? captureCanvasPixels();
}
function rubberbandStretch(x, y) {
? if (rubberbandRectangle.width > 2*context.lineWidth &&
? ? ? rubberbandRectangle.height > 2*context.lineWidth) {
? ? ? if (imageData !== undefined) {
? ? ? ? restoreRubberbandPixels();
? ? ? }
? }
? setRubberbandRectangle(x, y);
? if (rubberbandRectangle.width > 2*context.lineWidth &&
? ? ? rubberbandRectangle.height > 2*context.lineWidth) {
? ? ? drawRubberband();
? }
};
function rubberbandEnd() {
? context.putImageData(imageData, 0, 0);
? context.drawImage(canvas,
? ? ? ? ? ? ? ? ? ? rubberbandRectangle.left + context.lineWidth*2,
? ? ? ? ? ? ? ? ? ? rubberbandRectangle.top + context.lineWidth*2,
? ? ? ? ? ? ? ? ? ? rubberbandRectangle.width - 4*context.lineWidth,
? ? ? ? ? ? ? ? ? ? rubberbandRectangle.height - 4*context.lineWidth,
? ? ? ? ? ? ? ? ? ? 0, 0, canvas.width, canvas.height);
? dragging = false;
? imageData = undefined;
}
canvas.onmousedown = function (e) {
? var loc = windowToCanvas(canvas, e.clientX, e.clientY);
? e.preventDefault();
? rubberbandStart(loc.x, loc.y);
};
canvas.onmousemove = function (e) {
? var loc;
? if (dragging) {
? ? ? loc = windowToCanvas(canvas, e.clientX, e.clientY);
? ? ? rubberbandStretch(loc.x, loc.y);
? ? }
}
canvas.onmouseup = function (e) {
? rubberbandEnd();
};
image.src = 'arch.png';
image.onload = function () {
? context.drawImage(image, 0, 0, canvas.width, canvas.height);
};
resetButton.onclick = function(e) {
? ? context.clearRect(0, 0,
? ? ? canvas.width, canvas.height);
? ? context.drawImage(image, 0, 0, canvas.width, canvas.height);
};
context.strokeStyle = 'navy';
context.lineWidth = 1.0;
效果如圖: