我的编程空间,编程开发者的网络收藏夹
学习永远不晚

html5如何实现放大镜功能

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

html5如何实现放大镜功能

今天小编给大家分享一下html5如何实现放大镜功能的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

html5实现放大镜功能的方法:1、创建一个HTML示例文件;2、使用html5 canvas标签初始化图像;3、获得canvas和image对象;4、通过“function drawAnchor() {...}”等方法将选中的区域放大,然后再绘制到原先的图片上,保证两块区域的中心点一致即可。

原理

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

初始化

<canvas id="canvas" width="500" height="500">
</canvas>

<img class="lazy" data-src="image.png" style="display: none" id="img">

获得 canvas 和 image 对象,这里使用 <img> 标签预加载图片

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 函数裁剪出一个圆形区域,然后在该区域中绘制放大后的图。一旦裁减了某个区域,以后所有的绘图都会被限制的这个区域里,这里我们使用 saverestore 方法清除裁剪区域的影响。save 保存当前画布的一次状态,包含 canvas 的上下文属性,例如 stylelineWidth 等,然后会将这个状态压入一个堆栈。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 用于获得页面中某个元素的左,上,右和下分别相对浏览器视窗的位置。

function windowToCanvas(x, y) {
   var bbox = canvas.getBoundingClientRect();
   return {x: x - bbox.left, y: y - bbox.top}
}

修改鼠标样式

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

#canvas {
   display: block;
   border: 1px solid red;
   margin: 0 auto;
   cursor: crosshair;
}

图表放大镜

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

使用图表放大镜的效果
html5如何实现放大镜功能

原理

类似于地图中的图例,放大镜使用较为精确的图例,如下图所示:
html5如何实现放大镜功能

在放大镜坐标系统中,原始的区域会变大,如下图所示
html5如何实现放大镜功能

绘制原始线段

首先创建一个线段对象

function Line(xStart, yStart, xEnd, yEnd, index, color) {
   // 起点x坐标
   this.xStart = xStart;
   // 起点y坐标
   this.yStart = yStart;
   // 终点x坐标
   this.xEnd = xEnd;
   // 终点y坐标
   this.yEnd = yEnd;
   // 用来标记是哪条线段
   this.index = index;
   // 线段颜色
   this.color = color;
}

初始化线段

// 原始线段
var chartLines = new Array();
// 处于放大镜中的原始线段
var glassLines;
// 放大后的线段
var scaleGlassLines;
// 位于放大镜中的线段数量
var glassLineSize;

function initLines() {

   var line;
   line = new Line(200.5, 400, 200.5, 200, 0, "#888");
   chartLines.push(line);
   line = new Line(201.5, 400, 201.5, 20, 1, "#888");
   chartLines.push(line);


   glassLineSize = chartLines.length;
   glassLines = new Array(glassLineSize);
   for (var i = 0; i < glassLineSize; i++) {
       line = new Line(0, 0, 0, 0, i);
       glassLines[i] = line;
   }

   scaleGlassLines = new Array(glassLineSize);
   for (var i = 0; i < glassLineSize; i++) {
       line = new Line(0, 0, 0, 0, i);
       scaleGlassLines[i] = line;
   }
}

绘制线段

function drawLines() {
   var line;
   context.lineWidth = 1;

   for (var i = 0; i < chartLines.length; i++) {
       line = chartLines[i];
       context.beginPath();
       context.strokeStyle = line.color;
       context.moveTo(line.xStart, line.yStart);
       context.lineTo(line.xEnd, line.yEnd);
       context.stroke();
   }
}

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

function calGlassRectangle(point) {
   originalRectangle.x = point.x - originalRadius;
   originalRectangle.y = point.y - originalRadius;
   originalRectangle.width = originalRadius * 2;
   originalRectangle.height = originalRadius * 2;

   scaleGlassRectangle.width = originalRectangle.width * scale;
   scaleGlassRectangle.height = originalRectangle.height * scale;
   scaleGlassRectangle.x = originalRectangle.x + originalRectangle.width / 2 - scaleGlassRectangle.width / 2;
   scaleGlassRectangle.y = originalRectangle.y + originalRectangle.height / 2 - scaleGlassRectangle.height / 2;

   // 将值装换为整数
   scaleGlassRectangle.width = parseInt(scaleGlassRectangle.width);
   scaleGlassRectangle.height = parseInt(scaleGlassRectangle.height);
   scaleGlassRectangle.x = parseInt(scaleGlassRectangle.x);
   scaleGlassRectangle.y = parseInt(scaleGlassRectangle.y);
}

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

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

