three.js - 使用 lineTo 和 curveTo 在 Three.js 中为线条制作动画
问题描述
我是一个three.js 新手,我来自Processing/p5.js(所以我对动画循环有点宠坏了)。我正在尝试创建类似这种简单的拉伸药丸形状的东西:
这是我从网上找到的一些东西拼凑而成的。我只有“O”形。我试图让变量 oHeight 成为导致 Math.sin 来回流动的变量。
我需要更新路径吗?还是bufferGeometry?还是三条路径?
抱歉,这段代码太乱了。刚开始!
var camera, scene, renderer;
var curve;
var path;
var oHeight = 0;
var delta = 0;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 600;
scene = new THREE.Scene();
path = new THREE.Path();
path.lineTo( 0, 0 );
path.quadraticCurveTo( 0, 20, 20, 20 );
path.lineTo( 40, 20 );
path.quadraticCurveTo( 60,20, 60,0);
path.lineTo(60,-40-oHeight);
path.quadraticCurveTo( 60,-60-oHeight, 40,-60-oHeight);
path.lineTo(20,-60-oHeight);
path.quadraticCurveTo(0,-60,0,-40-oHeight);
path.lineTo(0,0);
var points = path.getPoints();
var geometry = new THREE.BufferGeometry().setFromPoints( points );
var material = new THREE.LineBasicMaterial( { color: 0xffffff } );
curve = new THREE.Line( geometry, material );
scene.add( curve );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
}
function animate() {
requestAnimationFrame( animate );
delta +=.1;
oHeight = Math.sin(delta)*20;
line.needUpdate = true; //is this where I went wrong?
renderer.render( scene, camera );
}
解决方案
您的代码中没有对象line
,也没有从对象geometry
到oHeight
. 只是一个临时对象,其中THREE.Path
包含创建BufferGeoemtry
. 请注意,最后的顶点geometry
存储在 GPU 上的数组缓冲区中。
您必须在animate
函数中创建路径并将其设置为BufferGeoemtry
. 所以几何图形在每一帧中重新创建:
function animate() {
requestAnimationFrame( animate );
delta +=.1;
oHeight = Math.sin(delta)*20;
path = new THREE.Path();
path.lineTo( 0, 0 );
path.quadraticCurveTo( 0, 20, 20, 20 );
path.lineTo( 40, 20 );
path.quadraticCurveTo( 60,20, 60,0);
path.lineTo(60,-40-oHeight);
path.quadraticCurveTo( 60,-60-oHeight, 40,-60-oHeight);
path.lineTo(20,-60-oHeight);
path.quadraticCurveTo(0,-60-oHeight,0,-40-oHeight);
path.lineTo(0,0);
geometry.dispose();
geometry.setFromPoints( path.getPoints() );
renderer.render( scene, camera );
}
var camera, scene, renderer;
var curve;
var path;
var oHeight = 0;
var delta = 0;
var geometry;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.z = 600;
scene = new THREE.Scene();
geometry = new THREE.BufferGeometry();
var material = new THREE.LineBasicMaterial( { color: 0xffffff } );
curve = new THREE.Line( geometry, material );
scene.add( curve );
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
window.onresize = resize;
}
function animate() {
requestAnimationFrame( animate );
delta +=.1;
oHeight = Math.sin(delta)*20;
path = new THREE.Path();
path.lineTo( 0, 0 );
path.quadraticCurveTo( 0, 20, 20, 20 );
path.lineTo( 40, 20 );
path.quadraticCurveTo( 60,20, 60,0);
path.lineTo(60,-40-oHeight);
path.quadraticCurveTo( 60,-60-oHeight, 40,-60-oHeight);
path.lineTo(20,-60-oHeight);
path.quadraticCurveTo(0,-60-oHeight,0,-40-oHeight);
path.lineTo(0,0);
geometry.dispose();
geometry.setFromPoints( path.getPoints() );
renderer.render( scene, camera );
}
function resize() {
var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
<script src="https://threejs.org/build/three.min.js"></script>
推荐阅读
- cmake - conan.io 包管理 - 仅源包
- javascript - 一个从对象中删除元素的衬垫
- ubuntu - ffmpeg snap 权限被拒绝访问加密文件夹
- cmake - CMake:静态库被忽略(对象编译两次)
- python - 有没有办法处理 Python 中第三方模块抛出的错误?
- python - Pygame - 图像不适用于 Visual Studio 代码
- java - 由于增强的 for 循环导致的 ConcurrentModification 错误
- javascript - 从 Spark AR 中的 Picker UI 中点击按钮时如何制作动画?
- php - 显示来自 Rss 文件的数据
- sorting - 在 Algolia 中按相关性对结果进行排序而不过滤