canvas離屏技術與放大鏡實現

教程所示圖片使用的是 github 倉庫圖片,網速過慢的朋友請移步>>> (原文)canvas 離屏技術與放大鏡實現。

更多討論或者錯誤提交,也請移步。

利用

canvas
除了可以實現濾鏡,還可以利用離屏技術放大鏡功能。

為了方便講解,本文分為 2 個應用部分:

  1. 實現水印和中心縮放
  2. 實現放大鏡

1. 什么是離屏技術?

canvas 學習和濾鏡實現介紹過

drawImage
接口。除了繪制圖像,這個接口還可以: 將一個
canvas
對象繪制到另一個
canvas
對象上
。這就是離屏技術。

2. 實現水印和中心縮放

在代碼中,有兩個 canvas 標簽。分別是可見與不可見。不可見的 canvas 對象上的 Context 對象,就是我們放置圖像水印的地方。

更多詳解,請看代碼注釋:

<!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.valuevar ctx = canvas.getContext('2d')var watermarkCtx = watermarkCanvas.getContext("2d")/* 給第二個canvas獲取的Context對象添加水印 */watermarkCanvas.width = 300watermarkCanvas.height = 100watermarkCtx.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"/* 加載圖片后執行操作 */img.onload = function () {canvas.width = img.width;canvas.height = img.height;drawImageByScale(canvas, ctx, img, scale, watermarkCanvas);// 監聽input標簽的mousemove事件// 注意:mousemove實時監聽值的變化,內存消耗較大slider.onmousemove = function () {scale = slider.valuedrawImageByScale(canvas, ctx, img, scale, watermarkCanvas);}}/******************/}/**** @param {Object} canvas 畫布對象* @param {Object} ctx* @param {Object} img* @param {Number} scale 縮放比例* @param {Object} watermark 水印對象*/function drawImageByScale(canvas, ctx, img, scale, watermark) {// 圖像按照比例進行縮放var width = img.width * scale,height = img.height * scale// (dx, dy): 畫布上繪制img的起始坐標var dx = canvas.width / 2 - width / 2,dy = canvas.height / 2 - height / 2ctx.clearRect(0, 0, canvas.width, canvas.height) // No1 清空畫布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>

實現效果如下圖所示:

拖動滑竿,即可放大和縮小圖像。然后右鍵保存圖像。保存后的圖像,就有已經有了水印,如下圖所示:

3. 實現放大鏡

在上述中心縮放的基礎上,實現放大鏡主需要注意以下 2 個部分:

  1. 細化處理
    canvas
    的鼠標響應事件:滑入、滑出、點擊和松開
  2. 重新計算離屏坐標(詳細公式計算思路請見代碼注釋)
  3. 重新計算鼠標相對于 canvas 標簽的坐標(詳細公式計算思路請見代碼注釋)

代碼如下:

<!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.0var canvas = document.querySelector("#my-canvas")var offCanvas = document.querySelector("#off-canvas") // 離屏 canvasvar ctx = canvas.getContext("2d")var offCtx = offCanvas.getContext("2d") // 離屏 canvas 的 Context對象var img = new Image()window.onload = function () {img.src = "./img/photo.jpg"img.onload = function () {canvas.width = img.widthcanvas.height = img.heightoffCanvas.width = img.widthoffCanvas.height = img.height// 計算縮放比例scale = offCanvas.width / canvas.width// 初識狀態下, 兩個canvas均繪制Imagectx.drawImage(img, 0, 0, canvas.width, canvas.height)offCtx.drawImage(img, 0, 0, canvas.width, canvas.height)}// 鼠標按下canvas.onmousedown = function (event) {event.preventDefault() // 禁用默認事件var point = windowToCanvas(event.clientX, event.clientY) // 獲取鼠標相對于 canvas 標簽的坐標isMouseDown = truedrawCanvasWithMagnifier(true, point) // 繪制在離屏canvas上繪制放大后的圖像}// 鼠標移動canvas.onmousemove = function (event) {event.preventDefault() // 禁用默認事件if (isMouseDown === true) {var point = windowToCanvas(event.clientX, event.clientY)drawCanvasWithMagnifier(true, point)}}// 鼠標松開canvas.onmouseup = function (event) {event.preventDefault() // 禁用默認事件isMouseDown = falsedrawCanvasWithMagnifier(false) // 不繪制離屏放大鏡}// 鼠標移出canvas標簽canvas.onmouseout = function (event) {event.preventDefault() // 禁用默認事件isMouseDown = falsedrawCanvasWithMagnifier(false) // 不繪制離屏放大鏡}}/*** 返回鼠標相對于canvas左上角的坐標* @param {Number} x 鼠標的屏幕坐標x* @param {Number} y 鼠標的屏幕坐標y*/function windowToCanvas(x, y) {var bbox = canvas.getBoundingClientRect() // bbox中存儲的是canvas相對于屏幕的坐標return {x: x - bbox.x,y: y - bbox.y}}function drawCanvasWithMagnifier(isShow, point) {ctx.clearRect(0, 0, canvas.width, canvas.height) // 清空畫布ctx.drawImage(img, 0, 0, canvas.width, canvas.height) // 在畫布上繪制圖像/* 利用離屏,繪制放大鏡 */if (isShow) {var { x, y } = pointvar mr = 50 // 正方形放大鏡邊長// (sx, sy): 待放大圖像的開始坐標var sx = x - mr / 2,sy = y - mr / 2// (dx, dy): 已放大圖像的開始坐標var dx = x - mr,dy = y - mr// 將offCanvas上的(sx,sy)開始的長寬均為mr的正方形區域// 放大到// canvas上的(dx,dy)開始的長寬均為 2 * mr 的正方形可視區域// 由此實現放大效果ctx.drawImage(offCanvas, sx, sy, mr, mr, dx, dy, 2 * mr, 2 * mr)}/*********************/}</script>
</body>
</html>

