教程所示图片使用的是 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离屏技术与放大镜实现

canvas离屏技术与放大镜实现相关推荐

  1. 【Web技术】1159- 浅析 Web 录屏技术方案与实现

    前言 随着互联网技术飞速发展,网页录屏技术已趋于成熟.例如可将录屏技术运用到在线考试中,实现远程监考.屏幕共享以及录屏等:而在我们开发人员研发过程中,对于部分偶发事件,异常监控系统仅仅只能告知程序出错 ...

  2. web前端录屏技术方案与实现详解

    前言 随着互联网技术飞速发展,网页录屏技术已趋于成熟.例如可将录屏技术运用到在线考试中,实现远程监考.屏幕共享以及录屏等:而在我们开发人员研发过程中,对于部分偶发事件,异常监控系统仅仅只能告知程序出错 ...

  3. canvas系列-图片处理(五)放大镜

    一.原理 当鼠标点击并移动在画布canvas中时,会显示放大后的图片一角.移除canvas,鼠标松开或是鼠标离开点击那块范围时,则不会显示. 这个原理是:把这个图片放在离屏canvas上,而可视画布c ...

  4. anydesk截屏技术

    anydesk针对不同的操作系统使用了不同的截屏技术 针对NT5系统使用DDraw截屏. 针对NT6系统优先使用DXGI截屏,如果不支持DXGI则使用DX截屏. 为什么这样做呢?首先DirectDra ...

  5. php屏幕共享功能,利用无线投屏技术同屏直播,精彩随时共享

    利用无线投屏技术同屏直播,精彩随时共享 传统的大班教学中,学生在教室中不同位置会受距离和观察角度的影响,加之实验现象不明显,会导致看不清或看不到有效的物理现象.利用传统的展示平台同步到投影屏上,可以克 ...

  6. 大屏技术演进-推模式

    一.问题 在我们上一篇文章<大屏技术演进-拉模式>最后思考部分,我们提出条件单一使用拉模式其实也可以,定时控制一下时间粒度问题,整个架构也简单,那如果我们条件增加了呢,用那个模式是不是又回 ...

  7. iOS Airplay Screen Mirroring 同屏技术详解

    投屏技术已经被大量用在身边的产品,比如电视投屏,投影仪,视频会议产品中. 在iOS平台外的其他平台中都已经有非常成熟的标准和实现.但在封闭的苹果iOS和Mac系统中,苹果使用私有的Airplay协议进 ...

  8. 热门搜索怎么实现_三个步骤教你学会,搜索引擎霸屏技术!

    做好SEO就要了解搜索引擎霸屏技术,它是在百度中搜索关键字来检索信息.整个画面的推荐都是你的内容.那么客户点击你的可能性就会增加!那么搜索引擎霸屏技术这么好,那要如何做到呢? 1.要想成为霸屏,第一步 ...

  9. 吐血分享:QQ群霸屏技术教程2017(活跃篇)

    热门词的群排名,在前期优化准备充分的情况下,活跃度不失为必杀技. 在<吐血分享:QQ群霸屏技术(初级篇)>中,我们提及到热门词的群排名,有了前面的基础,我们就可以进入深度优化,实现绝对的霸 ...

最新文章

  1. 理解WebKit和Chromium: Chromium for Android
  2. centos 6.4 FTP安装和配置
  3. 启用属性,索引和存储的用途是什么?
  4. [设计模式-行为型]备忘录模式(Memento)
  5. 投资公司的钱是自己的吗?
  6. Error:Module production: java.lang.NoClassDefFoundError: com/android/resources/ResourceFolderType
  7. python菜鸟教程100例-菜鸟教程python
  8. 联想小新打印机M7268W固件升级步骤
  9. clearcase 操作指南
  10. 自适应滤波器 | 时域ALE算法
  11. Android系统定时开关机
  12. 【深入理解TcaplusDB技术】详细介绍TDR 表中Tcaplus的相关属性
  13. 一网打尽!炫酷枪火打击视频+图文+源码!哔哔哔......
  14. Java 日志框架简介
  15. 教育知识与能力(中学)
  16. 【AWS+Drupal应用案例】如何让一个千万级流量网站从一直挂机到起死回生?
  17. @MapKey的使用
  18. C语言_函数递归举例
  19. 【读书笔记】《曾国藩的正面与侧面(一)》
  20. 交易员都是用什么方法盈利的?

热门文章

  1. js input 自动换行_深入Slate.js - 拯救 ContentEditble
  2. oracle查询排序速度慢,Oracle-请问Oracle SQL排序查询慢如何解决
  3. Delphi下实现全屏快速找图找色 二、矩阵遍历
  4. 数据结构(六)查找---多路查找树(2-3-4树)
  5. java基础(第七章课后作业)03
  6. RethinkDB创始人教你如何打造一个伟大的互联网产品
  7. [转载]jquery cookie的用法
  8. WCF学习笔记之序列化
  9. Work Queue based multi-threading
  10. 【Android】自带Theme