vue3 预览图片放大缩小功能百分比输出+鼠标滚动事件放大缩小(2)

vue3 预览图片放大缩小功能+百分比输出(2)

  • 实现方案
  • 讲解

实现方案

上一篇博客是通过css的 transform:scale(0)控制的图片整体放大缩小 点击跳转上一篇
这一篇是通过动态获取img 路径进行图片的放大缩小;
整体需要注意的点是初始显示的缩略图,要让每张图片尽量不超过显示区域,由于写的是一个全屏效果
所以需要获取屏幕可视宽高来对图片进行大小控制;

目前滚动事件目前好像只在Google Chrome 浏览器生效,有懂浏览器兼容的麻烦指点一下。

讲解

当时写功能时时间挺赶的,所以下面js可能有些冗余代码

模板部分

<template>
  <div>
    <div class="Back">
      <img
        v-for="(item, index) in ImgList"
        :key="item.id"
        :src="item.img"
        alt=""
        ref="mask"
        @click="maskImg(item, index)"
        style="width: 100px; height: 100px"
      />
    div>
	
    <div class="preView" v-show="HideImg">
      
      <div class="closeBlock" @click="ClosePreviess">
        <img src="../assets/chose.png" alt="" />
      div>
      
      <div class="previewImage">
        
        <p class="show" v-show="display">{{ percentage + "%" }}p>
        <p class="hint" v-show="status == 1">不能再放大了!p>
        <p class="hint" v-show="status == 2">不能再缩小了!p>
        <div
          class="Exhibition"
          v-for="item in ImgList"
          :key="item.id"
          v-show="
            preViewID == item.id ? (item.switch = true) : (item.switch = false)
          "
        >
          
          <img
            :style="{ width: `${w}px`, height: `${h}px` }"
            :src="item.img"
            alt=""
          />
        div>
      div>
      
      <div class="BigNav">
        <img src="../assets/u120.png" @click="change(true)" alt="" />
        <img
          src="../assets/u110.png"
          @click="change(false)"
          alt=""
        />
        <img src="../assets/u100.png" alt="" />
        <img src="../assets/u190.png" alt="" />
        <img src="../assets/u170.png" alt="" />
        <img src="../assets/u160.png" alt="" />
        <img src="../assets/u150.png" alt="" />
        <img src="../assets/u200.png" alt="" />
        <img src="../assets/u180.png" alt="" />
        <img src="../assets/u130.png" alt="" />
        <img src="../assets/u140.png" alt="" />
      div>
      
      <div class="inpuileImg">
        <img
          v-for="(item, index) in ImgList"
          :key="item.id"
          :src="item.img"
          :class="preViewIndex == index ? 'inpuile' : 'mask_img'"
          @click="preViewImg(item, index)"
        />
      div>
    div>
  div>
