uni-app 安卓端使用BindingX实现动画改变的translateY存在误差值

uni-app 安卓端使用BindingX实现动画改变的translateY存在误差值

示例代码:

<template>  
    <view class="mine-page">  
        <view class="swipper-wrap" ref="wrapRef" :style="{height:windowHeight+'px',width:windowWidth+'px'}">  
            <view id="videoWrap" class="items" ref="itemRef" @touchmove='touchmove'>  
                <view v-for="(i,k) in 5" :key='k' class="video" :style="{height:windowHeight+'px',width:windowWidth+'px',backgroundColor:i%2===0?'red':'blue'}">  
                    <text class="text-name">滑块{{i}}</text>  
                </view>  
            </view>  
        </view>  
    </view>  
</template>  

<script setup lang="ts">  
import { reactive } from 'vue';  
import { ComponentInternalInstance, PropType } from 'vue';  

const { proxy } = getCurrentInstance() as ComponentInternalInstance;  
const BindingX = uni.requireNativePlugin('bindingx');  
const wrapRef=ref();  
const itemRef=ref();  
const { windowHeight, windowWidth } = uni.getSystemInfoSync();  
const dataInfo=reactive({  
    distance:0,  
    BindingXToken:0,  
    isInAnimation:false,  
    startDistance: 20,  
    backDistance: 200,  
    minTime: 300,  
    index: 0,  
})  

const touchmove=(event)=>{  
    if (dataInfo.isInAnimation) {  
        if (dataInfo.BindingXToken != 0) {  
            BindingX.unbind({  
                eventType: 'pan',  
                token: dataInfo.BindingXToken,  
            });  
            dataInfo.BindingXToken = 0;  
        }  
        return;  
    }  
    let touch_origin = `y+${dataInfo.distance}<=0 &&  
            y+${dataInfo.distance}-${windowHeight}>=${-windowHeight * 5}?   
            y+${dataInfo.distance} : ${dataInfo.distance}`;  
    let anchor=wrapRef.value.ref;  
    let element=itemRef.value.ref;  
    let gesTokenObj = BindingX.bind({  
        anchor,  
        eventType:'pan',  
        props: [  
            {element, property:'transform.translateY',expression: touch_origin},   
        ]  
    }, (e)=>{  
        if(e.state === 'end'){  
            console.log('e======',e);  
            if (Math.abs(e.deltaY) > dataInfo.startDistance) {  

                console.log('记录Y的位置===',e.deltaY);  
                const distance = dataInfo.distance + e.deltaY;  

                if (  
                    distance > 0 ||  
                    dataInfo.distance + e.deltaY - windowHeight < -windowHeight * 5  
                ) {  
                    return;  
                }  

                Math.abs(e.deltaY) > 0 && bindTiming(distance, e.deltaY);  
            }  
        }  
    });  

    dataInfo.BindingXToken = gesTokenObj.token;  
}  

const bindTiming = (distance, Y) => {  
    BindingX.unbindAll();  
    dataInfo.isInAnimation = true;  
    let element=itemRef.value.ref;  
    let changed_Y, final_y, translate_y_origin;  

    final_y = dataInfo.distance + (Y > 0 ? 1 : -1) * windowHeight;  
    changed_Y = final_y - distance;  
    translate_y_origin = `easeOutExpo(t,${distance},${changed_Y},300)`;  

    let result = BindingX.bind(  
        {  
            eventType: 'timing',  
            exitExpression: 't>300',  
            props: [  
                { element, property: 'transform.translateY', expression: translate_y_origin }  
            ],  
        },  
        async e => {  
            if (e.state === 'end' || e.state === 'exit') {  
                dataInfo.distance = final_y;  
                dataInfo.isInAnimation = false;  
            }  
        }  
    );  
};  
</script>  

<style lang="scss" scoped>  
    .swipper-wrap{  
        overflow: hidden;  
    }  

    .video{  
        justify-content: center;  
        align-items: center;  
    }  

    .text-name{  
        font-size: 28px;  
        color: #ffffff;  
    }  
</style>

操作步骤:

新建一个nvue页面,复制示例代码进去即可复现。

预期结果:

消除误差值

实际结果:

存在滑动误差值

bug描述:

使用bindingx实现全屏滑块动画时,发现动画改变的translateY值存在误差值,随着滑块数量的增多,误差值会一直累积,应该是计算精度的问题,希望官方修复一下。

开发环境 版本号 项目创建方式
Windows 10 HBuilderX
手机系统 版本号
Android Android 13
手机厂商 手机机型
小米 Redmi K60


更多关于uni-app 安卓端使用BindingX实现动画改变的translateY存在误差值的实战教程也可以访问 https://www.itying.com/category-93-b0.html

1 回复

更多关于uni-app 安卓端使用BindingX实现动画改变的translateY存在误差值的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在使用 uni-appBindingX 实现动画时,特别是涉及到 translateY 的动画,可能会遇到误差值的问题。这种误差通常是由于以下几个原因引起的:

1. 设备像素密度(DPI)问题

不同设备的像素密度不同,可能会导致 translateY 的计算值与实际显示位置存在偏差。BindingX 在处理 translateY 时,可能没有完全考虑到设备的像素密度差异。

解决方案:

  • 在计算 translateY 时,考虑设备的像素密度。可以使用 uni.getSystemInfoSync() 获取设备的 pixelRatio,然后在计算 translateY 时进行相应的缩放。
const systemInfo = uni.getSystemInfoSync();
const pixelRatio = systemInfo.pixelRatio;
const translateY = targetTranslateY / pixelRatio;

2. 布局计算延迟

在某些情况下,布局计算可能会延迟,导致 BindingX 在计算 translateY 时使用了旧的布局信息,从而产生误差。

解决方案:

  • 确保在布局计算完成后再执行 BindingX 动画。可以使用 nextTicksetTimeout 来延迟动画的执行。
uni.nextTick(() => {
  // 执行 BindingX 动画
});

3. BindingX 插值器精度问题

BindingX 的插值器在计算动画时可能存在精度问题,特别是在处理复杂的动画曲线时,可能会导致 translateY 的误差。

解决方案:

  • 尝试使用更简单的动画曲线,或者手动调整 translateY 的值以补偿误差。

4. 浏览器渲染引擎差异

不同设备的浏览器渲染引擎可能存在差异,导致 translateY 的渲染效果不一致。

解决方案:

  • 在不同的设备上进行测试,调整 translateY 的值以适应不同的渲染引擎。

5. 使用 transform 的其他属性

有时,translateY 的误差可能是由于其他 transform 属性(如 scalerotate 等)的影响。

解决方案:

  • 确保在动画过程中,其他 transform 属性不会影响 translateY 的计算。

6. 使用 BindingXexpression 进行精确控制

BindingX 提供了 expression 功能,可以通过表达式精确控制动画的行为。你可以使用 expression 来补偿 translateY 的误差。

bindingx.bind({
  eventType: 'pan',
  anchor: element,
  props: [
    {
      element: element,
      property: 'transform.translateY',
      expression: 'y + offsetY', // 使用表达式进行精确控制
    },
  ],
});
回到顶部