简单的放大组件,放大倍数现在为hardCode, 可更改为根据两指之间距离重新计算倍数。 

放大后可移动整个页面用来聚焦某部分

缩小到一倍后不可继续缩小且页面也无法移动

<template>
  <div class="home-root">
    <div
      class="city"
      ref="chmap"
      style="transform: scale(1)"
      @dblclick="enlarge"
      id='imageWrapper'
      @touchstart="touchstart($event)"
      @touchmove="touchmove($event)"
      @touchend="touchend($event)"
      :style="{'backgroundImage': `url(${fireBackground})`}"
    >
     <img :src="cityImages.lightedIcon" alt="">
    </div>
  </div>
</template>

<script>
import { Toast } from 'vant';
import fireBackground from '@/assets/images/city/fire_background.png';
import cityImages from '@/assets/images/city';

export default {
  data() {
    return {
      fireBackground,
      cityImages,
      offsetWidth: document.documentElement.clientWidth,
      offsetHeight: document.documentElement.clientHeight,
      pageX: '',
      pageY: '',
      initX: '',
      initY: '',
      start: '',
      isTouch: false,
      currentScale: 1,
      canTouchMove: false,
    };
  },
  methods: {
    enlarge() {
      this.canTouchMove = true;
      this.$nextTick(() => {
        const self = this;
        if (this.currentScale === 1) {
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.2)';
          }, 50);
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.4)';
          }, 50);
          this.currentScale = 1.4;
        } else if (this.currentScale === 1.4) {
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.6)';
          }, 50);
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.8)';
          }, 50);
          this.currentScale = 1.8;
        } else if (this.currentScale === 1.8) {
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(2.0)';
          }, 50);
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(2.2)';
          }, 50);
          this.currentScale = 2.2;
        } else {
          Toast('不能再放大了');
          return;
        }
        this.$refs.chmap.style.transformOrigin = `${this.offsetWidth / 2} ${this.offsetHeight / 2}`;
      });
    },
    narrow() {
      this.canTouchMove = true;
      this.$nextTick(() => {
        const self = this;
        if (this.currentScale === 2.2) {
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(2.0)';
          }, 50);
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.8)';
          }, 50);
          this.currentScale = 1.8;
        } else if (this.currentScale === 1.8) {
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.6)';
          }, 50);
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.4)';
          }, 50);
          this.currentScale = 1.4;
        } else if (this.currentScale === 1.4) {
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.2)';
          }, 50);
          setTimeout(() => {
            self.$refs.chmap.style.transform = 'scale(1.0)';
          }, 50);
          this.currentScale = 1;
        } else {
          Toast('不能再缩小了');
          return;
        }
        this.$refs.chmap.style.transformOrigin = `${this.offsetWidth / 2} ${this.offsetHeight / 2}`;
        this.$refs.chmap.style.top = '0px';
        this.$refs.chmap.style.left = '0px';
      });
    },
    touchstart(e) {
      this.pageX = e.targetTouches[0].pageX; // 获取手指点的x坐标
      this.pageY = e.targetTouches[0].pageY; // 获取手指点的Y坐标
      this.initX = this.$refs.chmap.offsetLeft; // 获取div的left
      this.initY = this.$refs.chmap.offsetTop; // 获取div的top
      // 一根手指  移动事件
      if (e.touches.length > 0 && e.touches.length < 2) {
        this.isTouch = true; // 开启手指操作
      // 两根手指 缩放事件
      } else if (e.touches.length >= 2) {
        this.start = e.touches;
      }
    },
    // 手势操作中
    touchmove(e) {
      const self = this;
      const chmapScale = this.$refs.chmap.style.transform.slice(6, -1); // 获取scale值
      e.preventDefault(); // 取消事件的默认动作。
      // 移动操作
      if (e.touches.length === 1 && this.isTouch) {
        if (!this.canTouchMove) return;
        const touchMoveX = e.targetTouches[0].pageX; // 移动后的left值
        const touchMoveY = e.targetTouches[0].pageY; // 移动后的top值
        const top = parseInt(touchMoveY, 10) - parseInt(this.pageY, 10) + parseInt(this.initY, 10);
        const left = parseInt(touchMoveX, 10) - parseInt(this.pageX, 10) + parseInt(this.initX, 10);
        if (this.currentScale === 1) {
          this.$refs.chmap.style.left = '0px';
          this.$refs.chmap.style.top = '0px';
          return;
        }
        if (Math.abs(left) < (this.$refs.chmap.offsetWidth * (this.currentScale - 1)) / 2) {
          this.$refs.chmap.style.left = `${left}px`;
        }
        if (Math.abs(top) < (this.$refs.chmap.offsetHeight * (this.currentScale - 1)) / 2) {
          this.$refs.chmap.style.top = `${top}px`;
        }
      }
      // 放大操作 两个点以上,为了不无限放大造成负担,最大2.3倍
      if (e.touches.length >= 2 && self.isTouch && chmapScale < 2.3) {
        const now = e.touches; // 获取手指点的参数
        let scale = self.getDistance(now[0], now[1]) / self.getDistance(self.start[0], self.start[1]); // 调用算法算出偏移量
        // 最大值
        if (scale > 1.1) {
          scale = 2;
          this.isTouch = false;
          this.enlarge();
        }
        // 最小值
        if (scale < 1) {
          // 缩放后回归原位
          scale = 1;
          this.isTouch = false;
          this.narrow();
        }
      }
    },
    // 手势操作结束
    touchend(e) {
      if (this.isTouch) {
        this.isTouch = false;
      }
    },
    getDistance(p1, p2) {
      const x = p2.pageX - p1.pageX;
      const y = p2.pageY - p1.pageY;
      return Math.sqrt(x * x + y * y);
    },
  },
};
</script>

<style lang="scss" scoped>

.city {
  position: relative;
  min-width: 100vw;
  min-height: 100vh;
  color: white;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
.home {
  &-root {
    color: white;
    min-height: 100vh;
    position: relative;
    img {
      width: 80px;
      height: 80px;
      position: absolute;
      top: 200px;
      right: 150px;
    }
  }
}
</style>

Logo

前往低代码交流专区

更多推荐