整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

jQuery UI 实例-缩放(Resizable)

jQuery UI 实例-缩放(Resizable)

用鼠标改变元素的尺寸。

如需了解更多有关 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>

查看演示

最大/最小尺寸

使用 maxHeightmaxWidthminHeightminWidth 选项限制 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轻松实现放大镜效果

html

<div class="magnify">
 <div class="large"></div>
 <img class="small" src="0413pf3.jpg"/>
</div>

small是原始图片,large是放大镜片

css

.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;
} 

js

$(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:鼠标进入到小图框上的事件,此时显示遮罩和放大区域,并计算小图框的位置信息。
handOver() {
 // 计算小图框在浏览器中的位置
 this.imgObj=this.$el.getElementsByClassName('small-box')[0];
 this.imgRectNow=this.imgObj.getBoundingClientRect();
 this.showMagnifier=true;
 this.showMask=true;
}
 
复制代码
  • handMove:鼠标在小图上的移动事件,此事件发生在 handOver 之后,计算数据,移动遮罩以及背景图;
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:鼠标离开小图事件,此时无放大镜效果,隐藏遮罩和放大区域。
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 事件中的移动数据计算错误。

解决这个问题有两种方案:

  • 监听 scroll 事件,更新 this.imgRectNow;
  • 在 handMove 事件中更新 this.imgRectNow。

这里选择了第二种。

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。

总结

其实图片放大镜的实现思路没有那么复杂,核心点有两点:

  • 小图、大图的定位,遮罩和放大区域的创建方法
  • 放大镜的原理理解,并用代码实现 DOM 的移动等。

本文顺着这个思路,做了一个简单的实现,还有一些优化的空间,欢迎各位大佬在评论区讨论。虽然代码看起来不是非常优雅,但是足够明了,感兴趣的同学可以自己尝试一下。