template>
js部分 
<script>
import { ref, onMounted, onBeforeUnmount, watch, reactive } from "vue";
export default {
  name: "HomeView",
  components: {},
  setup() {
    const mask = ref(null);
    const ImgList = ref([
      {
        img: "https://www.helloimg.com/images/2022/06/22/ZnxrhX.png",
        id: "1",
        switch: false,
      },
      {
        img: "https://s1.ax1x.com/2022/04/11/LVnutK.jpg",
        id: "2",
        switch: false,
      },
      {
        img: "https://s1.ax1x.com/2022/04/11/LVpkVJ.png",
        id: "3",
        switch: false,
      },
      {
        img: "https://s1.ax1x.com/2022/04/11/LVnutK.jpg",
        id: "4",
        switch: false,
      },
      {
        img: "https://s1.ax1x.com/2022/06/23/jPCkOs.png",
        id: "5",
        switch: false,
      },
      {
        img: "https://s1.ax1x.com/2022/06/23/jPZRyT.png",
        id: "6",
        switch: false,
      },
    ]); //图片数组

    const PreviousImgList = ref([]);

    const w = ref(0); //宽
    const h = ref(0); //高
    const percentage = ref(100); //百分比
    const hint = ref("不能再缩小了"); //提示窗

    // 显示隐藏值
    const HideImg = ref(false);
    // 点击图片数组开始预览
    const maskImg = (item, i) => {
      getImgSize(item);
      HideImg.value = true;
      preViewID.value = item.id;
      preViewIndex.value = i;
    };
    // 判断点击状态值
    const preViewIndex = ref(0);
    // 判断点击显示隐藏状态值
    const preViewID = ref(1);
    // 点击底部小图片
    const preViewImg = (item, i) => {
      getImgSize(item);
      w.value = 0;
      h.value = 0;
      percentage.value = 0;
      preViewIndex.value = i;
      preViewID.value = item.id;
    };

    // 关闭按钮
    const ClosePreviess = () => {
      HideImg.value = false;
      w.value = 0;
      h.value = 0;
      percentage.value = 0;
    };

    watch(preViewIndex, (newV, oldV) => {
      console.log(newV, oldV);
      getImgSize(ImgList.value[preViewIndex.value]);
    });

    const fixed = reactive({
      width: 0,
      height: 0,
    });

    const domW = document.documentElement.clientHeight;
    const domH = document.documentElement.clientHeight;

    // 获取图片的宽高
    const getImgSize = (url) => {
      // 创建对象
      var img = new Image();
      // 改变图片的src
      img.src = url.img + "?" + Date.parse(new Date());

      // 加载完成获取宽高
      img.onload = function () {
        let value;
        if (img.width < img.height) {
          value = img.width / img.height;
          h.value = domH * 0.65;
          w.value = value * h.value;
          percentage.value = parseInt(((domH * 0.65) / img.height) * 100);
        } else {
          value = img.height / img.width;
          w.value = domW * 0.6;
          h.value = value * w.value;
          percentage.value = parseInt(((domW * 0.6) / img.width) * 100);
          if (domH * 0.65 > img.width) {
            value = img.width / img.height;
            h.value = domH * 0.65;
            w.value = value * h.value;
            percentage.value = parseInt(((domH * 0.65) / img.height) * 100);
          }
        }
        fixed.width = img.width;
        fixed.height = img.height;
        // 取消定时获取宽高
      };
    };

    // 鼠标滚动监听
    function handleScroll() {
      window.addEventListener("mousewheel", (e) => {
        var delta = 0;
        if (!e) e = window.event;
        if (e.wheelDelta) {
          //IE、chrome浏览器使用的是wheelDelta,并且值为“正负120”
          delta = e.wheelDelta / 120;
          if (window.opener) delta = -delta; //因为IE、chrome等向下滚动是负值,FF是正值,为了处理一致性,在此取反处理
        } else if (e.detail) {
          //FF浏览器使用的是detail,其值为“正负3”
          delta = -e.detail / 3;
        }
        // if (delta) handle(delta);
        // console.log(e);
        let direction = delta < 0 ? false : true; //true是向上
        change(direction);
      });
    }

    const status = ref(0);
    const display = ref(false);
    // 加减改变时
    let timeout;
    const change = (state) => {
      timeout && clearTimeout(timeout);
      display.value = true;
      console.log(w.value);
      if (state) {
        w.value = w.value + w.value * 0.01;
        h.value = h.value + h.value * 0.01;
      } else {
        if (percentage.value >= 1) {
          w.value = w.value - w.value * 0.01;
          h.value = h.value - h.value * 0.01;
        } else {
          status.value = 2;
        }
      }
      percentage.value = parseInt((w.value / fixed.width) * 100);

      timeout = setTimeout(() => {
        status.value = 0;
        display.value = false;
      }, 500);
    };

    onMounted(() => {
      handleScroll();
    });

    onBeforeUnmount(() => {
      window.removeEventListener("mousewheel", () => {}); // 离开当前组件别忘记移除事件监听
    });

    return {
      PreviousImgList,
      HideImg,
      ClosePreviess,
      preViewID,
      preViewIndex,
      preViewImg,
      maskImg,
      mask,
      ImgList,
      w, //动态写的宽
      h, //动态写的高
      percentage, //计算的百分比
      hint, //提示窗
      getImgSize, //获取图片的尺寸
      change, //加减号
      display, //百分比显示隐藏
      status, //
      fixed,
    };
  },
};
</script>
css部分,图片外层不需要宽高通过图片大小来把父级撑起来


你可能感兴趣的:(前端,javascript,开发语言,vue.js,前端框架)