利用canvas来实现放大镜效果很简单,而且效果相对于传统的js实现,更加流畅,体验效果更好。下面来具体实现一下(主要利用了canvas处理图片的相关方法):
1、整体的页面布局:
两个画布,一个存放原图,一个存放放大区域的展示效果
<div>
<canvas width="800" height="400" id="canvas1"></canvas>
<canvas width="200" height="100" id="canvas2"></canvas>
</div>
2 、实现放大镜效果的思路
首先通过预加载,加载一张图片并放在画布中;然后给外层的盒子一个监听事件,当鼠标在盒子中移动,触发事件,然后执行一个事件回调函数,在这个回调函数中,对画布2(canvas2) 的相对位置进行修改。移动完毕要清除canvas2区域然后重绘下一个canvas2显示区域。这里我们分为以下两种形式:
1 局部放大:
js部分:
// 获取canvas1
var canvas1 = document.querySelector("#canvas1");
//获取canvas2
var canvas2 = document.querySelector("#canvas2");
// 图像稍后再此会被渲染,由 CanvasRenderingContext2D 接口完成实际的绘制
var ctx1 = canvas1.getContext("2d");
var ctx2 = canvas2.getContext("2d");
//获取父容器
var div = document.querySelector("div");
// 加载图片
var img = new Image();
img.src = "./img/9-.png";
img.addEventListener("load", loadHandler);
function loadHandler(e) {
//鼠标在父容器移动监听事件
div.addEventListener("mousemove", mouseHandler)
// 将加载的图片放在画布canvas1中,因为监听事件时异步的不会影响图片的放入
ctx1.drawImage(img, 0, 0, 800, 800);
}
function mouseHandler(e) {
// 利用 e.clientX,e.clientY 改变canvas2的相对位置
console.log(e.clientX, e.clientY)
canvas2.style.left = e.clientX + "px";
canvas2.style.top = e.clientY + "px";
// 清除ctx2矩形区域
ctx2.clearRect(0, 0, 200, 100);
// 参数1将img加载到画布中,参数2和3,设置裁切的起始位置坐标,参数4和5设置裁切的宽高,参数6和7设置图片裁切后放置的位置,参数8和9设置图片放置后的缩放宽高
ctx2.drawImage(img, e.clientX * (img.width / 800), e.clientY * (img.height / 800),100,50, 0, 0, 300, 150);
}
css部分:
<style>
canvas
{
position: absolute;
left:0;
top:0;
}
div{
position: relative;
}
</style>
最终呈现的效果:鼠标移动跟随
2 购物车放大镜效果
整体的思路和上面一样,都是通过改变canvas2的相对位置,将图片裁切后放入画布中,展现出来。
这里只对事件回调函数部分稍作修改即可实现效果
// loaderHandler
function loadHandler(e) {
//鼠标在父容器移动监听事件
canvas1.addEventListener("mouseenter", mouseHandler)
// 将加载的图片放在画布canvas1中,因为监听事件时异步的不会影响图片的放入
ctx1.drawImage(img, 0, 0, 400, 400);
}
// mouseHandler回调函数
function mouseHandler(e) {
switch (e.type) {
case "mouseenter":
canvas1.addEventListener('mousemove',mouseHandler);
canvas1.addEventListener('mouseleave', mouseHandler);
break;
case "mousemove":
canvas2.style.display = 'block';
// 参数1将img加载到画布中,参数2和3,设置裁切的起始位置坐标,参数4和5设置裁切的宽高,参数6和7设置图片裁切后放置的位置,参数8和9设置图片放置后的缩放宽高
ctx2.drawImage(img, e.clientX, e.clientY, 400, 400, 0, 0, 400, 400);
break;
case "mouseleave":
canvas2.style.display = 'none';
canvas1.removeEventListener('mousemove',mouseHandler);
canvas1.removeEventListener('mouseleave',mouseHandler);
break;
}
}
整体感觉相对于js版本,更加流畅。它也能一定程度上解决一个问题: 当你鼠标滚动页面,图片展示区域和放大区域会相对上移或下移(同步的),而用js实现的会出现很奇怪的一个现象,你的鼠标位置和视口呈现的内容不匹配,由于使用的是e.clientX,e.clienY相对视口来定位的(你的鼠标位置变了)。使用canvas可以很好的规避这个问题。