vue3预览图片和pdf封装

需求:点击预览pdf和图片,模拟element预览图片效果

使用到了swiper版本7.2.0 和阿里图标库图标

swiper需要在main.js里引入


import 'swiper/swiper-bundle.min.css';
import "swiper/swiper-bundle.min.js";

html部分

<template>
  <div class="mask left" @mousewheel.prevent="rollImg">
    <div class="swiper mySwiper">
      <div class="swiper-wrapper">
        <div class="swiper-slide" v-for="(item, index) in props.srcList" :key="index">
          <embed v-if="item.endsWith('.pdf') == true" :src="item" type />
          <div class="img-box" v-else>
            <img :src="item" alt class="Img" :draggable="false" id="Img" @mousedown.stop="handleMove" />
            <div class="img-box-button">
              <div @click="handleRotate('负')">
                <svg class="icons" aria-hidden="true">
                  <use xlink:href="#lhgj-rotate-left" />
                </svg>
              </div>
              <div @click="handleScale(2)">
                <svg class="icons" aria-hidden="true">
                  <use xlink:href="#lhgj-fangda" />
                </svg>
              </div>
              <div @click="handleScale(1)">
                <svg class="icons" aria-hidden="true">
                  <use xlink:href="#lhgj-suoxiao" />
                </svg>
              </div>
              <div @click="handleRotate('正')">
                <svg class="icons" aria-hidden="true">
                  <use xlink:href="#lhgj-rotate-right" />
                </svg>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="swiper-button-next"></div>
      <div class="swiper-button-prev"></div>
    </div>
    <div class="delete" @click="previewClose">
      <svg class="icons" aria-hidden="true">
        <use xlink:href="#lhgj-chacha" />
      </svg>
    </div>
  </div>
</template>

js部分


<script setup>
import Swiper, { Navigation } from "swiper"
import { defineEmits, defineProps, onMounted, ref } from "vue"
Swiper.use([Navigation])
const emits = defineEmits(["previewClose"])
const props = defineProps({
  srcList: {
    type: Array,
    default: () => [],
  },
})
let deg = ref(0)
let activeIndex = ref(0)
let scaleValue = ref(1) // 放大倍数
let scaleNumber = ref(1) // 放大倍数变化的值
const previewClose = () => {
  emits("previewClose")
}
// 点击旋转
const handleRotate = (e) => {
  if (e == "负") {
    deg.value -= 90
  } else {
    deg.value += 90
  }
  var img = document.getElementsByClassName("Img")[activeIndex.value]
  img.style.transform =
    "translateX(-50%) scale(" +
    scaleValue.value +
    ") rotate(" +
    deg.value +
    "deg)"
}
// 点击放大缩小
const handleScale = (e) => {
  var img = document.getElementsByClassName("Img")[activeIndex.value]
  if (e == 2) {
    // 放大
    scaleValue.value = scaleNumber.value || e
    scaleValue.value += 0.2
    scaleNumber.value = scaleValue.value
    img.style.transform =
      "translateX(-50%) scale(" +
      scaleValue.value +
      ") rotate(" +
      deg.value +
      "deg)"
  } else if (e == 1) {
    // 缩小
    scaleValue.value = scaleNumber.value || e
    scaleValue.value -= 0.2
    scaleNumber.value = scaleValue.value
    img.style.transform =
      "translateX(-50%) scale(" +
      scaleValue.value +
      ") rotate(" +
      deg.value +
      "deg)"
  }
}

// 鼠标拖动图片
const handleMove = (e) => {
  var left = document.querySelector(".left")
  var img = document.getElementsByClassName("Img")[activeIndex.value]
  var x = e.pageX - img.offsetLeft
  var y = e.pageY - img.offsetTop
  // 添加鼠标移动事件
  left.addEventListener("mousemove", move)
  function move(e) {
    img.style.left = e.pageX - x + "px"
    img.style.top = e.pageY - y + "px"
  }
  // 添加鼠标抬起事件,鼠标抬起,将事件移除
  img.addEventListener("mouseup", function () {
    left.removeEventListener("mousemove", move)
  })
  // 鼠标离开父级元素,把事件移除
  left.addEventListener("mouseout", function () {
    left.removeEventListener("mousemove", move)
  })
}

// 鼠标滚动图片放大缩小
const rollImg = () => {
  var img = document.getElementsByClassName("Img")[activeIndex.value]
  // 判断滚轮方向
  if (event.wheelDelta > 0) scaleNumber.value += 0.2
  else scaleNumber.value -= 0.2
  // 修改图片scalc
  img.style.transform =
    "translateX(-50%) scale(" +
    scaleNumber.value +
    ") rotate(" +
    deg.value +
    "deg)"
  return false
}

// 初始化图片状态
const initPictureStatus = () => {
  deg.value = 0
  scaleValue.value = 1
  scaleNumber.value = 1
  var img = document.getElementsByClassName("Img")[activeIndex.value]
  img.style.transform =
    "translateX(-50%) scale(" +
    scaleValue.value +
    ") rotate(" +
    deg.value +
    "deg)"
}

onMounted(() => {
  var img = document.getElementsByClassName("Img")[0]
  new Swiper(".mySwiper", {
    navigation: {
      nextEl: ".swiper-button-next",
      prevEl: ".swiper-button-prev",
    },
    touchStartPreventDefault: false,
    noSwipingSelector: "img",
    on: {
      slideChange: function () {
        activeIndex.value = this.activeIndex
        initPictureStatus()
      },
    },
  })
})
</script>

css部分


<style scoped>
.swiper {
  width: 100%;
  height: 100%;
}
.mask {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  position: fixed;
  top: 0;
  left: 0;
  z-index: 99999;
}
.img-box {
  height: 100%;
  position: relative;
}
.img-box > img {
  max-width: 60%;
  max-height: 86%;
  /* margin: 0 auto; */
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 999999;
}
.img-box-button {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  width: 340px;
  height: 50px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 999999;
}
embed {
  width: 80%;
  height: 100%;
  margin-left: 50%;
  transform: translateX(-50%);
}
.delete {
  position: absolute;
  top: 20px;
  right: 20px;
  font-size: 24px;
  font-weight: bold;
  cursor: pointer;
  z-index: 999999;
}
.delete > .icons :hover {
  background: rgba(255, 255, 255, 0.8);
  border-radius: 50%;
}
.icons {
  fill: #fff;
  margin: 0 10px !important;
}
.swiper-button-next,
.swiper-button-prev {
  color: #fff !important;
}
</style>

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值