失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > js+html2canvas实现网页放大镜效果:放大镜图片使用css样式background背景图 鼠标移

js+html2canvas实现网页放大镜效果:放大镜图片使用css样式background背景图 鼠标移

时间:2022-03-31 11:30:49

相关推荐

js+html2canvas实现网页放大镜效果:放大镜图片使用css样式background背景图 鼠标移

实现效果:

鼠标移动到需要放大的网页上时,鼠标静止不动500毫秒后,一个长方形的放大镜框显示,放大镜中显示当前区域2.2倍的效果,并且这时候鼠标移动放大的区域也跟着变化。放大镜限制:放大镜只能在特定的区域内使用,即放大镜的移动范围有边界。

实现思路:

使用html2canvas将需要使用放大镜效果的dom元素转换为图片,使用背景图的background-position属性实现鼠标移动展示对应的部分放大图片

需要注意的地方是,为了将鼠标单纯的经过、不触发放大镜效果这一情况区分开。我们可以使鼠标进入目标区域后,要求鼠标在静止不移动的状态下,等待500毫秒后才触发处理放大镜的事件

首先我们需要将dom网页转为图片才能继续后面的事情,这个问题使用html2canvas镜进行转换

var dom =document.querySelector('.imgBox')var width = dom.offsetWidth;var height = dom.offsetHeight;var canvasBox = document.createElement("canvas");canvasBox.width = width * scale;canvasBox.height = height * scale;const option = {canvas: canvasBox,useCORS: true, // 是否尝试使用CORS从服务器加载图像allowTaint: true, // Whether to allow cross-origin images to taint the canvasbackground: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的};html2canvas(dom, option).then(canvas => {// 得到转换成功的canvas画布,再转换成base64值}).catch(error => {console.error('html2canvas', error);});

在这个过程中可能会遇到转换不清晰,图片转换不全等问题,我们需要对html2canvas添加如下配置

canvasBox.style.width = width + "px";canvasBox.style.height = height + "px";canvasBox.getContext("2d").scale(scale, scale);canvasBox.getContext("2d").translate(-rect.left, -rect.top);const option = {scale: 2.2,canvas: canvasBox,width: width, // canvas宽度height: height, // canvas高度x: 0, // x坐标y: 0, // y坐标scrollY: 0, scrollX: 0,useCORS: true, // 是否尝试使用CORS从服务器加载图像allowTaint: true, // Whether to allow cross-origin images to taint the canvasasync: false, // 是否异步解析和呈现元素background: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的// dpi: 300, // 处理模糊问题;}

得到网页转换的图片,就可以写放大镜的效果,这个过程主要使用鼠标移入、移动、移出三个事件

在这个过程中,我们需要将鼠标单纯的滑过和真正触发放大镜效果这两种情况区分开,所以添加一个触发放大镜的要求:鼠标进入需要放大的区域后,在鼠标不再移动的情况下,等待500毫秒后才触发放大镜。

var overTimer,hasTrans //是否已经转换function mouseOver(e){var e = e || window.event; //实现兼容if(overTimer){clearTimeout(overTimer)overTimer=null}overTimer=setTimeout(() => {// 转换图片的代码}, 500);}

在这一过程中,我们使用500毫秒的一次性定时器,鼠标一但在500毫秒的等待时间内移动就清除之前的定时器,重新计时

function mouseMove(e){// 未转换图片并且鼠标移动时,重新计时if(!hasTrans){mouseOver(e)}}

放大镜效果出现后,鼠标移动时,对应放大的效果图也随位置变化,这一变换过程使用背景图的定位background-position来实现,同时鼠标移动过程中需要判断鼠标移动的边界和鼠标移出需要放大范围的隐藏效果

完整代码如下:

<style>.boxs{width: 500px;position: relative;}.slide_box {position: absolute;width: 170px;height: 90px;background: #fff;z-index: 100;display: none;pointer-events: none; /*设置该元素没有事件,即可以穿透放大镜元素 操作图片盒子上的事件*/}</style><div class="boxs"><div class="imgBox" onmouseover="mouseOver()" onmousemove="mouseMove()" onmouseout="mouseOut()"><img width="100%" class="eachImg" src="./4.png" draggable="false" /><!-- 放大镜元素 --><div class="slide_box"></div></div></div><script src="/ajax/libs/jquery/3.6.0/jquery.min.js"></script><script src="./lib/html2canvas.js"></script><script>var loading=falsevar biggerSrc// dom转换为图片(放大镜使用)function domToImage() {if(loading){return}loading=truesetTimeout(() => {$(".slide_box").hide()var dom =document.querySelector('.imgBox')var width = dom.offsetWidth; //dom宽var height = dom.offsetHeight; //dom高if (!dom) {console.log('节点不存在');return}var canvasBox = document.createElement("canvas");var scale = 2.2;var rect = dom.getBoundingClientRect();canvasBox.width = width * scale;canvasBox.height = height * scale;canvasBox.style.width = width + "px";canvasBox.style.height = height + "px";canvasBox.getContext("2d").scale(scale, scale);canvasBox.getContext("2d").translate(-rect.left, -rect.top);const option = {scale: scale,canvas: canvasBox,// 以下字段可选width: width, // canvas宽度height: height, // canvas高度x: 0, // x坐标y: 0, // y坐标scrollY: 0, scrollX: 0,// foreignObjectRendering: true, // 是否在浏览器支持的情况下使用ForeignObject渲染useCORS: true, // 是否尝试使用CORS从服务器加载图像allowTaint: true, // Whether to allow cross-origin images to taint the canvasasync: false, // 是否异步解析和呈现元素// 以下字段必填background: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的// dpi: 300, // 处理模糊问题};html2canvas(dom, option).then(canvas => {var url = canvas.toDataURL(); biggerSrc={docImgUrl: url,change:false}getPosition(movePostionE);loading=false}).catch(error => {loading=falseconsole.error('html2canvas', error);});}, 500)}// 鼠标是否在图片上var overImg// 鼠标在图片上等待500毫秒后,才触发放大镜效果;在此期间鼠标移动了,则清除上次定时器,重新计时var overTimer // 是否是初次进入图片,触发放大镜效果,,触发并生成放大图片后,以后就走鼠标移动切换对应放大区域的效果var beginOver=truevar movePostionE// (放大镜使用)function mouseOver(e){overImg=truevar e = e || window.event;if(overTimer){clearTimeout(overTimer)overTimer=null}overTimer=setTimeout(() => {beginOver=falsemovePostionE=e// 是否已经转换为图片if(biggerSrc){// dom已经转换为图片,但dom元素宽高有改变时,需要重新转换图片if(biggerSrc.change){domToImage()}}else{domToImage()}}, 500);}//(放大镜使用)function mouseMove(e){overImg=truevar e = e || window.event; // 判断事件源// 未转换图片时,鼠标移动了,则清除之前的定时器 重新计时if(beginOver&&!biggerSrc){mouseOver(e)}else{// 转换后,鼠标移动则改变放大镜中显示图片的位置movePostionE=egetPosition(e);}}// (放大镜使用)function mouseOut(e){overImg=false// 放大镜元素隐藏,清除之前的定时器$(".slide_box").hide()beginOver=trueif(overTimer){clearTimeout(overTimer)overTimer=null}}// 移动坐标(放大镜使用)function getPosition(e) {var e = e || window.event; //实现兼容var imgbox=document.querySelector('.imgBox')// 取遮罩块var glassBlock = document.querySelector('.slide_box')// 鼠标在图片区域内移动事件if(e.stopPropagation){e.stopPropagation();}else{e.cancelBubble=true;}// 取图片容器的大小及其相对于视口的位置,需要实时取,所以放在move事件里var target=e.target||e.srcElementif(!target){return}var clientRect = target.getBoundingClientRect();if(!$(target).hasClass("eachImg")){var dom=targetwhile (!$(dom).hasClass("imgBox")) {dom=dom.parentNode}clientRect = dom.getBoundingClientRect();}// 获取距鼠标距的上和左的坐标var leftX = e.clientX - clientRect.left;var leftY = e.clientY - clientRect.top;// 动态设置遮罩块的left和top位置 这里需要减去遮罩层的一半,因为鼠标位于遮罩块中心点var pointerLeft = leftX - $(glassBlock).width()/2;var pointerTop = leftY - $(glassBlock).height()/2;var domWidth=parseInt(imgbox.clientWidth)var domHeight=parseInt(imgbox.clientHeight)var backgroundImgWidth=domWidth*2var backgroundImgHeight=domHeight*2var backgroundleft=-leftX*2+$(glassBlock).width()/2var backgroundtop=-leftY*2+$(glassBlock).height()/2// 如果鼠标坐标移动超出原始图片区域边缘 则取消放大镜效果 因为这里存在快速移动鼠标到大图区域时,鼠标仍处在外层的图片区域内,并不会触发mouseout事件(虽然中间隔了小小的间距,但是快速移动仍能产生这个bug,如代码下面的图所示)if((pointerLeft+$(glassBlock).width()/2) > clientRect.width || pointerLeft < 0 - $(glassBlock).width()/2 || (pointerTop+$(glassBlock).height()/2) > clientRect.height || pointerTop < 0 - $(glassBlock).height()/2){$(".slide_box").hide()return;};// 遮罩块在最左边的时候,鼠标仍在图片区域内,可在遮罩块左边缘至中心线区域内移动,且这时遮罩块为距左0像素if(pointerLeft < 0){pointerLeft = 0;backgroundleft=-leftX // -leftX*2+leftX};// 右边限制if(pointerLeft > clientRect.width - $(glassBlock).width()){pointerLeft = clientRect.width - $(glassBlock).width();backgroundleft=$(glassBlock).width()-$(imgbox).width()-leftX //-leftX*2 + ($(glassBlock).width()-($(imgbox).width()-leftX))};// 顶部限制if(pointerTop < 0){pointerTop = 0;backgroundtop=-leftY // -leftY*2+leftY};// 底部限制if(pointerTop > clientRect.height - $(glassBlock).height()){pointerTop = clientRect.height - $(glassBlock).height();backgroundtop=$(glassBlock).height()-$(imgbox).height()-leftY //-leftY*2+($(glassBlock).height()-($(imgbox).height()-leftY))};// 设置遮罩块的位置// console.log(e,pointerLeft,pointerTop)glassBlock.style.left = pointerLeft+"px";glassBlock.style.top = pointerTop+"px";$(glassBlock).css({'background-image': `url(${biggerSrc.docImgUrl})`,'background-position': `${backgroundleft}px ${backgroundtop}px`,'background-size': `${backgroundImgWidth}px ${backgroundImgHeight}px`})if(overImg){$(glassBlock).show()}}</script>

浏览器效果如下:

js+html2canvas实现网页放大镜效果:放大镜图片使用css样式background背景图 鼠标移动使用样式background-position动态设置

如果觉得《js+html2canvas实现网页放大镜效果:放大镜图片使用css样式background背景图 鼠标移》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。