放大鏡效果如下圖所示(被紅筆標出的區域就是我們的正方形放大鏡):

歡迎入群:857989948 。IT 技術深度交流和分享,涉及方面包括但不限于:網站制作、運營、UI 設計、算法分析、大數據、人工智能等。本群主打有深度、有態度的技術交流,歡迎熱衷記錄知識的您的加入。

本文轉載于:猿2048https://www.mk2048.com/blog/blog.php?id=k2ihkj&title=canvas離屏技術與放大鏡實現

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/370950.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/370950.shtml
英文地址,請注明出處:http://en.pswp.cn/news/370950.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

虛擬機下安裝ubuntu后root密碼設置

問題描述&#xff1a; 在虛擬機下安裝了ubuntu中要輸入用戶名&#xff0c;一般情況下大家都會輸入一個自己的網名或綽號之類的&#xff0c;密碼也在這時設置過了。 但是當安裝成功之后&#xff0c;使用命令#su root&#xff0c;然后輸入剛才設置的密碼&#xff0c;發現密碼錯誤…

使用Ajax的Spring MVC REST調用

這篇文章提供了對Spring MVC Web應用程序的REST調用的簡單示例。 它基于在Spring MVC上下文示例中使用Spring MVC服務靜態資源和使用Ajax獲取JSON 。 該代碼可在GitHub的Spring-REST-With-Ajax目錄中找到。 主頁 我們的主頁包含與執行Ajax調用的Javascript函數鏈接的四個按鈕…

團隊作業—預則立他山之石

團隊作業—預則立&&他山之石 Deadline: 2017.10.24 22:00pm 作業要求 一、確立團隊選題&#xff0c;建立和初步熟悉團隊git的協作方式。項目后續的代碼、文檔都要通過github增量式管理。實現文檔的版本化和增量式管理。 二、初步確立團隊任務計劃&#xff0c;將團隊的任…

linux7系統如何配置網卡,Linux 7 配置網卡(nmcli)

操作系統版本&#xff1a;[rootcjcos01 network-scripts]# cat /etc/redhat-releaseRed Hat Enterprise Linux Server release 7.5 (Maipo)查看網卡、IP等信息&#xff1a;[rootcjcos01 ~]# ifconfigenp0s3: flags4163 mtu 1500inet 192.168.1.90 netmask 255.255.255.0 bro…

學以致用深入淺出數字信號處理 pdf_數字陣列雷達--相控陣專題講座之三

數字陣列雷達-相控陣專題講座之三https://www.zhihu.com/video/1218562626877583360從名詞上看&#xff0c;數字陣列雷達&#xff0c;肯定是陣列雷達了&#xff0c;那么數字陣列與傳統的相控陣雷達又有什么區別呢&#xff1f;傳統的相控陣雷達&#xff0c;是依靠移相器、衰減器…

Ubuntu中右擊出現終端

1 root用戶 $sudo apt-get install nautilus-open-terminal 2重啟 3ok 轉載于:https://www.cnblogs.com/lanjianhappy/p/6761599.html

MapReduce:處理數據密集型文本處理–局部聚合第二部分

這篇文章繼續進行有關使用MapReduce進行數據密集型處理的書中實現算法的系列文章。 第一部分可以在這里找到。 在上一篇文章中&#xff0c;我們討論了使用本地聚合技術來減少通過網絡進行混洗和傳輸的數據量的方法。 減少傳輸的數據量是提高MapReduce作業效率的主要方法之一。 …

python爬蟲需要什么知識-學習Python爬蟲技術,需要掌握哪些web端的知識?

HTML5&#xff1a;html概述和基本結構、html標題標簽、html段落標簽、換行標簽、塊標簽、圖片標簽、a鏈接標簽、列表標簽、表格、表單、頁面布局等。 CSS3&#xff1a;CSS基本語法和頁面引用、CSS文本設置、顏色表示法、CSS選擇器、盒子模型、盒子模型實際尺寸、浮動、四大定位…

UDP學習總結

1、UDP的優勢是什么&#xff1f;有哪些典型的應用是使用UDP的&#xff1f;為什么&#xff1f; 2、轉載于:https://www.cnblogs.com/zhouhaibing/p/7669251.html

