Open ickg5 opened 2 years ago
节流一下 touchmove 16.7毫秒一次 然后加一下tansition: transform 0.1s
节流一下 touchmove 16.7毫秒一次 然后加一下tansition: transform 0.1s
import {ITouchEvent, Text, View} from '@tarojs/components'
import * as _ from 'lodash'
import {useMemo, useState} from "react";
import './index.scss'
// eslint-disable-next-line import/no-commonjs
const lodashRoot = require("lodash/_root")
if (!lodashRoot.Date) {
lodashRoot.Date = Date
}
export default function Index() {
const [distance, setDistance] = useState(0)
const touchMove = useMemo(() => _.throttle((event: ITouchEvent) => {
const {clientY} = event.touches[0]
setDistance(clientY)
}, 16.7), [])
return (
<View
className='index'
onTouchMove={touchMove}
style={{
transition: 'transform 0.1s',
transform: distance >= 0 ? `translate3d(0,${distance}px, 0)` : "",
}}
>
<Text>Hello world!</Text>
</View>
)
}
我试了一下好像不行。
实测有效 @tgioer
import useThrottleFn from '@/hooks/lib/useThrottleFn';
import {ITouch, ITouchEvent, Text, View} from '@tarojs/components'
import {useCallback, useRef, useState} from "react";
export function TouchTest() {
const [translate,setTranslate] = useState<{translateX:any,translateY:any}>()
const startPoint = useRef<ITouch>()
const onTouchStart= useCallback((e:ITouchEvent)=>{
startPoint.current = e.touches[0]
e.stopPropagation()
},[])
const touchMove = useThrottleFn((e: ITouchEvent) => {
if(!startPoint.current){return }
const endPoint = e.touches[e.touches.length - 1]
const translateX = endPoint.pageX - startPoint.current?.pageX
const translateY = endPoint.pageY - startPoint.current?.pageY
setTranslate({ translateX, translateY })
}, {wait:16.7})
const onTouchCancel = useCallback(()=>{
startPoint.current = undefined
},[])
return (
<View
catchMove
onTouchCancel={onTouchCancel}
onTouchEnd={onTouchCancel}
onTouchStart={onTouchStart}
className='w-15 h-15 rounded-lg fixed z-10 left-5 bottom-5 bg-primary-light'
onTouchMove={touchMove.run}
style={{
transition: 'transform 10ms',
transform: translate ? `translate3d(${translate.translateX}px, ${translate.translateY}px , 0)` : "",
}}
>
<Text className='text-white'>Hello world!</Text>
</View>
)
}
使用方,增加CustomWrapper,减少setData的嵌套
<CustomWrapper>
<TouchTest />
</CustomWrapper>
@liuhuapiaoyuan @lupingW 感谢两位大佬,有效。
我对比了一下h5、微信开发者工具、安卓真机和iOS真机上面onTouchMove的回调次数,安卓真机明显很少。所以并不是transfrom卡顿,而是onTouchMove回调次数少,导致触发位移的次数少,看起来移动就卡顿了。
参考这两篇这篇文章 1、https://developers.weixin.qq.com/community/develop/doc/00042cb0458f70b6b9c72aef85bc00?_at=1558774452627) 2、https://taro-docs.jd.com/docs/react-overall#%E4%BA%8Ccatchmove
得使用小程序的catch:touchmove以捕获更多的触摸移动事件,在Taro React中对应的是加上catchMove属性
相关平台
微信小程序
复现仓库
https://github.com/taroify/taro3312-distance 小程序基础库: 2.20.1 使用框架: React
复现步骤
通过 onTouchMove 事件设置 transform 时会存在卡顿问题
在安卓真机测试时,向下滑动时会存在卡顿问题。iOS真机测试没有问题。
卡帧演示
非卡帧演示
当触屏向下滑动时会卡顿,但是当先向上在向下滑动时就不卡顿了。
期望结果
在安卓真机上,向下滑动不卡顿
实际结果
在安卓真机上,向下滑动卡顿
环境信息