Vue 页面放大缩小,且放大后可以拖拽

简单的放大组件,放大倍数现在为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>

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 在Vue中实现SVG的放大缩小功能可以使用vue-svg-pan-zoom插件。首先,需要在项目中引入该插件,并注册为组件。然后,在需要放大缩小的SVG元素上使用SvgPanZoom组件,并设置相应的属性。例如,可以设置zoomEnabled属性为true来启用放大缩小功能,设置controlIconsEnabled属性为true来显示控制图标。同时,可以使用fit属性来控制SVG是否自适应容器大小,使用center属性来控制SVG是否居中显示。\[3\] 在JavaScript中,可以使用d3.zoom()方法来实现SVG的放大缩小功能。首先,需要选中SVG元素,然后调用d3.zoom()方法,并设置scaleExtent属性来限制缩放的范围。接着,使用on("zoom", zoom)方法来监听缩放事件,并在回调函数中设置元素的transform属性来实现缩放效果。\[2\] 综上所述,可以通过引入vue-svg-pan-zoom插件和使用d3.zoom()方法来实现Vue中的SVG放大缩小功能。 #### 引用[.reference_title] - *1* *2* [vue使用svg文件补充-svg放大缩小(使用d3.js)](https://blog.csdn.net/weixin_42118466/article/details/105861325)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [在vue页面用能放大缩小svg](https://blog.csdn.net/orangapple/article/details/107515081)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值