@greenfavo
2015-11-30T05:15:59.000000Z
字数 2352
阅读 1210
html5
在天猫淘宝购物时点开商品详情页把鼠标放到商品图片上移动时,就可以查看商品细节,这就是一个局部放大镜的功能。用canvas可以轻松实现这种功能。
之前在慕课网上看的canvas视频上介绍了这种局部放大镜的实现方法,采用了离屏canvas技术。其实就是先在DOM中创建2个canvas,准备一张大图,通过drawImage()方法,把大图缩放成小图放到其中一个canvas中,在另一个canvas里放这张大图,是实际尺寸。把大图隐藏。当鼠标在小图上移动时,就把大图上的像素复制到放大镜上。放大系数就是大图与小图宽度之比。放大的像素只显示在放大镜里,因此要用clip()方法裁剪。
这里用到的API在我上篇文章canvas API详解中有详细介绍。就不多说了。功能很简单,直接上代码吧。
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>canvas局部放大镜</title><style type="text/css">#canvas{margin: 30px auto;/*设置了block才会居中*/display: block;}#offcanvas{display: none;}</style></head><body><canvas id="canvas"></canvas><!-- 离屏canvas --><canvas id="offcanvas"></canvas><script>var canvas=document.getElementById('canvas');var context=canvas.getContext('2d');var offcanvas=document.getElementById('offcanvas');var offcontext=offcanvas.getContext('2d');var image=new Image();var scale;//放大系数canvas.width=500;canvas.height=300;image.src='images/4.jpg';image.onload=function(){offcanvas.width=image.width;offcanvas.height=image.height;scale=offcanvas.width/canvas.width;context.drawImage(image,0,0,canvas.width,canvas.height);//不是图片的实际大小,缩放了offcontext.drawImage(image,0,0);//是图片的实际大小}canvas.onmousemove=function(e){var point=window_to_canvas(e.clientX,e.clientY);//只有小图才调用放大镜if (canvas.width<offcanvas.width) {show_big_pic(point);canvas.style.cursor='move';};}canvas.onmouseout=function(){context.clearRect(0,0,canvas.width,canvas.height);context.drawImage(image,0,0,canvas.width,canvas.height);}function show_big_pic(point){//清空画布,重新绘制context.clearRect(0,0,canvas.width,canvas.height);context.drawImage(image,0,0,canvas.width,canvas.height);var imgLG_cx=point.x*scale;//大图中心位置var imgLG_cy=point.y*scale;var mr=100;//放大镜半径var sx=imgLG_cx-mr;//源图像起始坐标var sy=imgLG_cy-mr;var dx=point.x-mr;//目标图像起始坐标var dy=point.y-mr;context.save();context.lineWidth=5;context.strokeStyle="#ccc";context.beginPath();context.arc(point.x,point.y,mr,0,2*Math.PI);//绘制圆形放大镜context.stroke();context.clip();//剪辑,只在该区域显示context.drawImage(offcanvas,sx,sy,2*mr,2*mr,dx,dy,2*mr,2*mr);context.restore();}//鼠标在画布内的距离function window_to_canvas(x,y){var box=canvas.getBoundingClientRect();return{x:x-box.left,y:y-box.top};}</script></body></html>
当canvas里的图片比图片实际尺寸大时,如果不判断就直接调用放大镜,并不会显示很圆润的放大效果,而是会产生一种从源图像抽离出来的效果。所以应该判断下是否是小图,小图才放大。
每次鼠标移动都是重新将大图中适当位置里的像素复制到放大镜上,所以每次调用放大镜都应该清空放大镜里面的内容,不然内容会重叠。但放大镜每次移动的位置都不一样,不好判断,所以直接把整个画布清空就好了,这时应该重绘小图。