项目中用到的,记录一下,防止下次要用又找不到了。。。
- vue3
- three.js
- three.path
import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import { PathGeometry, PathPointList } from "three.path";
let scene, camera, renderer;
init();
cline();
animate();
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(
40,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.z = 200;
renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true,
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
document.body.appendChild(renderer.domElement);
const controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener("change", () => {
renderer.render(scene, camera);
});
}
function cline() {
let curve = [
5, 0, 0, 0, 0, 0, 10, 10, 0, 0, 20, 0, -10, -10, 0, 15, 0, 0, 25, -10, 0,
40, -10, 0, 40, -20, 0,
];
// 定义空数组,存储三维坐标
let points = [];
for (let i = 0; i < curve.length; i += 3) {
points.push(new THREE.Vector3(curve[i], curve[i + 1], curve[i + 2]));
}
// 生成曲线
let pathCurve = new THREE.CatmullRomCurve3(points, false, "catmullrom", 0);
// 贴图加载
const arrow = new THREE.TextureLoader().load("/arrow.png");
// 贴图重复设置
arrow.wrapS = arrow.wrapT = THREE.RepeatWrapping;
arrow.repeat.x = 1;
arrow.repeat.y = 1;
// 向异性(追求贴图真实感可以设置,我这里材质都选的基础材质,就没那么讲究了)
// arrow.anisotropy = renderer.capabilities.getMaxAnisotropy();
// 创建一个合适的材质
const material = new THREE.MeshBasicMaterial({
map: arrow,
depthWrite: false,
blending: THREE.AdditiveBlending,
});
// 确定一个向上的向量
const upVector = new THREE.Vector3(0, 0, 1);
// 创建路径点的集合
let pathPoints = new PathPointList();
// 设置集合属性
pathPoints.set(pathCurve.getPoints(1000), 0.5, 2, upVector, false);
// 创建路径几何体
const geometry = new PathGeometry();
// 更新几何体的属性
geometry.update(pathPoints, {
width: 1,
arrow: false,
});
// 创建路径的网格模型
let path = new THREE.Mesh(geometry, material);
// 添加到场景
scene.add(path);
// 在每一帧渲染的时候,更新贴图沿x轴的偏移量,形成uv动画效果
function textureLoop() {
if (arrow) {
arrow.offset.x -= 0.02;
}
requestAnimationFrame(textureLoop);
}
textureLoop();
}
function animate() {
renderer.render(scene, camera);
requestAnimationFrame(animate);
}