image-view.vue 2.2 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
<template>
  <v-uni-movable-area
    class="image-view-area"
    @touchstart.native="onTouchStart"
    @touchmove.native="checkDirection"
    @touchend.native="onTouchEnd"
  >
    <v-uni-movable-view
      class="image-view-view"
      :direction="direction"
      inertia
      scale
      scale-min="1"
      scale-max="4"
      @scale="onScale"
    >
      <img
        :src="src"
        class="image-view-img"
        @load="onImgLoad"
      >
    </v-uni-movable-view>
  </v-uni-movable-area>
</template>

<script>
export default {
  name: 'ImageView',
  props: {
    src: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      direction: 'none'
    }
  },
  created () {
    this.scale = 1
    this.imgWidth = 0
    this.imgHeight = 0
    this.width = 0
    this.height = 0
  },
  methods: {
    onScale ({ detail: { scale } }) {
      this.scale = scale
    },
    onImgLoad (event) {
      const target = event.target
      const rect = target.getBoundingClientRect()
      this.imgWidth = rect.width
      this.imgHeight = rect.height
    },
    onTouchStart (event) {
      const $el = this.$el
      const rect = $el.getBoundingClientRect()
      this.width = rect.width
      this.height = rect.height
      this.checkDirection(event)
    },
    onTouchEnd (event) {
      const scale = this.scale
      const horizontal = scale * this.imgWidth > this.width
      const vertical = scale * this.imgHeight > this.height
      if (horizontal && vertical) {
        this.direction = 'all'
      } else if (horizontal) {
        this.direction = 'horizontal'
      } else if (vertical) {
        this.direction = 'vertical'
      } else {
        this.direction = 'none'
      }
      this.checkDirection(event)
    },
    checkDirection (event) {
      // 避免水平滑动和 swiper 冲突
      const direction = this.direction
      if (direction === 'all' || direction === 'horizontal') {
        event.stopPropagation()
      }
    }
  }
}
</script>

<style>
.image-view-area,
.image-view-view {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
.image-view-img {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  max-height: 100%;
  max-width: 100%;
}
</style>