function calScaleLines() {
   var xStart = originalRectangle.x;
   var xEnd = originalRectangle.x + originalRectangle.width;
   var yStart = originalRectangle.y;
   var yEnd = originalRectangle.y + originalRectangle.height;
   var line, gLine, sgLine;
   var glassLineIndex = 0;
   for (var i = 0; i < chartLines.length; i++) {
       line = chartLines[i];

       // 判断线段是否在放大镜中
       if (line.xStart < xStart || line.xEnd > xEnd) {
           continue;
       }
       if (line.yEnd > yEnd || line.yStart < yStart) {
           continue;
       }

       gLine = glassLines[glassLineIndex];
       sgLine = scaleGlassLines[glassLineIndex];
       if (line.yEnd > yEnd) {
           gLine.yEnd = yEnd;
       }
       if (line.yStart < yStart) {
           gLine.yStart = yStart;
       }

       gLine.xStart = line.xStart - xStart;
       gLine.yStart = line.yStart - yStart;
       gLine.xEnd = line.xEnd - xStart;
       gLine.yEnd = line.yEnd - yStart;

       sgLine.xStart = parseInt(gLine.xStart * scale);
       sgLine.yStart = parseInt(gLine.yStart * scale);
       sgLine.xEnd = parseInt(gLine.xEnd * scale);
       sgLine.yEnd = parseInt(gLine.yEnd * scale);
       sgLine.color = line.color;
       glassLineIndex++;
   }
   glassLineSize = glassLineIndex;
}

绘制放大镜中心点

绘制放大镜中心的瞄准器

function drawAnchor() {
   context.beginPath();
   context.lineWidth = 2;
   context.fillStyle = "#fff";
   context.strokeStyle = "#000";
   context.arc(parseInt(centerPoint.x), parseInt(centerPoint.y), 10, 0, Math.PI * 2, false);

   var radius = 15;
   context.moveTo(parseInt(centerPoint.x - radius), parseInt(centerPoint.y));
   context.lineTo(parseInt(centerPoint.x + radius), parseInt(centerPoint.y));
   context.moveTo(parseInt(centerPoint.x), parseInt(centerPoint.y - radius));
   context.lineTo(parseInt(centerPoint.x), parseInt(centerPoint.y + radius));
   //context.fill();
   context.stroke();
}

绘制放大镜

function drawMagnifyingGlass() {

   calScaleLines();

   context.save();
   context.beginPath();
   context.arc(centerPoint.x, centerPoint.y, originalRadius, 0, Math.PI * 2, false);
   context.clip();

   context.beginPath();
   context.fillStyle = "#fff";
   context.arc(centerPoint.x, centerPoint.y, originalRadius, 0, Math.PI * 2, false);
   context.fill();

   context.lineWidth = 4;
   for (var i = 0; i < glassLineSize; i++) {
       context.beginPath();
       context.strokeStyle = scaleGlassLines[i].color;
       context.moveTo(scaleGlassRectangle.x + scaleGlassLines[i].xStart, scaleGlassRectangle.y + scaleGlassLines[i].yStart);
       context.lineTo(scaleGlassRectangle.x + scaleGlassLines[i].xEnd, scaleGlassRectangle.y + scaleGlassLines[i].yEnd);
       context.stroke();
   }
   context.restore();

   context.beginPath();
   var gradient = context.createRadialGradient(
       parseInt(centerPoint.x), parseInt(centerPoint.y), originalRadius - 5,
       parseInt(centerPoint.x), parseInt(centerPoint.y), originalRadius);

   gradient.addColorStop(0.50, 'silver');
   gradient.addColorStop(0.90, 'silver');
   gradient.addColorStop(1, 'black');
   context.strokeStyle = gradient;
   context.lineWidth = 5;
   context.arc(parseInt(centerPoint.x), parseInt(centerPoint.y), originalRadius, 0, Math.PI * 2, false);
   context.stroke();

   drawAnchor();
}

添加事件

鼠标拖动

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

canvas.onmousedown = function (e) {
   var point = windowToCanvas(e.clientX, e.clientY);
   var x1, x2, y1, y2, dis;

   x1 = point.x;
   y1 = point.y;
   x2 = centerPoint.x;
   y2 = centerPoint.y;
   dis = Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2);
   if (dis < Math.pow(originalRadius, 2)) {
       lastPoint.x = point.x;
       lastPoint.y = point.y;
       moveGlass = true;
   }
}