Linux版本的SVN客戶端,linux 下安裝 subversion(svn) 客戶端

svn server 為只支持http://協議的windows;test web server 為as4,現需安裝svn客戶端方便同步代碼網上找了下都是講如何安裝svn server的&#xff0c;我只需要一個支持http協議的客戶端哈&#xff0c;不想裝apache。安裝所需軟件apr,apr-util,sqlite,neon,subversion1.下載軟件…

使用bootstrap的dropdown部件時報錯:error:Bootstrap dropdown require Popper.js

前言&#xff1a;前端小白一枚&#xff0c;剛注冊博客&#xff0c;先發個學習過程中新碰到小問題試試水吧~ 摘要&#xff1a;最近在學習bootstrap&#xff0c;偶然碰到了一個小問題&#xff0c;bootstrap網站也沒有做過多的解釋&#xff0c;今天分享給大家。 問題描述&#x…

C#中的三層

三層架構(3-tier architecture) 通常意義上的三層架構就是將整個業務應用劃分為&#xff1a;界面層&#xff08;User Interface layer&#xff09;、業務邏輯層&#xff08;Business Logic Layer&#xff09;、數據訪問層&#xff08;Data access layer&#xff09;。區分層次的…

研究僵局–第3部分

在本系列的前兩個博客&#xff08; 第1部分和第2部分&#xff09;中 &#xff0c;我演示了如何創建一段死鎖的不良代碼&#xff0c;然后使用該代碼展示了進行線程轉儲的三種方式。 在這個博客中&#xff0c;我將分析線程轉儲以找出錯誤的原因。 下面的討論同時涉及本系列第1部…

qq2009顯ip版怎么用_毛孔粗大怎么破?用對方法,輕松改善顯皮膚嫩滑

臉上毛孔粗大怎么破&#xff1f;超級煩惱尤其是一到秋季臉上經常油膩膩的為什么會毛孔粗大呢&#xff1f;毛孔粗大怎么破&#xff1f;用對方法&#xff0c;輕松改善顯皮膚嫩滑 當皮膚老舊角質積聚越多&#xff0c;會使肌膚變厚、變粗糙&#xff0c;毛孔變粗大&#xff0c;肌膚也…

linux 賬號密碼 字段,詳解Linux中的用戶密碼管理命令passwd和change

passwd修改用戶密碼參數-k 保持未過期身份驗證令牌-l 關閉賬號密碼。效果相當于usermod -L&#xff0c;只有root才有權使用此項。-u 恢復賬號密碼。效果相當于usermod -U&#xff0c;同樣只有root才有權使用。-g 修改組密碼。gpasswd的等效命令。-f 更改由finger命令訪問的用戶…

hello程序的運行過程-從計算機系統角度

hello程序的運行過程-從計算機系統角度 1、gcc編譯器驅動程序讀取源程序文件hello.c&#xff0c;并將它翻譯成一個可執行目標文件hello。翻譯過程分為四個階段&#xff1a;預處理階段&#xff0c;編譯階段&#xff0c;匯編階段&#xff0c;鏈接階段。 2、初始時&#xff0c;she…

靠譜的div引入任何外鏈內容

靠譜的div引入任何外鏈內容 開發中經常要在div中引入一個頁面,該頁面可能是內部頁面,可能是一個外部頁面,也可能只是一個域名獲取的請求. 對于內部頁面的加載,建議使用jquery的load函數,如: 1 $("#targetId").load("someUrl/templatePage.html"); 對于外…

Eclipse對類固醇的重構

在上一篇有關常見Java違規的文章中 &#xff0c;我列出了Java開發人員容易犯的一系列錯誤。 在重構Java項目以解決這些違規問題的同時&#xff0c;我廣泛使用了Eclipse的重構功能來快速更改代碼。 下面是這種重構技術的匯編。 1.在塊級語句周圍添加花括號 用{curly braces}包裝…

微服務發展的歷史_“美麗新羌 光照未來” 新羌社區開展微視頻宣傳片拍攝活動...

見圳客戶端、深圳新聞網訊(記者 王志明 通訊員 甘力宇)為記錄新羌社區的歷史變遷&#xff0c;弘揚新羌人與時俱進、開拓進取的創新精神&#xff0c;宣傳社區黨委、社區一線工作者及社區居民的感人事跡和精神&#xff0c;展現深圳社區發展新風貌&#xff0c;2020年10月&#xff…

linux中掃描儀驅動程序,VueScan For Linux通用掃描儀驅動下載_VueScan For Linux通用掃描儀驅動官方下載-太平洋下載中心...

VueScan For Linux通用掃描儀驅動是一款提供 Linux 使用的圖片掃描工具&#xff0c;它具有各種高級硬件能力使用非常廣泛的的掃描儀軟件&#xff0c;支持EPSon、HP、Nikon 和Canon 品牌的掃描儀設備&#xff0c;具有優良的色彩保真度和色彩平衡&#xff0c;可以讓用戶比平板掃描…