用鼠标改变元素的尺寸。
如需了解更多有关 resizable 交互的细节,请查看 API 文档 可调整尺寸小部件(Resizable Widget)。
默认功能
在任意的 DOM 元素上启用 resizable 功能。通过鼠标拖拽右边或底边的边框到所需的宽度或高度。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 默认功能</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { width: 150px; height: 150px; padding: 0.5em; } #resizable h3 { text-align: center; margin: 0; } </style> <script> $(function() { $( "#resizable" ).resizable(); }); </script></head><body> <div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">缩放(Resizable)</h3></div> </body></html>
查看演示
动画
使用 animate
选项(布尔值)使缩放行为动画化。当该选项设置为 true 时,拖拽轮廓到所需的位置,元素会在拖拽停止时以动画形式调整到该尺寸。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 动画</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { width: 150px; height: 150px; padding: 0.5em; } #resizable h3 { text-align: center; margin: 0; } .ui-resizable-helper { border: 1px dotted gray; } </style> <script> $(function() { $( "#resizable" ).resizable({ animate: true }); }); </script></head><body> <div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">动画</h3></div> </body></html>
查看演示
限制缩放区域
定义缩放区域的边界。使用 containment
选项来指定一个父级的 DOM 元素或一个 jQuery 选择器,比如 'document.'。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 限制缩放区域</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #container { width: 300px; height: 300px; } #container h3 { text-align: center; margin: 0; margin-bottom: 10px; } #resizable { background-position: top left; width: 150px; height: 150px; } #resizable, #container { padding: 0.5em; } </style> <script> $(function() { $( "#resizable" ).resizable({ containment: "#container" }); }); </script></head><body> <div id="container" class="ui-widget-content"> <h3 class="ui-widget-header">限制</h3> <div id="resizable" class="ui-state-active"> <h3 class="ui-widget-header">缩放(Resizable)</h3> </div></div> </body></html>
查看演示
延迟开始
通过 delay
选项设置延迟开始缩放的毫秒数。通过 distance
选项设置光标被按下且拖拽指定像素后才允许缩放。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 延迟开始</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable, #resizable2 { width: 150px; height: 150px; padding: 0.5em; } #resizable h3, #resizable2 h3 { text-align: center; margin: 0; } </style> <script> $(function() { $( "#resizable" ).resizable({ delay: 1000 }); $( "#resizable2" ).resizable({ distance: 40 }); }); </script></head><body> <h3 class="docs">时间延迟 (ms):</h3><div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">时间</h3></div> <h3 class="docs">距离延迟 (px):</h3><div id="resizable2" class="ui-widget-content"> <h3 class="ui-widget-header">距离</h3></div> </body></html>
查看演示
助手
通过设置 helper
选项为一个 CSS class,当缩放时只显示元素的轮廓。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 助手</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { width: 150px; height: 150px; padding: 0.5em; } #resizable h3 { text-align: center; margin: 0; } .ui-resizable-helper { border: 2px dotted #00F; } </style> <script> $(function() { $( "#resizable" ).resizable({ helper: "ui-resizable-helper" }); }); </script></head><body> <div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">助手</h3></div> </body></html>
查看演示
最大/最小尺寸
使用 maxHeight
、maxWidth
、minHeight
和 minWidth
选项限制 resizable 元素的最大或最小高度或宽度。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 最大/最小尺寸</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { width: 200px; height: 150px; padding: 5px; } #resizable h3 { text-align: center; margin: 0; } </style> <script> $(function() { $( "#resizable" ).resizable({ maxHeight: 250, maxWidth: 350, minHeight: 150, minWidth: 200 }); }); </script></head><body> <div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">放大/缩小</h3></div> </body></html>
查看演示
保持纵横比
保持现有的纵横比或设置一个新的纵横比来限制缩放比例。设置 aspectRatio
选项为 true,且可选地传递一个新的比率(比如,4/3)。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 保持纵横比</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { width: 160px; height: 90px; padding: 0.5em; } #resizable h3 { text-align: center; margin: 0; } </style> <script> $(function() { $( "#resizable" ).resizable({ aspectRatio: 16 / 9 }); }); </script></head><body> <div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">保持纵横比</h3></div> </body></html>
查看演示
对齐到网格
对齐 resizable 元素到网格。通过 grid
选项设置网格单元的尺寸(以像素为单位的高度和宽度)。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 对齐到网格</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { width: 150px; height: 150px; padding: 0.5em; } #resizable h3 { text-align: center; margin: 0; } </style> <script> $(function() { $( "#resizable" ).resizable({ grid: 50 }); }); </script></head><body> <div id="resizable" class="ui-widget-content"> <h3 class="ui-widget-header">网格</h3></div> </body></html>
同步缩放
通过点击并拖拽一个元素的边来同时调整多个元素的尺寸。给 alsoResize
选项传递一个共享的选择器。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 同步缩放</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> #resizable { background-position: top left; } #resizable, #also { width: 150px; height: 120px; padding: 0.5em; } #resizable h3, #also h3 { text-align: center; margin: 0; } #also { margin-top: 1em; } </style> <script> $(function() { $( "#resizable" ).resizable({ alsoResize: "#also" }); $( "#also" ).resizable(); }); </script></head><body> <div id="resizable" class="ui-widget-header"> <h3 class="ui-state-active">缩放</h3></div> <div id="also" class="ui-widget-content"> <h3 class="ui-widget-header">同步缩放</h3></div> </body></html>
查看演示
文本框
可缩放的文本框。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 缩放(Resizable) - 文本框</title> <link rel="stylesheet" href="//code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.9.1.js"></script> <script src="//code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" href="http://jqueryui.com/resources/demos/style.css"> <style> .ui-resizable-se { bottom: 17px; } </style> <script> $(function() { $( "#resizable" ).resizable({ handles: "se" }); }); </script></head><body> <textarea id="resizable" rows="5" cols="20"></textarea> </body></html>
视觉反馈
通过设置 ghost
选项为 true,可在缩放期间显示一个半透明的元素,而不是显示一个实际的元素。
每当打开淘宝,天猫等pc端时,看到心仪的物品时,点击图片时,便呈现出放大的效果。有没有去理解分析它的原理?是不是感觉非常的神奇?当真正地去接触,其实非常好理解。下面一起来学习!
Jquery和CSS3轻松实现放大镜效果
<div class="magnify"> <div class="large"></div> <img class="small" src="0413pf3.jpg"/> </div>
small是原始图片,large是放大镜片
.magnify{ position: relative; } .magnify img{ width: 100%; } .large { width: 175px; height: 175px; position: absolute; border-radius: 100%; box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25); background: url('0413pf3.jpg') no-repeat; display: none; }
$(document).ready(function(){ var native_width=0; var native_height=0; // 监听鼠标在magnify元素移动 $(".magnify").mousemove(function(e){ if(!native_width && !native_height){ // 获取原始图片的宽高 var image_object=new Image(); image_object.src=$(".small").attr("src"); native_width=image_object.width; native_height=image_object.height; }else{ var magnify_offset=$(this).offset(); var mx=e.pageX - magnify_offset.left; var my=e.pageY - magnify_offset.top; if(mx < $(this).width() && my < $(this).height() && mx > 0 && my > 0) { $(".large").fadeIn(100); } else { $(".large").fadeOut(100); } if($(".large").is(":visible")) { var rx=Math.round(mx/$(".small").width()*native_width - $(".large").width() / 2) * -1; var ry=Math.round(my/$(".small").height()*native_height - $(".large").height() / 2) * -1; var bgp=rx + "px " + ry + "px"; var px=mx - $(".large").width()/2; var py=my - $(".large").height()/2; $(".large").css({left: px, top: py, backgroundPosition: bgp}); } } }) })
是不是觉得很简单了,代码量不大,原理了就是鼠标移动时,获取鼠标在原始图片的位置,计算出放大镜片图片的`background-osition`值,实时去修改,这样就形成了放大镜的效果。
需要源码和演示地址的同学,点击下方“了解更多”!
更多资源敬请关注!
言
在做电商类应用时,难免会遇到商品主图实现放大镜效果的场景,现有的基于Vue的第三方包不多并且无法直接复用,今天,我来分享一种高稳定性的基于 Vue 的图片放大镜方法。
实现原理
放大镜的原理用一句话概括,就是根据小图上的鼠标位置去定位大图。
图1 原理图(以2倍放大为例)
相信原理图已经画的很明白了, 图中,左侧框是小图框,其蓝色区域为图片遮罩层(需放大区域),右侧框是整个大图目前所在区域,其蓝色区域是放大区域,设置超出隐藏,就实现了放大遮罩区域的效果。
显然,两块蓝色区域存在着某种对应关系,即遮罩的左上角位置(相对于小图,以下称 X 坐标)和放大区域(相对于大图)的左上角位置是成比例的,即放大倍数。计算出 X 坐标后,适当调整背景图的位置,使大图向反方向移动 scale 倍的 X 坐标即可。
X 坐标为(maskX,maskY),以计算 maskX 为例:
鼠标移动中会产生 e.clientX ,标识鼠标与浏览器左侧的距离,小图与浏览器左侧的距离是 left ,由于遮罩始终是一个以鼠标为中心的正方形,所以:
maskX=e.clientX - left - mask/2
同理,
maskY=e.clientY - top - mask/2
大图的对应样式设置为:
{ left: - maskX * scale + 'px'; top: - maskY * scale + 'px'; } 复制代码
效果演示
图2 长图展示
图3 宽图展示
图4 两倍放大效果图
图5 四倍放大效果图
核心代码
HTML
一般放大镜实现的是 1:1 等宽等高的正方形图片,这里兼容了其他比例的图片,设置图片为垂直居中对齐,包括小图,大图。如果小图不够充满整个小图框,余留下的空白部分也可以有放大效果,只不过放大结果依然是空白。 这样只需计算背景图的移动距离,不用过多的关注图片定位问题。
<template> <div class="magnifier"> <!-- 小图 --> <div class="small-box" @mouseover="handOver" @mousemove="handMove" @mouseout="handOut"> <img class="smallPic" :src="`${src}?x-oss-process=image/resize,l_836`" /> <div class="magnifier-zoom" v-show="showMask" :style="{ background: configs.maskColor, height: configs.maskWidth + 'px', width: configs.maskHeight + 'px', opacity: configs.maskOpacity, transform: transformMask }" ></div> </div> <!-- 大图, 注意误差 --> <div class="magnifier-layer" v-show="showMagnifier" :style="{ width: configs.width + 'px', height: configs.height + 'px', left: configs.width + 20 + 'px' }" > <div class="big-box" :style="{ width: bigWidth + 'px', height: bigHeight + 'px', left: moveLeft, top: moveTop }" > <div class="big-box-img" :style="{ width: bigWidth - 2 + 'px', height: bigHeight - 2 + 'px' }" > <img :src="bigSrc" :style="{ maxWidth: bigWidth - 2 + 'px', maxHeight: bigHeight -2 + 'px' }" /> </div> </div> </div> </div> </template> 复制代码
JS
这里主要有三个事件函数。
handOver() { // 计算小图框在浏览器中的位置 this.imgObj=this.$el.getElementsByClassName('small-box')[0]; this.imgRectNow=this.imgObj.getBoundingClientRect(); this.showMagnifier=true; this.showMask=true; } 复制代码
handMove(e) { // 计算初始的遮罩左上角的坐标 let objX=e.clientX - this.imgRectNow.left; let objY=e.clientY - this.imgRectNow.top; // 计算初始的遮罩左上角的坐标 let maskX=objX - this.configs.maskWidth / 2; let maskY=objY - this.configs.maskHeight / 2; // 判断是否超出界限,并纠正 maskY=maskY < 0 ? 0 : maskY; maskX=maskX < 0 ? 0 : maskX; if(maskY + this.configs.maskHeight >=this.imgRectNow.height) { maskY=this.imgRectNow.height - this.configs.maskHeight; } if(maskX + this.configs.maskWidth >=this.imgRectNow.width) { maskX=this.imgRectNow.width - this.configs.maskWidth; } // 遮罩移动 this.transformMask=`translate(${maskX}px, ${maskY}px)`; // 背景图移动 this.moveLeft=- maskX * this.configs.scale + "px"; this.moveTop=- maskY * this.configs.scale + "px"; } 复制代码
handOut() { this.showMagnifier=false; this.showMask=false; } 复制代码
以上三个事件基本上就实现了图片的放大镜功能。
但仔细看,你会发现每次移入小图框都会触发一次 handOver 事件,并且计算一次小图框 DOM (imgObj) 。
为了优化此问题,可以用 init 标识是否是页面加载后首次触发 handOver 事件,如果是初始化就计算imgObj 信息,否则不计算。
handOver() { if (!this.init) { this.init=true; // 原 handOver 事件 ... } this.showMagnifier=true; this.showMask=true; }, 复制代码
在测试的过程中,发现页面滚动后,会出现遮罩定位错误的情况,原来是因为初始化时,我们固定死了小图框的位置信息(存放在 this.imgRectNow ),导致 handMove 事件中的移动数据计算错误。
解决这个问题有两种方案:
这里选择了第二种。
handMove(e) { // 动态获取小图的位置(或者监听 scroll ) let imgRectNow=this.imgObj.getBoundingClientRect(); let objX=e.clientX - imgRectNow.left; let objY=e.clientY - imgRectNow.top; // 原 handMove 事件剩余内容 ... }, 复制代码
综合以上,我们已经实现了一个完美的图片放大镜功能。最终的 js 如下所示:
data() { return { imgObj: {}, moveLeft: 0, moveTop: 0, transformMask:`translate(0px, 0px)`, showMagnifier:false, showMask:false, init: false, }; }, computed: { bigWidth(){ return this.configs.scale * this.configs.width; }, bigHeight(){ return this.configs.scale * this.configs.height; } }, methods: { handMove(e) { // 动态获取小图的位置(或者监听 scroll ) let imgRectNow=this.imgObj.getBoundingClientRect(); let objX=e.clientX - imgRectNow.left; let objY=e.clientY - imgRectNow.top; // 计算初始的遮罩左上角的坐标 let maskX=objX - this.configs.maskWidth / 2; let maskY=objY - this.configs.maskHeight / 2; // 判断是否超出界限,并纠正 maskY=maskY < 0 ? 0 : maskY; maskX=maskX < 0 ? 0 : maskX; if(maskY + this.configs.maskHeight >=imgRectNow.height) { maskY=imgRectNow.height - this.configs.maskHeight; } if(maskX + this.configs.maskWidth >=imgRectNow.width) { maskX=imgRectNow.width - this.configs.maskWidth; } // 遮罩移动 this.transformMask=`translate(${maskX}px, ${maskY}px)`; // 背景图移动 this.moveLeft=- maskX * this.configs.scale + "px"; this.moveTop=- maskY * this.configs.scale + "px"; }, handOut() { this.showMagnifier=false; this.showMask=false; }, handOver() { if (!this.init) { this.init=true; this.imgObj=this.$el.getElementsByClassName('small-box')[0]; } this.showMagnifier=true; this.showMask=true; } } 复制代码
使用方法
本示例中的固定参数:小图框:420 * 420 。
程序可接受参数:
// 小图地址 src: { type: String, }, // 大图地址 bigSrc: { type: String, }, // 配置项 configs: { type: Object, default() { return { width:420,//放大区域 height:420,//放大区域 maskWidth:210,//遮罩 maskHeight:210,//遮罩 maskColor:'rgba(25,122,255,0.5)',//遮罩样式 maskOpacity:0.6, scale:2,//放大比例 }; } } 复制代码
文中图 2 是一张长图,小图的最大边不超过 836px(二倍图) ,大图为了视觉效果,分辨率尽量高点,程序会根据配置项自动设置对应的 height , width ,长图与宽图的效果对比可参考图3。
配置项可根据应用场景自行设置,本文示例的配置项是 2 倍放大,效果可参考图 4,四倍放大效果可参考图 5。
总结
其实图片放大镜的实现思路没有那么复杂,核心点有两点:
本文顺着这个思路,做了一个简单的实现,还有一些优化的空间,欢迎各位大佬在评论区讨论。虽然代码看起来不是非常优雅,但是足够明了,感兴趣的同学可以自己尝试一下。
*请认真填写需求信息,我们会在24小时内与您取得联系。