canvas.onmousemove = function (e) {
   if (moveGlass) {
       var xDis, yDis;
       var point = windowToCanvas(e.clientX, e.clientY);
       xDis = point.x - lastPoint.x;
       yDis = point.y - lastPoint.y;
       centerPoint.x += xDis;
       centerPoint.y += yDis;
       lastPoint.x = point.x;
       lastPoint.y = point.y;
       draw();
   }
}

canvas.onmouseup = function (e) {
   moveGlass = false;
}

鼠标双击

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

canvas.ondblclick = function (e) {
   var xStart, xEnd, yStart, yEnd;
   var clickPoint = {};
   clickPoint.x = scaleGlassRectangle.x + scaleGlassRectangle.width / 2;
   clickPoint.y = scaleGlassRectangle.y + scaleGlassRectangle.height / 2;
   var index = -1;

   for (var i = 0; i < scaleGlassLines.length; i++) {
       var scaleLine = scaleGlassLines[i];

       xStart = scaleGlassRectangle.x + scaleLine.xStart - 3;
       xEnd = scaleGlassRectangle.x + scaleLine.xStart + 3;
       yStart = scaleGlassRectangle.y + scaleLine.yStart;
       yEnd = scaleGlassRectangle.y + scaleLine.yEnd;

       if (clickPoint.x > xStart && clickPoint.x < xEnd && clickPoint.y < yStart && clickPoint.y > yEnd) {
           scaleLine.color = "#f00";
           index = scaleLine.index;
           break;
       }
   }

   for (var i = 0; i < chartLines.length; i++) {
       var line = chartLines[i];
       if (line.index == index) {
           line.color = "#f00";
       } else {
           line.color = "#888";
       }
   }

   draw();
}

键盘事件

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

document.onkeyup = function (e) {
   if (e.key == 'w') {
       centerPoint.y = intAdd(centerPoint.y, -0.2);
   }
   if (e.key == 'a') {
       centerPoint.x = intAdd(centerPoint.x, -0.2);
   }
   if (e.key == 's') {
       centerPoint.y = intAdd(centerPoint.y, 0.2);
   }
   if (e.key == 'd') {
       centerPoint.x = intAdd(centerPoint.x, 0.2);
   }
   draw();
}

以上就是“html5如何实现放大镜功能”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

html5如何实现放大镜功能

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

html5如何实现放大镜功能

今天小编给大家分享一下html5如何实现放大镜功能的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。html5实现放大镜功能的方
2023-07-05

HTML5中如何实现拖放功能

这篇文章主要介绍了HTML5中如何实现拖放功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、什么是拖放拖放就是通过鼠标放在一个物体上,按住鼠标不放就可以把一个物体托动到另
2023-06-09

利用Android实现一个放大镜功能

今天就跟大家聊聊有关利用Android实现一个放大镜功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。源码分析public class ShaderView extends View
2023-05-31

JavaScript如何实现放大镜

这篇文章给大家分享的是有关JavaScript如何实现放大镜的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。实现原理借助宽高等比例放大的两张图片,结合js中鼠标偏移量、元素偏移量、元素自身宽高等属性完成;左侧遮罩移
2023-06-21

使用canvas怎么实现一个放大镜功能

使用canvas怎么实现一个放大镜功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 1. 什么是离屏技术?canvas 学习和滤镜实现 介绍过 drawImage 接口。除了
2023-06-09

Flutter如何支持放大镜的输入框功能

这篇文章将为大家详细讲解有关Flutter如何支持放大镜的输入框功能,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。功能需求最近需求开发中遇到一个Flutter开发问题,为了优化用户输入体验。产品同学希望能
2023-06-29

js如何实现仿京东放大镜

这篇文章主要介绍“js如何实现仿京东放大镜”,在日常操作中,相信很多人在js如何实现仿京东放大镜问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”js如何实现仿京东放大镜”的疑惑有所帮助!接下来,请跟着小编一起来
2023-07-02

html5如何实现自动播放mov格式视频功能

这篇文章给大家分享的是有关html5如何实现自动播放mov格式视频功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、首先网站要支持.MOV格式文件就是说,网站要能识别.MOV格式文件。
2023-06-09

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录