欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue模仿實(shí)現(xiàn)京東商品大圖放大鏡效果

 更新時(shí)間:2022年12月27日 14:33:46   作者:Eric加油學(xué)!  
這篇文章主要為大家介紹了Vue實(shí)現(xiàn)京東網(wǎng)站商品放大鏡效果示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

效果如下:

首先,有一個(gè)放大鏡的DOM結(jié)構(gòu)

<template>
  <div class="spec-preview">
    <!-- 展示的原圖 -->
    <img :src="imgObj.imgUrl" />
    <!-- 綁定觸發(fā) -->
    <div class="event"></div>
    <!-- 放大圖 -->
    <div class="big">
      <img :src="imgObj.imgUrl" />
    </div>
    <!-- 遮罩層 -->
    <div class="mask"></div>
  </div>
</template>

這里img的src是通過父組件傳過來的imgList來展示的,可以換成自己的任意圖

交代一下:遮罩層和展示圖都是正方形的,而且遮罩層的寬高都是展示圖的一半

分別要綁定鼠標(biāo)移動(dòng)事件,和獲取兩個(gè)元素節(jié)點(diǎn),分別是遮罩層和放大圖

<template>
  <div class="spec-preview">
    <img :src="imgObj.imgUrl" />
    <div class="event" @mousemove="handler"></div>
    <div class="big">
      <img :src="imgObj.imgUrl" ref="big" />
    </div>
    <!-- 遮罩層 -->
    <div class="mask" ref="mask"></div>
  </div>
</template>

vue3中如何獲得ref綁定的節(jié)點(diǎn)元素呢?

首先,要知道在vue2中獲取ref節(jié)點(diǎn)元素是很簡單的,只需要this.$refs.mask即可。但是vue3中是沒有this.$refs的。

<script>
import { computed, getCurrentInstance, onMounted, ref } from "vue";
export default {
  name: "ZoomIndex",
  props: ["skuImageList"],
  setup(props) {
    let mask = ref(null);
    let big = ref(null);
    function handler(event) {
     let handlerMask = mask.value;
     let handlerBig = big.value;
    }
    return {
      handler,
      mask,
      big,
    };
  },
};
</script>

為了結(jié)構(gòu)清楚,我把其他不涉及這個(gè)案例的代碼都刪掉了。handlerMask和handlerBig就是我們想要獲取的節(jié)點(diǎn)。

獲取到節(jié)點(diǎn)后,就可以寫相應(yīng)的放大器實(shí)現(xiàn)代碼了

首先要獲取event的offserX也就是我們鼠標(biāo)距離左側(cè)邊框的距離 ,然后還需要減去遮罩層本身寬度的一半,高度同理。并且添加約束條件,讓這個(gè)遮罩層不能出展示區(qū)域。最后就只需要修改相應(yīng)元素的left和top屬性即可了(當(dāng)然,這里肯定是要用到絕對(duì)定位的,子絕父相)

function handler(event) {
      let handlerMask = mask.value;
      let left = event.offsetX - handlerMask.offsetWidth / 2;
      let top = event.offsetY - handlerMask.offsetHeight / 2;
      // 約束范圍
      if (left <= 0) left = 0;
      if (left >= handlerMask.offsetWidth) left = handlerMask.offsetWidth;
      if (top <= 0) top = 0;
      if (top >= handlerMask.offsetHeight) top = handlerMask.offsetHeight;
      // 修改元素的left|top屬性值
      handlerMask.style.left = left + "px";
      handlerMask.style.top = top + "px";
      // 修改放大圖
      let handlerBig = big.value;
      handlerBig.style.left = -2 * left + "px";
      handlerBig.style.top = -2 * top + "px";
    }

這里稍微有疑惑的可能就是放大圖為什么是-2去相乘。 首先根據(jù)前面的介紹,我們的展示圖和放大圖的大小是一致的,都是正方形。而遮罩層的寬高都是其一半。所以要把相應(yīng)的遮罩層的圖片放大,就是簡單的乘以2即可。那為什么是負(fù)數(shù)。這就是涉及到放大圖的移動(dòng)方向了。我們遮罩層向左移動(dòng),起始放大圖是相應(yīng)的向右移動(dòng)的。

