vue 实现图片或者文件的【缩放、拖动】功能组件

1、安装插件 hammerjs

npm install -save hammerjs

2、添加zoom.js,写入一下代码

import Hammer from 'hammerjs'// 引用hammerjs

// 定义缩放方法,接收一个element参数:使用export暴露该方法
export function zoomElement (el) {
  var x = 0// x轴偏移
  var y = 0// y轴偏移
  var lastScale = 1// 上次缩放值
  var currentScale = 1// 当前缩放值
  var center// 双指中心点

  // 初始化hammer
  var hammer = new Hammer(el)
  // 缩放事件默认是关闭的,需要设置启用
  hammer.get('pinch').set({ enable: true })

  // 监听缩放事件
  hammer.on('pinchmove pinchstart pinchin pinchout', e => {
    // 缩放开始时获取上一次缩放值与双指中心点
    if (e.type === 'pinchstart') {
      lastScale = currentScale || 1
      center = e.center
      console.log('centerX:' + center.x)
      console.log('centerY:' + center.y)
    }
    // 当前缩放值 = 上一次缩放值 * 缩放比例
    currentScale = lastScale * e.scale

    // 如果缩放值小于1,重置为1
    if (currentScale < 1) {
      currentScale = 1
    }

    // 偏移量 = 双指中心点 - 当前缩放值 * 双指中心点 = 双指中心点 *(1-当前缩放值)
    x = center.x * (1 - currentScale)
    y = center.y * (1 - currentScale)

    // 设置transform
    el.style.transform = 'translateX(' + (x) + 'px)' + 'translateY(' + (y) + 'px)' + 'scale(' + (currentScale) + ')'
  })
  // 监听滑动事件
  hammer.on('panright panleft panup pandown', (e) => {
    // 滑动时:偏移量 = 滑动距离 + 当前偏移量
    var translateX = e.deltaX + x
    var translateY = e.deltaY + y
    // 如果偏移X值大于0:表示视图已经滑到最左侧,重置为0
    if (translateX > 0) {
      translateX = 0
    }
    // 如果偏移Y值大于0:表示视图已经滑到最顶部,重置为0
    if (translateY > 0) {
      translateY = 0
    }
    // 如果偏移X值小于(屏幕宽度-元素宽度):表示视图已经滑到最左侧,重置为0
    // 屏幕宽度 = el.clientWidth
    // 元素宽度 = el.getBoundingClientRect().width
    if (translateX < el.clientWidth - el.getBoundingClientRect().width) {
      translateX = el.clientWidth - el.getBoundingClientRect().width
    }
    // 如果偏移Y值大于(屏幕高度-元素高度):表示视图已经滑到最左侧,重置为0
    // 屏幕高度 = el.clientHeight
    // 元素高度 = el.getBoundingClientRect().height
    if (translateY < el.clientHeight - el.getBoundingClientRect().height) {
      translateY = el.clientHeight - el.getBoundingClientRect().height
    }
    // 设置transform
    el.style.transform = 'translateX(' + (translateX) + 'px)' + 'translateY(' + (translateY) + 'px)' + 'scale(' + (currentScale) + ')'
  })
  hammer.on('panend', (e) => {
    // 滑动结束:记录当前偏移量
    x = e.deltaX + x
    y = e.deltaY + y
    console.log('panendx:' + x)
    console.log('panendy:' + y)
  })
}

3、创建组件 Zoom.vue

<template>
  <div ref="test" class="test">
    <img :src="ImgSrc" alt="">
  </div>
</template>
<script>
import {zoomElement} from '@/utils/zoom.js'
export default {
  props: {
    ImgSrc: {
      type: String,
      default: ''
    }
  },
  mounted () {
    // 获取需要缩放的dom元素
    let zoomEl = this.$refs.test
    zoomElement(zoomEl)
  }
}
</script>
<style lang="scss" scoped>
.test{
    transform-origin: 0 0;
    img{
        width: 100%;
        height: 100%;
    }
}
</style>

4、页面调用

<template>
  <div>
    <div v-for="(da, daindex) of dataList" :key="daindex" class="target_box">
      <div class="target_scorll">
         <Zoom :ImgSrc="da.url"></Zoom>
      </div>
    </div>
  </div>
</template>
<script>
import Zoom from '@/components/Zoom/index'
export default {
  components: { Zoom },
  data () {
    return {
      dataList:[
        {url: require('@/assets/pic.png')},
        {url: require('@/assets/pic.png')},
        {url: require('@/assets/pic.png')}
      ]
    }
  }
</script>

坑:如使用此插件的话,图片超过设置的高度,用于(移动端)的滚动上下滑动功能会受影响,只能设置滚动条进行上下拖动,并且只能先缩放再拖动

<style lang="scss" scoped>
.target_top_box {
   overflow: hidden;
   .target_scorll::-webkit-scrollbar{
      width: 20px;
      height: 0;
   }
   .target_scorll::-webkit-scrollbar-thumb{
      background: #03ba82;
      border-radius: 10px;
   }
   .target_scorll{
      height: 600px;
      overflow-y: scroll;
      overflow-x: none;
   }
}
</style>

      希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值