iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么在HTML5中使用Canvas实现一个放大镜效果
  • 348
分享到

怎么在HTML5中使用Canvas实现一个放大镜效果

2023-06-09 11:06:05 348人浏览 泡泡鱼
摘要

这期内容当中小编将会给大家带来有关怎么在HTML5中使用canvas实现一个放大镜效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。原理首先选择图片的一块区域,然后将这块区域放大,然后再绘制到原先的图片上

这期内容当中小编将会给大家带来有关怎么在HTML5中使用canvas实现一个放大镜效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

原理

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

怎么在HTML5中使用Canvas实现一个放大镜效果

undefined

初始化

<canvas id="canvas" width="500" height="500"></canvas><img 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中使用Canvas实现一个放大镜效果

使用图表放大镜的效果

怎么在HTML5中使用Canvas实现一个放大镜效果

在线演示    源码

原理

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

怎么在HTML5中使用Canvas实现一个放大镜效果

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

怎么在HTML5中使用Canvas实现一个放大镜效果

绘制原始线段

首先创建一个线段对象

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中使用Canvas实现一个放大镜效果了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网精选频道。

--结束END--

本文标题: 怎么在HTML5中使用Canvas实现一个放大镜效果

本文链接: https://www.lsjlt.com/news/255792.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • 怎么在HTML5中使用Canvas实现一个放大镜效果
    这期内容当中小编将会给大家带来有关怎么在HTML5中使用Canvas实现一个放大镜效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。原理首先选择图片的一块区域,然后将这块区域放大,然后再绘制到原先的图片上...
    99+
    2023-06-09
  • 使用canvas怎么实现一个放大镜功能
    使用canvas怎么实现一个放大镜功能?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。 1. 什么是离屏技术?canvas 学习和滤镜实现 介绍过 drawImage ...
    99+
    2023-06-09
  • 怎么在HTML5中实现一个图片悬停放大效果
    这篇文章将为大家详细讲解有关怎么在HTML5中实现一个图片悬停放大效果,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。HTML5 代码如下:<!DOCTYPE html>...
    99+
    2023-06-09
  • 怎么在HTML5中使用canvas实现一个瀑布流文字效果
    今天就跟大家聊聊有关怎么在HTML5中使用canvas实现一个瀑布流文字效果,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。代码如下:<!doctype html>...
    99+
    2023-06-09
  • HTML5中怎么实现一个拖放效果
    这篇文章给大家介绍HTML5中怎么实现一个拖放效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。先看html核心代码: 代码如下:<div> <p>把黄色小方块...
    99+
    2024-04-02
  • jquery中怎么实现放大镜效果
    这篇文章给大家介绍jquery中怎么实现放大镜效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。html部分:这里需要使用2长一定比例的图片,在页面中按比例设置2个div中来存放这2长...
    99+
    2024-04-02
  • html5中怎么利用canvas实现一个刮刮卡效果
    这篇文章给大家介绍html5中怎么利用canvas实现一个刮刮卡效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。代码如下:<!DOCTYPE html><...
    99+
    2024-04-02
  • 怎么用javascript实现放大镜效果
    今天小编给大家分享一下怎么用javascript实现放大镜效果的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。先来看一下效果:...
    99+
    2023-07-02
  • 怎么用vue实现放大镜效果
    这篇文章主要介绍“怎么用vue实现放大镜效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用vue实现放大镜效果”文章能帮助大家解决问题。组件使用less,请确保已安装loader本组件为放大镜...
    99+
    2023-07-04
  • JavaScript怎么实现放大镜效果
    这篇文章主要介绍了JavaScript怎么实现放大镜效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。这次实现的效果如下:这次的案例稍微有一点难度,在css和js上都需要多加...
    99+
    2023-06-25
  • 怎么使用HTML+CSS+JavaScript实现放大镜效果
    本文小编为大家详细介绍“怎么使用HTML+CSS+JavaScript实现放大镜效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么使用HTML+CSS+JavaScript实现放大镜效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢...
    99+
    2023-07-02
  • 用javascript实现放大镜效果
    我们经常在一些详情页上可以见到放大镜效果,今天我们也来做一个放大镜样式。 先来看一下效果: 图中的图片选的不是很好,有些糊了,各位可以重新选择图片进行做放大镜案例 这个案例可以分为...
    99+
    2024-04-02
  • 怎么用HTML5的canvas实现一个炫酷时钟效果
    小编给大家分享一下怎么用HTML5的canvas实现一个炫酷时钟效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!对于H5来说,canvas可以说是它最有特色的一...
    99+
    2023-06-09
  • 怎么在Android中利用ScrollView实现一个放大回弹效果
    这期内容当中小编将会给大家带来有关怎么在Android中利用ScrollView实现一个放大回弹效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。自定义ScrollView创建一个类,继承ScrollVi...
    99+
    2023-05-31
    scrollview android roi
  • 怎么在Android中利用ScrollView 实现一个伸缩放大效果
    这篇文章给大家介绍怎么在Android中利用ScrollView 实现一个伸缩放大效果,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。核心的控件就是下面的这段代码:package com.kokjuis.tra...
    99+
    2023-05-31
    android scrollview roi
  • 原生js实现一个放大镜效果超详细
    目录前言:一、放大镜效果二、实现步骤1. 首先分析放大镜结构2. 整体样式---css部分3. JS操作dom实现放大镜总结前言: 学习js之初,写过js放大镜,但是当时模模糊糊,似...
    99+
    2024-04-02
  • 使用原生JavaScript实现放大镜效果
    目录需求列表HTMLCSSJavascript分析需求列表 鼠标进入盒子里面控制遮罩层和放大盒子显示与隐藏 遮罩层跟随鼠标移动且遮罩层不超出盒子限定范围内 图片盒子/遮罩层/放大盒子...
    99+
    2023-03-01
    JavaScript实现放大镜效果 JavaScript放大镜效果 JavaScript放大镜
  • 怎么用HTML5 Canvas实现烟花绽放动画效果
    这篇文章主要介绍“怎么用HTML5 Canvas实现烟花绽放动画效果”,在日常操作中,相信很多人在怎么用HTML5 Canvas实现烟花绽放动画效果问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方...
    99+
    2024-04-02
  • css3中怎么实现图片放大镜特效效果
    这篇文章将为大家详细讲解有关css3中怎么实现图片放大镜特效效果,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。代码如下:<ul class="...
    99+
    2024-04-02
  • 怎么在HTML5中使用Canvas实现一个破碎重组视频特效
    本篇文章为大家展示了怎么在HTML5中使用Canvas实现一个破碎重组视频特效,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。HTML代码<video id="sourcev...
    99+
    2023-06-09
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作