.event {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 998;
  }
  .mask {
    width: 50%;
    height: 50%;
    background-color: rgba(0, 255, 0, 0.3);
    position: absolute;
    left: 0;
    top: 0;
    display: none;
  }
  .big {
    width: 100%;
    height: 100%;
    position: absolute;
    top: -1px;
    left: 100%;
    border: 1px solid #aaa;
    overflow: hidden;
    z-index: 998;
    display: none;
    background: white;
 }
 img {
      width: 200%;
      max-width: 200%;
      height: 200%;
      position: absolute;
      left: 0;
      top: 0;
    }

根據(jù)上面的展示(我把big里面的overflow:hidden去掉后的),可以看到,其實(shí)圖片的大小的是展示圖和放大鏡大小的2倍,超出部分是隱藏的。也就是向著相反的方向移動(dòng),使得我們遮罩層的區(qū)域放大后正好在放大鏡的展示區(qū)域中。

完整代碼如下:

<template>
  <div class="spec-preview">
    <img :src="imgObj.imgUrl" />
    <div class="event" @mousemove="handler"></div>
    <div class="big">
      <img :src="imgObj.imgUrl" ref="big" />
    </div>
    <!-- 遮罩層 -->
    <div class="mask" ref="mask"></div>
  </div>
</template>
<script>
import { computed, getCurrentInstance, onMounted, ref } from "vue";
export default {
  name: "ZoomIndex",
  props: ["skuImageList"],
  setup(props) {
    const internalInstance = getCurrentInstance(); //當(dāng)前組件實(shí)例
    const $bus = internalInstance.appContext.config.globalProperties.$bus;
    // console.log(props);
    let currentIndex = ref(0);
    let mask = ref(null);
    let big = ref(null);
    let imgObj = computed({
      get() {
        return props.skuImageList[currentIndex.value] || {};
      },
    });
    function handler(event) {
      let handlerMask = mask.value;
      let left = event.offsetX - handlerMask.offsetWidth / 2;
      let top = event.offsetY - handlerMask.offsetHeight / 2;
      // 約束范圍
      if (left <= 0) left = 0;
      if (left >= handlerMask.offsetWidth) left = handlerMask.offsetWidth;
      if (top <= 0) top = 0;
      if (top >= handlerMask.offsetHeight) top = handlerMask.offsetHeight;
      // 修改元素的left|top屬性值
      handlerMask.style.left = left + "px";
      handlerMask.style.top = top + "px";
      // 修改放大圖
      let handlerBig = big.value;
      handlerBig.style.left = -2 * left + "px";
      handlerBig.style.top = -2 * top + "px";
    }
    onMounted(() => {
      // 全局事件總線,獲取兄弟組件傳遞過來的索引值
      $bus.on("getIndex", (index) => {
        // 修改當(dāng)前響應(yīng)式數(shù)據(jù)
        currentIndex.value = index.value;
      });
    });
    return {
      currentIndex,
      imgObj,
      handler,
      mask,
      big,
    };
  },
};
</script>
<style lang="less">
.spec-preview {
  position: relative;
  width: 400px;
  height: 400px;
  border: 1px solid #ccc;
  img {
    width: 100%;
    height: 100%;
  }
  .event {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 998;
  }
  .mask {
    width: 50%;
    height: 50%;
    background-color: rgba(0, 255, 0, 0.3);
    position: absolute;
    left: 0;
    top: 0;
    display: none;
  }
  .big {
    width: 100%;
    height: 100%;
    position: absolute;
    top: -1px;
    left: 100%;
    border: 1px solid #aaa;
    // overflow: hidden;
    z-index: 998;
    display: none;
    background: white;
    img {
      width: 200%;
      max-width: 200%;
      height: 200%;
      position: absolute;
      left: 0;
      top: 0;
    }
  }
  .event:hover ~ .mask,
  .event:hover ~ .big {
    display: block;
  }
}
</style>

到此這篇關(guān)于Vue模仿實(shí)現(xiàn)京東商品大圖放大鏡效果的文章就介紹到這了,更多相關(guān)Vue放大鏡效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論