<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
index.html
main.js
package.json
现在支持上传本地图片了!
index.html
main.js
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 初始化
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.set(20, 20, 20);
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 交互
const controls = new OrbitControls( camera, renderer.domElement );
// 辅助线
const helper = new THREE.AxesHelper(30)
scene.add(helper);
// 创建路径曲线
const start = new THREE.Vector3(0, 0, 0);
const end = new THREE.Vector3(20, 0, 0);
// 可加入中间控制点提升曲线弯曲效果
const mid = new THREE.Vector3(10, 15, 0);
// 样条曲线:经过给定点,并包含插值算法的平滑曲线
const curve = new THREE.CatmullRomCurve3([start, mid, end]);
// 绘制路径线(可视化)
const curvePoints = curve.getPoints(100);
const geometry = new THREE.BufferGeometry().setFromPoints(curvePoints);
const material = new THREE.LineBasicMaterial({ color: 0x00ffff });
const curveLine = new THREE.Line(geometry, material);
scene.add(curveLine);
// 飞线点对象(小球或粒子)
const flyGeometry = new THREE.SphereGeometry(0.3, 16, 16);
const flyMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const flyObject = new THREE.Mesh(flyGeometry, flyMaterial);
scene.add(flyObject);
// 粒子拖尾/尾迹
const trailGroup = new THREE.Group();
scene.add(trailGroup);
const trailLength = 15;
// 创建粒子并添加到Group
for (let i = 0; i < trailLength; i++) {
const g = new THREE.SphereGeometry(0.2, 8, 8);
const m = new THREE.MeshBasicMaterial({
color: 0xff0000,
opacity: 1,
transparent: true
});
const dot = new THREE.Mesh(g, m);
trailGroup.add(dot);
}
// 动画控制变量
let t = 0;
const speed = 0.01; // 每帧前进的量
function animate() {
requestAnimationFrame(animate);
// t 控制在 0~1 区间来沿曲线移动
t += speed;
if (t > 1) t = 0;
const point = curve.getPoint(t);
flyObject.position.copy(point);
// 从尾部开始更新粒子位置
const children = trailGroup.children;
for (let i = children.length - 1; i > 0; i--) {
children[i].position.copy(children[i - 1].position);
children[i].material.opacity = 1 - i / children.length;
}
// 将队头位置更新为飞行物的位置
children[0].position.copy(flyObject.position);
children[0].material.opacity = 1.0;
controls.update();
renderer.render(scene, camera);
}
animate();
编辑器加载中
package.json
注意:新添加的依赖包首次加载可能会报错,稍后再次刷新即可
{
"dependencies": {
"three": "0.173.0"
}
}
编辑器加载中
预览页面