vue3實現(xiàn)淘寶放大鏡效果的示例代碼
實現(xiàn)效果
實現(xiàn)思路
我們實現(xiàn)動圖的淘寶放大鏡的效果需要4步。
1.完成小圖盒子、遮罩、大圖盒子布局
2.實現(xiàn)鼠標移動到小圖盒子顯示遮罩和大圖盒子
3.實現(xiàn)鼠標移動遮罩在小圖盒子移動
4.實現(xiàn)遮罩的移動范圍不能超出小圖盒子,且移動時帶動大圖圖片移動
完成小圖盒子、遮罩、大圖盒子布局
我的布局小圖盒子包裹圖片、遮罩、大圖盒子。
小圖盒子為相對定位。遮罩、大圖盒子、大圖圖片都為絕對定位(大圖圖片沒定位不能移動)。mask要設置透明度。只要能實現(xiàn)效果即可。
實現(xiàn)鼠標移動到小圖盒子顯示遮罩和大圖盒子
小圖盒子綁定mouseout鼠標移到事件和mouseover鼠標移出事件。每次觸發(fā)事件的時候切換狀態(tài)。
實現(xiàn)鼠標移動遮罩在小圖盒子移動
小圖盒子綁定mousemove鼠標移動事件。鼠標在頁面的x坐標減去小圖盒子的offersetLeft就是鼠標在盒子的左邊這就是遮罩要移動的坐標,想要鼠標在mask的中間要除以2。同理y坐標也是。
實現(xiàn)遮罩的移動范圍不能超出小圖盒子,且移動時帶動大圖圖片移動
邊界值的判斷,如果小于等于0,則將mask的left等于0,x的有邊界值其實就是小盒子的寬度減去mask的寬度的值。同理y軸就是小盒子的高度減去mask的高度。
帶動大圖移動有個比例關系。大圖片移動距離 = mask的移動距離*大盒子最大移動距離 / mask的x最大移動距離,
完整代碼
<template> ? <div ? ? class="tb-booth" ? ? @mouseover="onMouseOver" ? ? @mouseout="onMouseOut" ? ? @mousemove="onMouseMove" ? ? ref="boothRef" ? > ? ? <img ? ? ? src="https://img.alicdn.com/imgextra/i3/1917047079/O1CN01lkG2pf22AEUi1owve_!!1917047079.png_430x430q90.jpg" ? ? /> ? ? <div class="mask" ref="mask" v-show="boxShow" /> ? ? <div class="big-img_box" ref="bigImgBox" v-show="boxShow"> ? ? ? <img ? ? ? ? class="big-img" ? ? ? ? ref="bigImg" ? ? ? ? src="https://img.alicdn.com/imgextra/i3/1917047079/O1CN01lkG2pf22AEUi1owve_!!1917047079.png" ? ? ? /> ? ? </div> ? </div> </template> <script> import { reactive, toRefs, ref } from "vue"; export default { ? setup() { ? ? const boothRef = ref(null); ? ? const mask = ref(null); ? ? const bigImg = ref(null); ? ? const bigImgBox = ref(null); ? ? const state = reactive({ ? ? ? boxShow: false ? ? }); ? ? const onMouseOver = () => { ? ? ? state.boxShow = true; ? ? }; ? ? const onMouseOut = () => { ? ? ? state.boxShow = false; ? ? }; ? ? const onMouseMove = (e) => { ? ? ? let x = e.pageX - boothRef.value.offsetLeft; ? ? ? let y = e.pageY - boothRef.value.offsetTop; ? ? ? let maskX = x - mask.value.offsetWidth / 2; ? ? ? let maskY = y - mask.value.offsetHeight / 2; ? ? ? // mask的x最大移動距離 ? ? ? let maskXMaxMove = boothRef.value.offsetWidth - mask.value.offsetWidth; ? ? ? let maskYMaxMove = boothRef.value.offsetHeight - mask.value.offsetHeight; ? ? ? let bigImgXMaxMove = ? ? ? ? bigImgBox.value.offsetWidth - bigImg.value.offsetWidth; ? ? ? let bigImgYMaxMove = ? ? ? ? bigImgBox.value.offsetHeight - bigImg.value.offsetHeight; ? ? ? if (maskX <= 0) { ? ? ? ? maskX = 0; ? ? ? } else if (maskX >= maskXMaxMove) { ? ? ? ? maskX = maskXMaxMove; ? ? ? } ? ? ? if (maskY <= 0) { ? ? ? ? maskY = 0; ? ? ? } else if (maskY >= maskYMaxMove) { ? ? ? ? maskY = maskYMaxMove; ? ? ? } ? ? ? mask.value.style.left = maskX + "px"; ? ? ? mask.value.style.top = maskY + "px"; ? ? ? // 大圖片移動距離 = mask的移動距離*大盒子最大移動距離 / mask的x最大移動距離 ? ? ? let bixImgXMove = (maskX * bigImgXMaxMove) / maskXMaxMove; ? ? ? let bixImgYMove = (maskY * bigImgYMaxMove) / maskYMaxMove; ? ? ? bigImg.value.style.left = bixImgXMove + "px"; ? ? ? bigImg.value.style.top = bixImgYMove + "px"; ? ? }; ? ? return { ? ? ? ...toRefs(state), ? ? ? boothRef, ? ? ? mask, ? ? ? bigImg, ? ? ? bigImgBox, ? ? ? onMouseOver, ? ? ? onMouseOut, ? ? ? onMouseMove, ? ? }; ? }, }; </script> <style scoped> .tb-booth { ? width: 430px; ? height: 430px; ? position: relative; ? border: 1px solid #cccccc; } .mask { ? position: absolute; ? top: 0; ? left: 0; ? width: 200px; ? height: 200px; ? background-color: rgb(61, 110, 206); ? opacity: 0.5; ? cursor: move; } .big-img_box { ? position: absolute; ? top: 0; ? left: 530px; ? width: 500px; ? height: 500px; ? background-color: #fff; ? border: 1px solid #cccccc; ? overflow: hidden; } .big-img { ? position: absolute; ? left: 0; ? top: 0; } </style>
總結
- mouseover、mouseout、mousemove事件的運用
- v-show顯示隱藏
- vue3獲取ref兩種方式其中一種通過setup創(chuàng)建ref響應式數(shù)據(jù),暴露出去賦予ref元素的值。第二種是getCurrentInstance方法。
- offsetWidth、offsetHeight、offsetLeft、offsetTop、pageX、pageY的概念
到此這篇關于vue3實現(xiàn)淘寶放大鏡效果的示例代碼的文章就介紹到這了,更多相關vue3 淘寶放大鏡內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
如何在Vue單頁面中進行業(yè)務數(shù)據(jù)的上報
為什么要在標題里加上一個業(yè)務數(shù)據(jù)的上報呢,因為在咱們前端項目中,可上報的數(shù)據(jù)維度太多,比如還有性能數(shù)據(jù)、頁面錯誤數(shù)據(jù)、console捕獲等。這里我們只講解業(yè)務數(shù)據(jù)的埋點。2021-05-05vue實現(xiàn)動態(tài)給data函數(shù)中的屬性賦值
這篇文章主要介紹了vue實現(xiàn)動態(tài)給data函數(shù)中的屬性賦值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09解決vue運行報錯Error:Cannot?find?module?'@vue/cli-plugin-b
解決了因為版本問題在創(chuàng)建項目時出現(xiàn)的各種報錯問題,這次在運行時出現(xiàn)的問題,下面這篇文章主要給大家介紹了關于解決vue運行報錯Error:Cannot?find?module?'@vue/cli-plugin-babel'的相關資料,需要的朋友可以參考下2023-04-04Ant?Design?Vue?走馬燈實現(xiàn)單頁多張圖片輪播效果
這篇文章主要介紹了Ant?Design?Vue?走馬燈實現(xiàn)單頁多張圖片輪播,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-07-07Vue實現(xiàn)用戶沒有登陸時,訪問后自動跳轉登錄頁面的實現(xiàn)思路
這篇文章主要介紹了Vue實現(xiàn)用戶沒有登陸時,訪問后自動跳轉登錄頁面,定義路由的時候配置屬性,這里使用needLogin標記訪問頁面是否需要登錄,本文通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-02-02vue2項目使用element-ui的el-tabs組件導致瀏覽器崩潰卡死問題
這篇文章主要介紹了vue2項目使用element-ui的el-tabs組件導致瀏覽器崩潰卡死問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07websocket+Vuex實現(xiàn)一個實時聊天軟件
這篇文章主要利用websocked 建立長連接,利用Vuex全局通信的特性,以及watch,computed函數(shù)監(jiān)聽消息變化,并驅動頁面變化實現(xiàn)實時聊天,感興趣的可以了解一下2021-08-08vue中v-if和v-for一起使用的弊端及解決辦法(同時使用 v-if 和 v-for不
當 v-if 和 v-for 同時存在于一個元素上的時候,v-if 會首先被執(zhí)行,這篇文章主要介紹了vue中v-if和v-for一起使用的弊端及解決辦法,需要的朋友可以參考下2023-07-07