HTML5 Canvas筆記——使用浮云DIV元素來實(shí)現(xiàn)橡皮筋式選取框

參考書目:《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;

效果如圖:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末谋作,一起剝皮案震驚了整個(gè)濱河市孝扛,隨后出現(xiàn)的幾起案子列吼,更是在濱河造成了極大的恐慌,老刑警劉巖苦始,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件寞钥,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡陌选,警方通過查閱死者的電腦和手機(jī)理郑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蹄溉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人您炉,你說我怎么就攤上這事柒爵。” “怎么了赚爵?”我有些...
    開封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵餐弱,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我囱晴,道長(zhǎng),這世上最難降的妖魔是什么瓢谢? 我笑而不...
    開封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任畸写,我火速辦了婚禮,結(jié)果婚禮上氓扛,老公的妹妹穿的比我還像新娘枯芬。我一直安慰自己,他們只是感情好采郎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開白布千所。 她就那樣靜靜地躺著,像睡著了一般蒜埋。 火紅的嫁衣襯著肌膚如雪淫痰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天整份,我揣著相機(jī)與錄音待错,去河邊找鬼。 笑死烈评,一個(gè)胖子當(dāng)著我的面吹牛火俄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讲冠,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瓜客,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了竿开?” 一聲冷哼從身側(cè)響起谱仪,我...
    開封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎德迹,沒想到半個(gè)月后芽卿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胳搞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年卸例,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了称杨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡筷转,死狀恐怖姑原,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情呜舒,我是刑警寧澤锭汛,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站袭蝗,受9級(jí)特大地震影響唤殴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜到腥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一朵逝、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧乡范,春花似錦配名、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至瓶佳,卻和暖如春芋膘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背涩哟。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工索赏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贴彼。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓潜腻,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親器仗。 傳聞我的和親對(duì)象是個(gè)殘疾皇子融涣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容