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.mzph.cn/news/370950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Ajax的Spring MVC REST调用

这篇文章提供了对Spring MVC Web应用程序的REST调用的简单示例。 它基于在Spring MVC上下文示例中使用Spring MVC服务静态资源和使用Ajax获取JSON 。 该代码可在GitHub的Spring-REST-With-Ajax目录中找到。 主页 我们的主页包含与执行Ajax调用的Javascript函数链接的四个按钮…

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

使用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;肌肤也…

hello程序的运行过程-从计算机系统角度

hello程序的运行过程-从计算机系统角度 1、gcc编译器驱动程序读取源程序文件hello.c&#xff0c;并将它翻译成一个可执行目标文件hello。翻译过程分为四个阶段&#xff1a;预处理阶段&#xff0c;编译阶段&#xff0c;汇编阶段&#xff0c;链接阶段。 2、初始时&#xff0c;she…

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;可以让用户比平板扫描…

HTML head 头部中的各类标签

HTML <head> 头部 <head> 元素包含了所有的头部标签元素。在 <head>元素中你可以插入脚本&#xff08;scripts&#xff09;, 样式文件&#xff08;CSS&#xff09;&#xff0c;及各种meta信息。 可以添加在头部区域的元素标签为: <title>, <style&g…

CSS变量(自定义属性)实践指南

本文翻译自&#xff1a;https://www.sitepoint.com/practical-guide-css-variables-custom-properties/ 转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 Sass和Less这样的预处理器&#xff0c;让…

ffmpeg-win32-v3.2.4 下载_MVBOX下载|MVBOX 7.1.0.4官方版

还是要强调一句&#xff0c;现在市面上很多盗版或者免费的软件&#xff0c;都给一些黑客留下了暗门&#xff0c;所以大家还是支持正版比较好&#xff0c;不要贪图便宜使用盗版软件造成不好的后果。MVBOX播放器功能介绍1、在线卡拉OK2、虚拟摄像头3、画面调色板4、摄像头抠像5、…

饿了么商家电脑版_饿了么企业版荣膺“2020中国十大影响力人力资源品牌”大奖...

11月6日&#xff0c;由MeetHR GROUP主办的2020大中华地区HRVP高峰论坛在上海落幕。饿了么企业版凭借自身产品在人力资源管理与服务方面的创新实践&#xff0c;荣获“2020 中国十大影响力人力资源品牌(薪酬福利类)”殊荣。本次评选&#xff0c;据主办方介绍&#xff0c;旨在激励…

navicat连接linux远程数据库,使用Navicat forMySql远程连接Linux 系统上的数据库

使用Navicat for MySql远程连接Linux 系统上的数据库解决mysql"Access denied for userrootIP地址"问题1.问题说明&#xff1a;在MYSQL 中&#xff0c;用远程软件登陆服务器&#xff0c;有时出现&#xff1a;Access denied for user rootlocalhost出现这种问题&#…

HTTPS 通俗简介

为什么需要HTTPS 9个问题搞懂 https 来源 HTTP是明文传输的&#xff0c;也就意味着&#xff0c;介于发送端、接收端中间的任意节点都可以知道你们传输的内容是什么。这些节点可能是路由器、代理 等。 举个最常见的例子&#xff0c;用户登陆。用户输入账号&#xff0c;密码&am…

CSS Modules入门教程

为什么引入CSS Modules 或者可以这么说&#xff0c;CSS Modules为我们解决了什么痛点。针对以往我写网页样式的经验&#xff0c;具体来说可以归纳为以下几点&#xff1a; 全局样式冲突 过程是这样的&#xff1a;你现在有两个模块&#xff0c;分别为A、B,你可能会单独针对这两…

热电偶校验仪_热电偶校验方法_热电偶的使用方法及维修经验

一、遵照仪表接线图进行准确接线通电后&#xff0c;仪表先是显示仪表的热电偶分度号&#xff0c;接着显示仪表量程范围&#xff0c;再测仪表显示设定温度&#xff0c;数显仪表显示测量温度。若仪表数码管显示不是发热体的温度&#xff0c;而显示“OVER”、“0000”或“000”等状…