canvas放大镜
原理
首先选择图片的一块区域,而后将这块区域放大,而后再绘制到原先的图片上,保证两块区域的中心点一致;
- 初始化:
一个canvas, 预加载image(也可以通过html预加载), 得到 canvas 和 image 对象
设置相关变量
<canvas ref="myCanvas"></canvas>
<!-- <img src="image.png" style="display: none" id="img">-->
import img from '@/assets/a.webp';
// 相关变量
interface basicSetType {
// 图片被放大区域的中心点,也是放大镜的中心点
centerPoint: centerPointType;
// 图片被放大区域的半径
originalRadius: number;
// 图片被放大区域
originalRectangle: originalRectangleType;
// 放大倍数
scale: number;
// 放大后区域
scaleGlassRectangle: scaleGlassRectangleType;
}
- 画背景图
- 计算图片被放大的区域的范围
使用鼠标的位置做为被放大区域的中心点(放大镜随着鼠标移动而移动),由于 canvas 在画图片的时候,须要知道左上角的坐标以及区域的宽高,因此这里咱们计算区域的范围
// 计算图片被放大的区域的范围
const calOriginalRectangle = () => {
const radius = basicSet.originalRadius / 2;
const {
x, y} = basicSet.centerPoint;
basicSet.originalRectangle = {
x: x - radius,
y: y - radius,
width: basicSet.originalRadius,
height: basicSet.originalRadius
}
}
- 计算放大镜区域
经过中心点、被放大区域的宽高以及放大倍数,得到区域的左上角坐标以及区域的宽高。 - 绘制放大镜区域
裁剪区域
放大镜通常是圆形的,这里咱们使用 clip 函数裁剪出一个圆形区域,而后在该区域中绘制放大后的图。一旦裁减了某个区域,之后全部的绘图都会被限制的这个区域里,这里咱们使用 save 和 restore 方法清除裁剪区域的影响。save 保存当前画布的一次状态,包含 canvas 的上下文属性,例如 style,lineWidth 等,而后会将这个状态压入一个堆栈。restore 用来恢复上一次 save 的状态,从堆栈里弹出最顶层的状态。 - 绘制图片
在这里咱们使用 context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); 方法,将 canvas 自身做为一副图片,而后取被放大区域的图像,将其绘制到放大镜区域里。 - 绘制放大边缘
createRadialGradient 用来绘制渐变图像 - 绑定事件
在按下时判断鼠标位置是否在canvas画布中,在画布中再绑定鼠标移动事件去绘图。鼠标松开时清除事件并重辉背景。
注: 由于鼠标移动绘制放大区域,需要每一次绘制重画背景使背景图不发生变化。
// 绘制放大区域
const drawScaleRectangle = (myCanvas: Ref) => {
const ctx = myCanvas.value.getContext('2d');
// 每次画之前重画图片
ctx.drawImage(image, 0, 0, 400, 400)
ctx.save();
ctx.beginPath();
ctx.arc(basicSet.centerPoint.x, basicSet.centerPoint.y, basicSet.originalRadius, 0, Math.PI*2, false);
ctx.clip();
const oR = basicSet.originalRectangle;
const sR = basicSet.scaleGlassRectangle;
drawScaleGradient(ctx);
// 绘制放大图片
ctx.drawImage(myCanvas.value, oR.x, oR.y, oR.width, oR.height, sR.x, sR.