Taro小程序Canvas缩放、平移、双击重置

  • Post author:
  • Post category:小程序


不管是小程序的原生Canvas组件还是Taro框架的Canvas组件。

他们在手势事件上还是没有太完善。

举例:

在双指缩放时,我们一定用的是小程序的Canvas手指触摸移动事件。

经过测试直接使用双指缩放,然后用单手拖动,再用双指缩放,再用单指拖动。 Canvas给您返回的touches数组会一直是2个。正常情况下单指返回1个,双指返回2个。

解决方案:

给Canvas创建一个控制器,意思就是制作一个跟Canvas一样大的View将Canvas移至其下层,View设置透明。所有事件绑定到View上,即可。

(仅限Android,IOS上View事件会被屏蔽)建议引入Web或做设备判断IOS直接使用Canvas Android用View做控制器

实例:

import React, { useEffect } from "react"
import Taro from "@tarojs/taro";
import { View, Canvas } from "@tarojs/components";

let ctx,
    scale = 1,
    tousX = 0,
    tousY = 0,
    touX = 0,
    touY = 0,
    touseX = 0,
    touseY = 0,
    clickBind = 0,
    start;
const Canvase = () => {
    const getDistance = (arr1, arr2) => {//计算缩放
        if (arr1 && arr2) {
            let x = arr2.pageX - arr1.pageX;
            let y = arr2.pageY - arr1.pageY;
            return (x * x) + (y * y);
        }
    }
    const touchstartCallback = (e) => {//触摸开始
        if (e.touches.length === 2) {//缩放
            start = e.touches;
            return
        } else {//平移
            touX = touseX + e.changedTouches[0].clientX;
            touY = touseY + e.changedTouches[0].clientY;
            return
        }
    }
    const touchmoveCallback = (e) => {//用户开始拖动
        if (e.changedTouches.length === 2) {//缩放
            const now = e.changedTouches;
            const now1 = getDistance(now[0], now[1]);
            const now2 = getDistance(start[0], start[1]);
            scale = now1 / now2;
            return
        } else {//平移
            tousX = touX - e.changedTouches[0].clientX;
            tousY = touY - e.changedTouches[0].clientY;
            return
        }
    }
    const touchEdn = (e) => {//记录平移位置
        touseX = touX - e.changedTouches[0].clientX;
        touseY = touY - e.changedTouches[0].clientY;
        return
    }
    const handleTab = (e) => {//双击重置
        clickBind = clickBind + 1;
        if (clickBind >= 2) {
            scale = 1;
            tousX = 0;
            tousY = 0;
            touX = 0;
            touY = 0;
            touseX = 0;
            touseY = 0;
        }
        setTimeout(() => {
            clickBind = 0;
        }, 500)
    }
    const draw = () => {
        ctx.translate(-(tousX), -(tousY));
        ctx.scale(scale, scale);
        ctx.rect(50, 50, 50, 50);
        ctx.setFillStyle('yellow');
        ctx.fill();
        ctx.draw();
    }
    useEffect(() => {
        ctx = Taro.createCanvasContext('canvas');
        setInterval(() => {
            draw()
        }, 100)
    }, [])
    return (
        <View style={{ height: '20rem', position: 'relative' }}>
            <Canvas style={{ height: '20rem' }} canvas-id='canvas' id="canvas"></Canvas>
            <View
                onClick={(e) => handleTab(e)}
                onTouchStart={(e) => touchstartCallback(e)}
                onTouchEnd={(e) => touchEdn(e)}
                onTouchMove={(e) => touchmoveCallback(e)}
                style={{
                    height: '20rem',
                    width: '100%',
                    background: 'transparent',
                    position: 'absolute',
                    top: 0,
                    border: '0.0625rem solid black'
                }}
            />
        </View>
    )
}
export default Canvase



版权声明:本文为qq_41659472原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。