如何使用 JavaScript 为一帧中的相机运动设置动画?
How do I animate a camera movement in a-frame, using JavaScript?
我正在使用 A-Frame 在桌面的常规网页上构建虚拟游览,运行。没有VR导航,只是移动和点击鼠标光标。
我会在a-scene上面有几个按钮。每个按钮都会将相机指向不同的方向。我设法让它工作。下一步是将它设置为动画,就好像相机正在平移到它的新方向,而不是直接跳到它。
有没有办法实现这一点,同时设置动画的持续时间和缓动?
我从 this SO post 知道如何在框架内做到这一点。但是因为我在它之外调用一个函数,所以我对如何让它工作有点迷茫。
这是我的代码:
function moveCamera() {
var el = document.querySelector("a-camera");
el.components["look-controls"].pitchObject.rotation.x = -0.1;
el.components["look-controls"].yawObject.rotation.y = 0.85;
}
.sceneWrapper {
position: relative;
padding-top: 20px;
height: 100vh;
}
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<button id="btn01" type="button" name="button" onclick="moveCamera()">Move Camera</button>
<div class="sceneWrapper">
<a-scene embedded background="color: #FAFAFA">
<a-entity id='cameraWrapper' position="0 0 0">
<a-camera wasd-controls-enabled="false" look-controls="reverseMouseDrag:true">
<a-animation attribute="position"
dur="2000"
easing="linear"
to="0 1.6 -10"></a-animation>
</a-camera>
</a-entity>
<a-sky color="#c7dcff"></a-sky>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane>
</a-scene>
</div>
有几种方法可以做到这一点。一种是直接在 look-controls 组件的 tick 函数中管理它。这意味着您需要根据外观控件创建自己的组件。它需要一些技巧,但它确实有效。
更简单的方法是使用 requestAnimationFrame 来管理移动。这是我根据您的代码制作的一个完整的示例。您可以将持续时间更改为您喜欢的时间。
<html>
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
<a-entity id='cameraWrapper' position="0 0 0">
<a-camera wasd-controls-enabled="false" look-controls="reverseMouseDrag:true">
<a-animation attribute="position" dur="2000" easing="linear" to="0 1.6 -10"></a-animation>
</a-camera>
</a-entity>
<a-sky color="#c7dcff"></a-sky>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane>
</a-scene>
<button type="button" style="position: fixed; top: 10px; left: 10px;" onclick="moveCamera(-0.1, 0.85)">Move Camera</button>
<script type="text/javascript">
var start, x_start, y_start, x_rotation, y_rotation;
var duration = 1000;
var camera = document.querySelector("a-camera");
function moveCamera(x_destination, y_destination) {
start = null;
x_start = camera.components["look-controls"].pitchObject.rotation.x;
x_rotation = x_destination - x_start;
y_start = camera.components["look-controls"].yawObject.rotation.y;
y_rotation = y_destination - y_start;
requestAnimationFrame(step);
}
function step(timestamp) {
if (start === null) start = timestamp;
var progress = timestamp - start;
camera.components["look-controls"].pitchObject.rotation.x = x_start + x_rotation * progress / duration;
camera.components["look-controls"].yawObject.rotation.y = y_start + y_rotation * progress / duration;
if (progress < duration) {
requestAnimationFrame(step);
}
}
</script>
</body>
</html>
我正在使用 A-Frame 在桌面的常规网页上构建虚拟游览,运行。没有VR导航,只是移动和点击鼠标光标。
我会在a-scene上面有几个按钮。每个按钮都会将相机指向不同的方向。我设法让它工作。下一步是将它设置为动画,就好像相机正在平移到它的新方向,而不是直接跳到它。
有没有办法实现这一点,同时设置动画的持续时间和缓动?
我从 this SO post 知道如何在框架内做到这一点。但是因为我在它之外调用一个函数,所以我对如何让它工作有点迷茫。
这是我的代码:
function moveCamera() {
var el = document.querySelector("a-camera");
el.components["look-controls"].pitchObject.rotation.x = -0.1;
el.components["look-controls"].yawObject.rotation.y = 0.85;
}
.sceneWrapper {
position: relative;
padding-top: 20px;
height: 100vh;
}
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<button id="btn01" type="button" name="button" onclick="moveCamera()">Move Camera</button>
<div class="sceneWrapper">
<a-scene embedded background="color: #FAFAFA">
<a-entity id='cameraWrapper' position="0 0 0">
<a-camera wasd-controls-enabled="false" look-controls="reverseMouseDrag:true">
<a-animation attribute="position"
dur="2000"
easing="linear"
to="0 1.6 -10"></a-animation>
</a-camera>
</a-entity>
<a-sky color="#c7dcff"></a-sky>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane>
</a-scene>
</div>
有几种方法可以做到这一点。一种是直接在 look-controls 组件的 tick 函数中管理它。这意味着您需要根据外观控件创建自己的组件。它需要一些技巧,但它确实有效。 更简单的方法是使用 requestAnimationFrame 来管理移动。这是我根据您的代码制作的一个完整的示例。您可以将持续时间更改为您喜欢的时间。
<html>
<head>
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
</head>
<body>
<a-scene background="color: #FAFAFA">
<a-entity id='cameraWrapper' position="0 0 0">
<a-camera wasd-controls-enabled="false" look-controls="reverseMouseDrag:true">
<a-animation attribute="position" dur="2000" easing="linear" to="0 1.6 -10"></a-animation>
</a-camera>
</a-entity>
<a-sky color="#c7dcff"></a-sky>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane>
</a-scene>
<button type="button" style="position: fixed; top: 10px; left: 10px;" onclick="moveCamera(-0.1, 0.85)">Move Camera</button>
<script type="text/javascript">
var start, x_start, y_start, x_rotation, y_rotation;
var duration = 1000;
var camera = document.querySelector("a-camera");
function moveCamera(x_destination, y_destination) {
start = null;
x_start = camera.components["look-controls"].pitchObject.rotation.x;
x_rotation = x_destination - x_start;
y_start = camera.components["look-controls"].yawObject.rotation.y;
y_rotation = y_destination - y_start;
requestAnimationFrame(step);
}
function step(timestamp) {
if (start === null) start = timestamp;
var progress = timestamp - start;
camera.components["look-controls"].pitchObject.rotation.x = x_start + x_rotation * progress / duration;
camera.components["look-controls"].yawObject.rotation.y = y_start + y_rotation * progress / duration;
if (progress < duration) {
requestAnimationFrame(step);
}
}
</script>
</body>
</html>