【小程序+Vue3+ts】手势放大/缩小图片的组件封装

记录下以前实现的双指滑动操控图片大小的功能。

        ps:图片缩放时有点抖动,感觉要再调调参数。有什么建议欢迎留言~

【效果图】

组件-HTML部分代码

<template>
  <div>
    <scroll-view
      scroll-x="true"
      scroll-y="true"
      style="max-width: 350px; max-height: 700px; white-space: nowrap"
    >
      <image
        :src="props.imageUrl"
        mode="widthFix"
        @load="imageLoad"
        :style="{
          width: imageWidth,
          height: imageHeight,
          display: 'inline-block',
        }"
        @touchmove="TouchMove"
        @touchstart="TouchStart"
        @touchend="TouchEnd"
      ></image>
    </scroll-view>
  </div>
</template>

组件-ts部分代码

<script lang="ts" setup>
import { ref } from "vue";

const props = defineProps({
  imageUrl: {
    type: String,
    default: "",
  },
});

// 1. 定义两个变量计算双指的两个点X、Y坐标之间的距离
const moveX = ref<number>(0);
const moveY = ref<number>(0);
// 2. 定义变量表示两个点之间的距离,用勾股定理计算
// 3. 老距离:手指刚放在屏幕上的距离;
const oldDistance = ref<number>(0);
// 4. 新距离:移动后的距离。
const newDistance = ref<number>(0);
// 5. 距离:新距离-老距离。是正数,说明图片要放大,是负数,说明图片要缩小
const distanceDiff = ref<number>(0);
const imageBaseHeight = ref<number>(0);
const imageBaseWidth = ref<number>(0);

const imageHeight = ref<string>("");
const imageWidth = ref<string>("");
const imageScale = ref<number>(1);
const imageNewScale = ref<number>(1);
const canMove = ref<boolean>(false);

const imageLoad = (imageInfo) => {
  // 在图片加载完成时获取图片的宽度和高度
  imageBaseHeight.value = imageInfo.detail.height;
  imageBaseWidth.value = imageInfo.detail.width;
};

const TouchStart = (touchInfo) => {
  // 触摸事件的对象中属性touches可以获取屏幕中触摸点的信息。是一个数组,双指触摸就是有两个值
  // clientX 和 clientY:距离屏幕可显示区域左上角距离
  if (touchInfo.touches.length === 2) {
    canMove.value = true;
    moveX.value = touchInfo.touches[1].clientX - touchInfo.touches[0].clientX;
    moveY.value = touchInfo.touches[1].clientY - touchInfo.touches[0].clientY;
    // 刚触摸时赋值老距离
    oldDistance.value = Math.sqrt(
      moveX.value * moveX.value + moveY.value * moveY.value
    );
  } else {
    // 单指触摸或双指以上不做处理
    return ;
  }
};
const TouchMove = (touchInfo) => {
  // 双指触摸,且没有结束触摸时执行下面的计算
  if (touchInfo.touches.length === 2 && canMove.value) {
    moveX.value = touchInfo.touches[1].clientX - touchInfo.touches[0].clientX;
    moveY.value = touchInfo.touches[1].clientY - touchInfo.touches[0].clientY;
    // 开始移动时赋值新的距离
    newDistance.value = Math.sqrt(
      moveX.value * moveX.value + moveY.value * moveY.value
    );
    distanceDiff.value = newDistance.value - oldDistance.value;
    imageNewScale.value = imageScale.value + 0.002 * distanceDiff.value;

    // 最大缩放倍数为2.5倍
    // if (imageNewScale.value >= 2.5) {
    //   imageNewScale.value = 2.5;
    // }
    // 不加最小缩放,因为获取到的图片基础宽高的单位(不知道是啥单位,试不出来)和计算用的单位(用的rpx)不统一,加上最小缩放会导致图片显示不全
    // if (imageNewScale.value <= 1) {
    //   imageNewScale.value = 1;
    // }
    imageHeight.value =
      String(imageBaseHeight.value * imageNewScale.value) + "rpx";
    imageWidth.value =
      String(imageBaseWidth.value * imageNewScale.value) + "rpx";
    // 每次基于上次的缩放比例进行缩放
    imageScale.value = imageNewScale.value;
    oldDistance.value = Math.sqrt(
      moveX.value * moveX.value + moveY.value * moveY.value
    );
  } else {
    // 单指触摸或双指以上或结束触摸则不做处理
    return ;
  }
};

const TouchEnd = () => {
  canMove.value = false;
};
</script>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值