利用 canvas
除了可以實(shí)現(xiàn)濾鏡,還可以利用 離屏技術(shù) 放大鏡功能。
為了方便講解,本文分為 2 個(gè)應(yīng)用部分:
1. 什么是離屏技術(shù)?
canvas 學(xué)習(xí)和濾鏡實(shí)現(xiàn) 介紹過(guò) drawImage
接口。除了繪制圖像,這個(gè)接口還可以: 將一個(gè) canvas
對(duì)象繪制到另一個(gè) canvas
對(duì)象上 。這就是離屏技術(shù)。
2. 實(shí)現(xiàn)水印和中心縮放
在代碼中,有兩個(gè) canvas 標(biāo)簽。分別是可見(jiàn)與不可見(jiàn)。 不可見(jiàn)的 canvas 對(duì)象上的 Context 對(duì)象,就是我們放置圖像水印的地方。
更多詳解,請(qǐng)看代碼注釋?zhuān)?/p>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Learn Canvas</title> <style> canvas { display: block; margin: 0 auto; border: 1px solid #222; } input { display: block; margin: 20px auto; width: 800px } </style> </head> <body> <div id="app"> <canvas id="my-canvas"></canvas> <input type="range" value="1.0" min="0.5" max="3.0" step="0.1"> <canvas id="watermark-canvas" style="display: none;"></canvas> </div> <script type="text/javascript"> window.onload = function () { var canvas = document.querySelector("#my-canvas") var watermarkCanvas = document.querySelector("#watermark-canvas") var slider = document.querySelector("input") var scale = slider.value var ctx = canvas.getContext('2d') var watermarkCtx = watermarkCanvas.getContext("2d") /* 給第二個(gè)canvas獲取的Context對(duì)象添加水印 */ watermarkCanvas.width = 300 watermarkCanvas.height = 100 watermarkCtx.font = "bold 20px Arial" watermarkCtx.lineWidth = "1" watermarkCtx.fillStyle = "rgba(255 , 255 , 255, 0.5)" watermarkCtx.fillText("=== yuanxin.me ===", 50, 50) /****************************************/ var img = new Image() img.src = "./img/photo.jpg" /* 加載圖片后執(zhí)行操作 */ img.onload = function () { canvas.width = img.width; canvas.height = img.height; drawImageByScale(canvas, ctx, img, scale, watermarkCanvas); // 監(jiān)聽(tīng)input標(biāo)簽的mousemove事件 // 注意:mousemove實(shí)時(shí)監(jiān)聽(tīng)值的變化,內(nèi)存消耗較大 slider.onmousemove = function () { scale = slider.value drawImageByScale(canvas, ctx, img, scale, watermarkCanvas); } } /******************/ } /** * * @param {Object} canvas 畫(huà)布對(duì)象 * @param {Object} ctx * @param {Object} img * @param {Number} scale 縮放比例 * @param {Object} watermark 水印對(duì)象 */ function drawImageByScale(canvas, ctx, img, scale, watermark) { // 圖像按照比例進(jìn)行縮放 var width = img.width * scale, height = img.height * scale // (dx, dy): 畫(huà)布上繪制img的起始坐標(biāo) var dx = canvas.width / 2 - width / 2, dy = canvas.height / 2 - height / 2 ctx.clearRect(0, 0, canvas.width, canvas.height) // No1 清空畫(huà)布 ctx.drawImage(img, dx, dy, width, height) // No2 重新繪制圖像 if (watermark) { // No3 判斷是否有水印: 有, 繪制水印 ctx.drawImage(watermark, canvas.width - watermark.width, canvas.height - watermark.height) } } </script> </body> </html>
實(shí)現(xiàn)效果如下圖所示:
拖動(dòng)滑竿,即可放大和縮小圖像。然后右鍵保存圖像。保存后的圖像,就有已經(jīng)有了水印,如下圖所示:
3. 實(shí)現(xiàn)放大鏡
在上述中心縮放的基礎(chǔ)上,實(shí)現(xiàn)放大鏡主需要注意以下 2 個(gè)部分:
代碼如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style> canvas { display: block; margin: 0 auto; border: 1px solid #222; } </style> </head> <body> <canvas id="my-canvas"></canvas> <canvas id="off-canvas" style="display: none;"></canvas> <script> var isMouseDown = false, scale = 1.0 var canvas = document.querySelector("#my-canvas") var offCanvas = document.querySelector("#off-canvas") // 離屏 canvas var ctx = canvas.getContext("2d") var offCtx = offCanvas.getContext("2d") // 離屏 canvas 的 Context對(duì)象 var img = new Image() window.onload = function () { img.src = "./img/photo.jpg" img.onload = function () { canvas.width = img.width canvas.height = img.height offCanvas.width = img.width offCanvas.height = img.height // 計(jì)算縮放比例 scale = offCanvas.width / canvas.width // 初識(shí)狀態(tài)下, 兩個(gè)canvas均繪制Image ctx.drawImage(img, 0, 0, canvas.width, canvas.height) offCtx.drawImage(img, 0, 0, canvas.width, canvas.height) } // 鼠標(biāo)按下 canvas.onmousedown = function (event) { event.preventDefault() // 禁用默認(rèn)事件 var point = windowToCanvas(event.clientX, event.clientY) // 獲取鼠標(biāo)相對(duì)于 canvas 標(biāo)簽的坐標(biāo) isMouseDown = true drawCanvasWithMagnifier(true, point) // 繪制在離屏canvas上繪制放大后的圖像 } // 鼠標(biāo)移動(dòng) canvas.onmousemove = function (event) { event.preventDefault() // 禁用默認(rèn)事件 if (isMouseDown === true) { var point = windowToCanvas(event.clientX, event.clientY) drawCanvasWithMagnifier(true, point) } } // 鼠標(biāo)松開(kāi) canvas.onmouseup = function (event) { event.preventDefault() // 禁用默認(rèn)事件 isMouseDown = false drawCanvasWithMagnifier(false) // 不繪制離屏放大鏡 } // 鼠標(biāo)移出canvas標(biāo)簽 canvas.onmouseout = function (event) { event.preventDefault() // 禁用默認(rèn)事件 isMouseDown = false drawCanvasWithMagnifier(false) // 不繪制離屏放大鏡 } } /** * 返回鼠標(biāo)相對(duì)于canvas左上角的坐標(biāo) * @param {Number} x 鼠標(biāo)的屏幕坐標(biāo)x * @param {Number} y 鼠標(biāo)的屏幕坐標(biāo)y */ function windowToCanvas(x, y) { var bbox = canvas.getBoundingClientRect() // bbox中存儲(chǔ)的是canvas相對(duì)于屏幕的坐標(biāo) return { x: x - bbox.x, y: y - bbox.y } } function drawCanvasWithMagnifier(isShow, point) { ctx.clearRect(0, 0, canvas.width, canvas.height) // 清空畫(huà)布 ctx.drawImage(img, 0, 0, canvas.width, canvas.height) // 在畫(huà)布上繪制圖像 /* 利用離屏,繪制放大鏡 */ if (isShow) { var { x, y } = point var mr = 50 // 正方形放大鏡邊長(zhǎng) // (sx, sy): 待放大圖像的開(kāi)始坐標(biāo) var sx = x - mr / 2, sy = y - mr / 2 // (dx, dy): 已放大圖像的開(kāi)始坐標(biāo) var dx = x - mr, dy = y - mr // 將offCanvas上的(sx,sy)開(kāi)始的長(zhǎng)寬均為mr的正方形區(qū)域 // 放大到 // canvas上的(dx,dy)開(kāi)始的長(zhǎng)寬均為 2 * mr 的正方形可視區(qū)域 // 由此實(shí)現(xiàn)放大效果 ctx.drawImage(offCanvas, sx, sy, mr, mr, dx, dy, 2 * mr, 2 * mr) } /*********************/ } </script> </body> </html>
放大鏡效果如下圖所示(被紅筆標(biāo)出的區(qū)域就是我們的正方形放大鏡):
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
標(biāo)簽:阿壩 綏化 萍鄉(xiāng) 盤(pán)錦 聊城 金昌 赤峰 中山
巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《canvas離屏技術(shù)與放大鏡實(shí)現(xiàn)代碼示例》,本文關(guān)鍵詞 canvas,離屏,技術(shù),與,放大鏡,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。