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

不管是小程序的原生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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿也会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值