用鼠標改變元素的尺寸。
如需了解更多有關 resizable 交互的細節,請查看 API 文檔 可調整尺寸小部件(Resizable Widget)。
默認功能
在任意的 DOM 元素上啟用 resizable 功能。通過鼠標拖拽右邊或底邊的邊框到所需的寬度或高度。
<!doctype html><html lang="en"><head> <meta charset="utf-8"> <title>jQuery UI 縮放(Resizable) - 默認功能</title> <link rel="stylesheet" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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" > <script src="http://code.jquery.com/jquery-1.9.1.js"></script> <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script> <link rel="stylesheet" > <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小時內與您取得聯系。