封装的H5图片双指缩放拖拽代码

import { reactive } from "vue";

type StoreType = {

  scale: number;

  originScale: number;

  pageX?: number;

  pageY?: number;

  pageX2?: number;

  pageY2?: number;

  moveable: boolean;

  lastTranslateX: number;

  lastTranslateY: number;

};

export default function (el: HTMLElement) {

  const store = reactive<StoreType>({

    scale: 1,

    originScale: 1,

    moveable: false,

    lastTranslateX: 0,

    lastTranslateY: 0

  });

  if (el) {

    el.addEventListener("touchstart", function (event) {

      const touches = event.touches;

      const [events, events2] = touches;

      event.preventDefault();

      // 第一个触摸点的坐标

      store.pageX = events.pageX;

      store.pageY = events.pageY;

      store.moveable = true;

      if (events2) {

        store.pageX2 = events2.pageX;

        store.pageY2 = events2.pageY;

      }

      store.originScale = store.scale || 1;

    });

  }

  el.addEventListener("touchmove", function (event) {

    if (!store.moveable) {

      return;

    }

    event.preventDefault();

    const touches = event.touches;

    const [events, events2] = touches;

    if (events2) {

      // 双指移动

      // 第2个指头坐标在touchmove时候获取

      if (!store.pageX2) {

        store.pageX2 = events2.pageX;

      }

      if (!store.pageY2) {

        store.pageY2 = events2.pageY;

      }

      // 获取坐标之间的举例

      const getDistance = function (start, stop) {

        return Math.hypot(stop.x - start.x, stop.y - start.y);

      };

      // 双指缩放比例计算

      const zoom =

        getDistance({ x: events.pageX, y: events.pageY }, { x: events2.pageX, y: events2.pageY }) /

        getDistance({ x: store.pageX, y: store.pageY }, { x: store.pageX2, y: store.pageY2 });

      // 应用在元素上的缩放比例

      let newScale = store.originScale * zoom;

      // 最大缩放比例限制

      if (newScale > 3) {

        newScale = 3;

      }

      if (newScale < 1) {

        newScale = 1;

        store.lastTranslateX = 0;

        store.lastTranslateY = 0;

      }

      // 记住使用的缩放值

      store.scale = newScale;

      // 图像应用缩放效果

      el.style.transformOrigin = `${(events.pageX + events2.pageX) / 2 - store.lastTranslateX}px  ${(events.pageY + events2.pageY) / 2 - store.lastTranslateY}px`;

      el.style.transform = `scale(${store.scale}) `;

    } else {

      if (store.scale === 1) {

        el.style.transform = "none";

      } else {

        // 单指移动

        el.style.transform = `scale(${store.scale}) translate(${store.lastTranslateX + (events.pageX - (store.pageX || 0)) / store.scale}px,${store.lastTranslateY + (events.pageY - (store.pageY || 0)) / store.scale}px)`;

      }

    }

  });

  el.addEventListener("touchend", function () {

    const styleStr = el.style.transform.split("translate(")?.[1]?.split(",");

    store.lastTranslateX = parseFloat(styleStr?.[0]) || 0;

    store.lastTranslateY = parseFloat(styleStr?.[1]) || 0;

    store.moveable = false;

    store.pageX2 = undefined;

    store.pageY2 = undefined;

  });

  el.addEventListener("touchcancel", function () {

    store.moveable = false;

    store.pageX2 = undefined;

    store.pageY2 = undefined;

  });

}

以上代码单独一个文件useTouches.ts。

使用:import { useTouches } from "./useTouches";

   const img = document.getElementById("day-img") as HTMLElement;

        useTouches(img);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值