如何使用devicemotion旋转获得平滑运动动画速率数据

时间:2019-02-06 19:56:25

标签: javascript three.js

我正在使用rotationRate事件监听器中的devicemotion数据来倾斜three.js场景。使用该数据,场景确实以正确的角度倾斜,但是会导致类似断断续续的运动效果。有什么方法可以使运动效果平滑吗?

我目前正在将event.betaevent.gamma数据映射到three.js相机倾斜的适当角度,但是由于旋转数据直接用于角度更新,因此结果不太顺利。我已经尝试过将角度乘以较小的数字,但这并不能使动作平滑。

function handleDeviceMotion(event) {
    rotateX = Math.clip(parseInt((event.rotationRate.beta*10).toFixed(0)), -rotationContain, rotationContain);
    rotateY = Math.clip(parseInt((event.rotationRate.alpha*10).toFixed(0)), -rotationContain, rotationContain);
    rotateXMapped = rotateX.map(-rotationContain, rotationContain, -paneAngleContain, paneAngleContain);
    rotateYMapped = rotateY.map(-rotationContain, rotationContain, -paneAngleContain, paneAngleContain);
    rotateXMapped += 0.3;
    rotateYMapped += 0.3;
}

rotateXMaprotateYMap随后在orbitControls.js提供的three.js库中使用。有没有办法增加从当前角度到更新角度的延迟呢?数学不是我的强项,并且已经尝试了一段时间了。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我相信您会遇到抖动动画,因为您使用的是devicemotion事件(主要用于捕获加速度的变化),而不是deviceorientation事件(主要用于捕捉方向变化)。 deviceorientation是Three.js用于其DeviceOrientation控件的推荐方法,您可以在此处使用它:https://threejs.org/examples/?q=dev#misc_controls_deviceorientation

为了安全起见,您是否尝试过使用非常简单的设置运行场景?这可以帮助排除其他性能瓶颈导致帧率降低的可能性。

答案 1 :(得分:0)

事实证明,我只是缺少一些lerp interpolation来平滑倾斜数据的运动。该公式计算未来点,当前点并取平均值。产生流畅的动画。

我发现了很棒的lerp demo on CodePen

这是我执行中的更新代码:

function handleDeviceMotion(event) {
    // contain rotationRate data, then map it to appropriate scene tilt angles, add lerp to smooth effect
    rotateX = Math.clip(parseInt((event.rotationRate.beta*10).toFixed(0)), -rotationContain, rotationContain);
    rotateY = Math.clip(parseInt((event.rotationRate.alpha*10).toFixed(0)), -rotationContain, rotationContain);
    rotateXMapped = rotateX.map(-rotationContain, rotationContain, -paneAngleContain, paneAngleContain);
    rotateYMapped = rotateY.map(-rotationContain, rotationContain, -paneAngleContain, paneAngleContain);
    rotateXLerp = lerp(rotateXLerp, rotateXMapped, 0.15); // 0.1 = default
    rotateYLerp = lerp(rotateYLerp, rotateYMapped, 0.15); // 0.1 = default
}

function lerp(start, end, amt) {
    return (1-amt)*start+amt*end;
}

我希望这对以后的任何人都有帮助!