Canvas实现放大镜效果

广告:宝塔Linux面板高效运维的服务器管理软件 点击【 https://www.bt.cn/p/uNLv1L 】立即购买

Canvas实现放大镜效果

  图片放大镜

  效果

  在线演示 源码

  原理

  首先选择图片的一块区域,然后将这块区域放大,然后再绘制到原先的图片上,保证两块区域的中心点一致, 如下图所示:

  初始化

<canvas id="canvas" width="500" height="500"></canvas><img src="image.png" style="display: none" id="img">
登录后复制

  获得 canvas 和 image 对象,这里使用 标签预加载图片, 关于图片预加载可以看这里

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");
登录后复制

  设置相关变量

// 图片被放大区域的中心点,也是放大镜的中心点var centerPoint = {};// 图片被放大区域的半径var originalRadius = 100;// 图片被放大区域var originalRectangle = {};// 放大倍数var scale = 2;// 放大后区域var scaleGlassRectangle
登录后复制

  画背景图片

function drawBackGround() {    context.drawImage(img, 0, 0);}
登录后复制

  计算图片被放大的区域的范围

  这里我们使用鼠标的位置作为被放大区域的中心点(放大镜随着鼠标移动而移动),因为 canvas 在画图片的时候,需要知道左上角的坐标以及区域的宽高,所以这里我们计算区域的范围

function calOriginalRectangle(point) {    originalRectangle.x = point.x - originalRadius;    originalRectangle.y = point.y - originalRadius;    originalRectangle.width = originalRadius * 2;    originalRectangle.height = originalRadius * 2;}
登录后复制

  绘制放大镜区域

  裁剪区域

  放大镜一般是圆形的,这里我们使用 clip 函数裁剪出一个圆形区域,然后在该区域中绘制放大后的图。一旦裁减了某个区域,以后所有的绘图都会被限制的这个区域里,这里我们使用 save 和 restore 方法清除裁剪区域的影响。save 保存当前画布的一次状态,包含 canvas 的上下文属性,例如 style,lineWidth 等,然后会将这个状态压入一个堆栈。restore 用来恢复上一次 save 的状态,从堆栈里弹出最顶层的状态。

context.save();context.beginPath();context.arc(centerPoint.x, centerPoint.y, originalRadius, 0, Math.PI * 2, false);context.clip();......context.restore();
登录后复制

  计算放大镜区域

  通过中心点、被放大区域的宽高以及放大倍数,获得区域的左上角坐标以及区域的宽高。

scaleGlassRectangle = {    x: centerPoint.x - originalRectangle.width * scale / 2,    y: centerPoint.y - originalRectangle.height * scale / 2,    width: originalRectangle.width * scale,    height: originalRectangle.height * scale}
登录后复制

  绘制图片

  在这里我们使用 context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); 方法,将 canvas 自身作为一副图片,然后取被放大区域的图像,将其绘制到放大镜区域里。

context.drawImage(canvas,    originalRectangle.x, originalRectangle.y,    originalRectangle.width, originalRectangle.height,    scaleGlassRectangle.x, scaleGlassRectangle.y,    scaleGlassRectangle.width, scaleGlassRectangle.height);
登录后复制

  绘制放大边缘

  createRadialGradient 用来绘制渐变图像

context.beginPath();var gradient = context.createRadialGradient(    centerPoint.x, centerPoint.y, originalRadius - 5,    centerPoint.x, centerPoint.y, originalRadius);gradient.addColorStop(0, 'rgba(0,0,0,0.2)');gradient.addColorStop(0.80, 'silver');gradient.addColorStop(0.90, 'silver');gradient.addColorStop(1.0, 'rgba(150,150,150,0.9)');context.strokeStyle = gradient;context.lineWidth = 5;context.arc(centerPoint.x, centerPoint.y, originalRadius, 0, Math.PI * 2, false);context.stroke();
登录后复制

  添加鼠标事件

  为 canvas 添加鼠标移动事件

canvas.onmousemove = function (e) {    ......}
登录后复制

  转换坐标

  鼠标事件获得坐标一般为屏幕的或者 window 的坐标,我们需要将其装换为 canvas 的坐标。getBoundingClientRect 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");0
登录后复制

  修改鼠标样式

  我们可以通过 css 来修改鼠标样式

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");1
登录后复制

  图表放大镜

  我们可能基于 canvas 绘制一些图表或者图像,如果两个元素的坐标离得比较近,就会给元素的选择带来一些影响,例如我们画两条线,一个线的坐标是(200.5, 400) -> (200.5, 200),另一个线的坐标为 (201.5, 400) -> (201.5, 20),那么这两条线几乎就会重叠在一起,如下图所示:

  使用图表放大镜的效果

  在线演示 源码

  原理

  类似于地图中的图例,放大镜使用较为精确的图例,如下图所示:

  在放大镜坐标系统中,原始的区域会变大,如下图所示

  绘制原始线段

  首先创建一个线段对象

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");2
登录后复制

  初始化线段

 

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");3
登录后复制

  绘制线段

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");4
登录后复制

  计算原始区域和放大镜区域

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");5
登录后复制

  计算线段在新坐标系统的位置

  由原理图我们知道,放大镜中使用坐标系的图例要比原始坐标系更加精确,比如原始坐标系使用 1:100,那么放大镜坐标系使用 1:10,因此我们需要重新计算线段在放大镜坐标系中的位置。同时为了简便,我们将线段的原始坐标进行了转化,减去原始区域起始的x值和y值,即将原始区域左上角的点看做为(0,0)。

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");6
登录后复制

  绘制放大镜中心点

  绘制放大镜中心的瞄准器

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");7
登录后复制

  绘制放大镜

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");8
登录后复制

  添加事件

  鼠标拖动

  鼠标移动到放大镜上,然后按下鼠标左键,可以拖动放大镜,不按鼠标左键或者不在放大镜区域都不可以拖动放大镜。

  为了实现上面的效果,我们要实现3种事件 mousedown, mousemove, 'mouseup', 当鼠标按下时,检测是否在放大镜区域,如果在,设置放大镜可以移动。鼠标移动时更新放大镜中兴点的坐标。鼠标松开时,设置放大镜不可以被移动。

var canvas = document.getElementById("canvas");var context = canvas.getContext("2d");var img = document.getElementById("img");9
登录后复制

  鼠标双击

  当移动到对应的线段上时,鼠标双击可以选择该线段,将该线段的颜色变为红色。

// 图片被放大区域的中心点,也是放大镜的中心点var centerPoint = {};// 图片被放大区域的半径var originalRadius = 100;// 图片被放大区域var originalRectangle = {};// 放大倍数var scale = 2;// 放大后区域var scaleGlassRectangle0
登录后复制

  键盘事件

  因为线段离得比较近,所以使用鼠标移动很难精确的选中线段,这里使用键盘的w, a, s, d 来进行精确移动

 

// 图片被放大区域的中心点,也是放大镜的中心点var centerPoint = {};// 图片被放大区域的半径var originalRadius = 100;// 图片被放大区域var originalRectangle = {};// 放大倍数var scale = 2;// 放大后区域var scaleGlassRectangle1
登录后复制

以上就是Canvas实现放大镜效果的详细内容,更多请关注9543建站博客其它相关文章!

广告:SSL证书一年128.66元起,点击购买~~~

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。

作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:css怎样去掉li元素默认样式
下一篇:HTML字符实体

发表评论

关闭广告
关闭广告