javascript實現放大鏡外掛【含進階】
放大鏡在網頁中運用廣泛,在淘寶京東上面的商品圖中就用到了,還有在空間上面展示圖片的地方也有用到。現在這種jquery的外掛也有很多,但是也要明白其中原理就可以自己做各種各樣的放大鏡效果了。
現在就來好好分析一下放大鏡的原理和實現的過程:
簡單的實現
成果圖:
影像 1.png
放大鏡的原理
使用兩個圖片,一個是小圖——全部展現在頁面中的,一個是大圖——區域性展示放大的效果。所以由此可以看出突破點,就是網頁中一共有兩張圖,根據他們的移動的距離,可以實現放大鏡的效果。
網頁結構
下面就來寫以下網頁的結構
<!--css樣式--> <!--html結構--> <!--放大鏡的整體--><!--小圖的模組--><!--小圖--> ![](images/small.png) <!--遮擋層--><!--大圖的模組--><!--大圖--> ![](images/big.jpg)
如果上面的骨架搭好了,下面就來分析以下放大鏡的功能步驟:
1.滑鼠移動的時候遮罩層中的框也跟著一起移動
2.在遮罩層移動的時候右邊的大圖也一起移動
3.遮罩層的移動和大圖的移動是相反的,也是按照一定比例進行移動的
4.遮罩層是不能離開小圖的框的
實現步驟
下面上步驟:
第一步 獲取元素
因為這裡面的元素都有可能用到
//獲取最外面的div var box = document.getElementById("box"); //獲取顯示小圖的div var small = box.children[0]; //獲取小圖中的遮擋的div var mask = small.children[1]; //獲取顯示大圖的div var big = box.children[1]; //獲取大div中的大圖 var imgObj = big.children[0];
第二步 註冊滑鼠進入離開事件
在滑鼠進入的時候,顯示遮擋層和大圖的圖層
在滑鼠離開的時候,隱藏遮擋層和大圖的圖層
//滑鼠進入事件 box.onmouseover = function(){ mask.style.display = "block"; big.style.display = "block"; } //滑鼠離開事件 box.onmouseout = function(){ mask.style.display = "none"; big.style.display = "none"; }
第三步 註冊滑鼠移動事件(確定遮罩層的定位)
給滑鼠註冊移動事件,在小圖上移動的時候,遮罩層也跟著移動
要拿到可視區域的橫縱座標——clientX,clientY(不考慮相容性)
設定遮罩層的left和top值
那麼怎麼透過滑鼠的橫縱座標來設定遮罩層的left和top的值呢?
一張圖來說明白:
mask.png
上圖中的第三步,分析為什麼會出現這樣的問題
因為在滑鼠進入的時候,在滑鼠和小圖的框中加了一個遮罩層,這個遮罩層讓滑鼠和小圖的框進行了分離。所以當滑鼠進行移動的時候,移動到了小圖的框的外面,但是檢測不到滑鼠到底有沒有離開小圖的範圍,所以遮罩層就跟著滑鼠一起可以在可視區域中進行移動。
要想要進行範圍的限定,就類似於一輛車在兩堵牆之間的移動的最大距離一樣。最大的移動距離無非就是小圖框本身的寬度 - 遮罩層本身的寬度
下面上程式碼:
small.onmousemove = function (e) { var left = e.clientX - mask.offsetWidth / 2;//橫座標 var top = e.clientY - mask.offsetHeight / 2;//縱座標 //設定遮擋層的left和top var x = left - 100;//margin var y = top - 100;//margin //為遮擋層設定範圍 x=xsmall.offsetWidth-mask.offsetWidth?small.offsetWidth-mask.offsetWidth:x; //如果縱座標大於縱向最大移動距離就設定為縱向最大移動距離 y=y>small.offsetHeight-mask.offsetHeight?small.offsetHeight-mask.offsetHeight:y; //設定mask的定位 mask.style.left = x + "px"; mask.style.top = y + "px"; };
最後一步 大圖跟著滑鼠移動
如果圖片是有比例的,那麼移動的時候也成比例就可以
如果圖片是不成比例的,那麼就要有一個普遍的演算法
先來個原理圖:
max.png
上圖說的是寬度,其實高度可以以此類推。
由此可以得出:
**大圖的移動距離 = 遮擋層的移動距離 * 大圖的最大移動距離 / 遮擋層的最大移動距離 **
//大圖的最大的移動距離 var imgMaxMove=imgObj.offsetWidth-big.offsetWidth; //遮擋層的最大的移動距離 var maskMaxMove=small.offsetWidth-mask.offsetWidth; //大圖的橫向移動的距離 var imgMoveLeft=x*imgMaxMove/maskMaxMove; //大圖的縱向移動的距離 var imgMoveTop=y*imgMaxMove/maskMaxMove; //設定大圖的left和top---移動的是margin-left和margin-top imgObj.style.marginLeft=-imgMoveLeft+"px"; imgObj.style.marginTop=-imgMoveTop+"px";
整理一下全部的js程式碼
放大鏡進階
最近要做的這個放大鏡的功能需求是這樣的
擷取螢幕可視區域的圖片然後進行放大。
為了可以看到動態的效果,所以我在上面加了隨機的新增圖示的功能,這樣就可以看到實時的改變。
功能分析
設定按鈕,點選按鈕的時候顯示遮擋層和大圖框
設定新增圖示按鈕,點選在螢幕的隨機位置生成一個圖示
在文字框中輸入文字
擷取可視區域的螢幕並生成圖片
將可視區域的圖片進行放大放入到大圖框中
滑鼠移動的時候大圖框中的也同樣移動
效果圖
tb.png
截圖外掛 html2canvas
這個外掛是讓你整體截圖或者部分截圖的功能,截圖直接在瀏覽器上使用。這個外掛是基於dom操作,但是不是百分百準確的,因為它並不是生成一個圖片,而是基於頁面上的資訊截圖。(說白了就是截下來一部分的資訊然後直接繪製到另一個地方,並不是儲存成了圖片檔案)
注意事項
這個外掛有一定的限制
第一個就是文件不是很全,過於簡單
第二個是其工作原理不是真正生成一個截圖,而是遍歷所有的dom元素構建頁面,所以很多css屬性無法使用
第三個是要求影像同源且沒有代理,這個指令碼不渲染flashappletiframe等內容
可用引數
這些參考API和中文的簡書,寫的很清楚
demo
先引入js檔案
寫html結構
寫js程式碼
下面還是迴歸正題,開始寫放大鏡的結構:
放大鏡的html結構
hello world!!<!--遮罩層--> <!--相當於小圖--> <!--跟著滑鼠的層--><!--顯示的區域--> <!--移動的地方-->
使用jquery進行程式碼實現
第一步 獲取元素
//獲取id var btn = $('#btn'); var dv = $('#dv'); var box = $('#box'); var mask = $('#mask'); var look = $('#look'); var move = $('#move'); //定義圖片的最大移動距離和跟著滑鼠層的最大移動距離的變數 var imgMaxMove; var maskMaxMove;
第二步 註冊按鈕點選事件
點選按鈕的時候顯示遮罩層,同時也顯示出來隨著滑鼠移動的框框,顯示出來圖片顯示的位置。
顯示遮罩層的時候截圖
點選遮罩層的時候遮罩層消失
//給按鈕註冊點選事件 btn.on('click',function(){ //截圖功能 takeScreenshot(); //遮罩層顯示 dv.css('display','block'); }); //點選螢幕的時候就消除 dv.on('click',function(){ $(this).css('display','none'); })
第三步 截圖功能
function takeScreenshot() { //根據body進行截圖 html2canvas(bd, { allowTaint: true, //允許跨域 taintTest: false, //渲染圖片不用測試圖片 //渲染圖片 onrendered: function(canvas) { //將canvas標籤轉化為img標籤 canvas.id = 'cv'; var dataUrl = canvas.toDataURL(); var newImg = document.createElement("img"); newImg.src = dataUrl; //設定圖片的長和寬 newImg.width = 4 * bd.width(); newImg.height = 4* bd.height(); //把圖片的長寬賦值給外面的盒子 move.width(newImg.width); move.height(newImg.height); //把圖片加到盒子上 move.append(newImg); }, }); }
第四步 註冊滑鼠移動事件
不考慮相容的問題,使用clientX
確定不要讓跟著滑鼠的小塊出了螢幕,給它設定範圍
比例這個東西啊,因為之前截圖的時候,長度就進行了擴大,所以比例也不好掌握,後面自己慢慢的調。。。總會差不多的。(給自己留的bug)
//給滑鼠註冊移動事件dv.on('mousemove',function(e){ var left = e.clientX - mask.width() / 2;//橫座標 var top = e.clientY - mask.height() / 2;//縱座標 //設定遮擋層的left和top var x = left; var y = top; x=xbox.width()-mask.width()?box.width()-mask.width():x; y=y>box.height()-mask.height()?box.height()-mask.height():y; //確定跟著滑鼠動的小塊的定位值 mask.offset({"left":x,"top":y}); //大圖的最大的移動距離 imgMaxMove=newImg.width-look.width(); //遮擋層的最大的移動距離 maskMaxMove=box.width()-mask.width(); //大圖的橫向移動的距離 var imgMoveLeft=x*maskMaxMove/imgMaxMove*9; //大圖的縱向移動的距離 var imgMoveTop=y*maskMaxMove/imgMaxMove*9; // 給大圖設定移動位置 move.css("marginLeft",-imgMoveLeft); move.css("marginTop",-imgMoveTop); })
第五步 給螢幕上動態的新增元素
點選新增圖示的時候,在螢幕上隨機的新增一個圖示
可以在文字框中輸入文字資訊
$('#jb').on('click',function(){ var img = document.createElement('img'); img.src = 'images/jb.jpg'; img.width = 100; img.height = 100; var leftRandom = Math.random()*1366; //隨機生成橫座標 var topRandom = Math.random()*768; //隨機生成縱座標 img.style.position = 'absolute'; img.style.left = leftRandom + 'px'; img.style.top = topRandom + 'px'; $('#show').append(img); })
完整程式碼
css檔案glass.css
*{ margin:0; padding:0; }body{ background-image: url('../images/hua.jpg'); background-repeat: no-repeat; position: absolute; width: 100%; height: 100%; }#dv{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); display: none; }#btn{ position:absolute; top: 100px; left: 100px; width: 100px; height:50px; background-color:rgba(0,0,0,.9); border-radius: 8px; line-height: 50px; text-align: center; color: #fff; cursor: pointer; font-size: 16px; }#mask{ width: 200px; height:200px; position: absolute; top: 0; left: 0; background-color: rgba(255,150,0,.5); cursor: move; }#look{ width: 300px; height:300px; position: absolute; bottom: 30px; right: 30px; border: 1px solid #f40; cursor: move; overflow: hidden; }#box{ width: 100%; height:100%; }#jb{ position:absolute; left: 100px; top:200px; width: 100px; height: 50px; background-color: rgba(0,0,0,.9); border-radius: 8px; line-height: 50px; text-align: center; color: #fff; cursor: pointer; font-size: 16px; }#txt{ position: absolute; left: 100px; top: 300px; width: 100px; height: 50px; }
index.html
hello world!!顯示圖示放大鏡<!--遮罩層--> <!--相當於小圖--> <!--跟著滑鼠的區域--><!--移動的地方--><!--顯示的區域-->
js檔案 glass.js
(function($){ $.fn.glass = function(){ var mask = $('#mask'); var box = $('#box'); var look = $('#look'); var move = $('#move'); var btn = $('#btn'); var imgMaxMove; var maskMaxMove; var _this = $(this); //點選按鈕 btn.on('click',function(){ move.html(''); takeScreenshot(); _this.css('display','block'); }); //點選螢幕的時候就消除 _this.on('click',function(){ _this.css('display','none'); }) //獲取螢幕截圖 function takeScreenshot() { alert('1'); html2canvas($('#bd'), { allowTaint: true, taintTest: false, onrendered: function(canvas) { canvas.id = 'cv'; var dataUrl = canvas.toDataURL(); var newImg = document.createElement("img"); newImg.src = dataUrl; newImg.width = 4 * $('#bd').width(); newImg.height = 4* $('#bd').height(); move.width(newImg.width); move.height(newImg.height); move.append(newImg); _this.on('mousemove',function(e){ var left = e.clientX - mask.width() / 2;//橫座標 var top = e.clientY - mask.height() / 2;//縱座標 //console.log(mask.width()); //設定遮擋層的left和top var x = left;//margin var y = top;//margin x=xbox.width()-mask.width()?box.width()-mask.width():x; y=y>box.height()-mask.height()?box.height()-mask.height():y; mask.offset({"left":x,"top":y}); //大圖的最大的移動距離 imgMaxMove=newImg.width-look.width(); console.log(imgMaxMove); //遮擋層的最大的移動距離 maskMaxMove=box.width()-mask.width(); console.log(maskMaxMove); //大圖的橫向移動的距離 var imgMoveLeft=x*maskMaxMove/imgMaxMove*9; //大圖的縱向移動的距離 var imgMoveTop=y*maskMaxMove/imgMaxMove*9; move.css("marginLeft",-imgMoveLeft); move.css("marginTop",-imgMoveTop); }) }, }); } } })(jQuery);
補充
關於圖片的比例問題
也可以這樣做:
大圖的寬 / 小圖的寬 = 大圖的移動距離 / 小圖的移動距離
這樣就將id = move的標籤進行設定
css:
#move{ position:absolute; top:0; left: 0; }
js:
x = newImg.width / $('#bd').width() * x / 2; y = newImg.width / $('#bd').width() * y / 2; $('#move').css('left',-x); $('#move').css('top',-y);
還是那句話,比例自己調正。。。
作者:頑皮的雪狐七七
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/3486/viewspace-2810995/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 淘寶放大鏡實現
- JavaScript 圖片放大鏡效果JavaScript
- 直播app開發搭建,純javascript實現圖片放大鏡效果APPJavaScript
- canvas實現的圖片放大鏡效果Canvas
- JavaScript原生實現樓梯外掛JavaScript
- javascript實現的微信分享外掛JavaScript
- 利用 OmniGraffle 實現放大鏡標註效果
- 用JavaScript中jQuery編寫放大鏡效果JavaScriptjQuery
- FCPX外掛 SUGARfx Xflare Mac(真實鏡頭光暈效果外掛)Mac
- 圖片放大鏡效果實現過程詳解
- 五分鐘實現一個chrome外掛(含原始碼)Chrome原始碼
- 實現元素動畫的6款 JavaScript 外掛動畫JavaScript
- gulp進階-自定義gulp外掛
- 鏡頭光暈外掛Optical Flares ae鏡頭光暈耀斑外掛
- jQuery放大鏡jQuery
- vue-piczoom:基於vue2.x的電商圖片放大鏡外掛VueOOM
- javascript實現的放大效果程式碼JavaScript
- Canvas實現放大鏡效果完整案例分析(附程式碼)Canvas
- vim進階 | 使用外掛打造實用vim工作環境
- 【譯】JavaScript進階 從實現理解閉包JavaScript
- Vue 進階系列(二)之外掛原理及實現Vue
- jQuery 放大鏡效果jQuery
- Nik collection 4.3,濾鏡外掛
- 用最簡單的方法實現原生 JS 放大鏡特效JS特效
- Gradle外掛從入門到進階Gradle
- 淘寶放大鏡的簡單實現,原來道理很簡單
- PS濾鏡外掛:Nik Collection 5
- Mac顯示放大鏡Mac
- PHP外掛系統的實現(七):外掛案例PHP
- 視覺化學習:實現Canvas圖片區域性放大鏡視覺化Canvas
- PHP外掛系統的實現(五):觸發外掛PHP
- Flutter入門進階之旅(二十)Flutter外掛開發Flutter
- Android進階(九)Activity外掛化和VirtualApk分析AndroidAPK
- jQuery 放大鏡效果詳解jQuery
- JavaScript進階JavaScript
- QQ搶紅包外掛實現
- Sublime Text 3常用外掛安裝(含Emmet外掛指令介紹)
- javascript日曆外掛JavaScript