<!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
现在支持上传本地图片了!
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
// 引入gltf模型加载库GLTFLoader.js
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
// 1. 三维样条曲线
const path = new THREE.CatmullRomCurve3([
new THREE.Vector3(-50, 20, 90),
new THREE.Vector3(-10, 40, 40),
new THREE.Vector3(0, 0, 0),
new THREE.Vector3(60, -60, 0),
new THREE.Vector3(70, 0, 80)
]);
// 2. LineCurve3创建直线段路径
const lineCurve3Path = new THREE.LineCurve3(new THREE.Vector3(50, 100, 0), new THREE.Vector3(50, 0, 0));
// 3. 创建多段线条的顶点数据
const p1 = new THREE.Vector3(0, 0,100)
const p2 = new THREE.Vector3(0, 0,30);
const p3 = new THREE.Vector3(0, 0,0);
const p4 = new THREE.Vector3(30, 0, 0);
const p5 = new THREE.Vector3(100, 0, 0);
const line1 = new THREE.LineCurve3(p1, p2);
const curve = new THREE.QuadraticBezierCurve3(p2, p3, p4);
const line2 = new THREE.LineCurve3(p4, p5);
const CurvePath = new THREE.CurvePath();
CurvePath.curves.push(line1, curve, line2); // 三条线拼接为一条曲线
// 一组二维向量表示一个多边形轮廓坐标
const pointsArr = [
new THREE.Vector2(-50, -50),
new THREE.Vector2(-60, 0),
new THREE.Vector2(0, 50),
new THREE.Vector2(60, 0),
new THREE.Vector2(50, -50),
];
const shape = new THREE.Shape(pointsArr);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 3000);
const renderer = new THREE.WebGLRenderer({ antialias: true });
// TubeGeometry管道
// path:路径 40:沿着轨迹细分数 2:管道半径 25:管道截面圆细分数
const geometry = new THREE.TubeGeometry(path, 40, 2, 25);
const material = new THREE.MeshLambertMaterial({
side:THREE.DoubleSide,//双面显示看到管道内壁
});
const curveMesh = new THREE.Mesh(geometry, material);
const geometry2 = new THREE.TubeGeometry(lineCurve3Path, 40, 2, 25);
const material2 = new THREE.MeshLambertMaterial({
side:THREE.DoubleSide,//双面显示看到管道内壁
color: 0x83ab29
});
const curveLine2 = new THREE.Line(geometry2, material2);
// CurvePath:路径 40:沿着轨迹细分数 2:管道半径 25:管道截面圆细分数
const geometry3 = new THREE.TubeGeometry(CurvePath, 50, 2, 25);
const material3 = new THREE.MeshLambertMaterial({
side:THREE.DoubleSide,//双面显示看到管道内壁
color: 0x48ad22
});
const curveLine3 = new THREE.Line(geometry3, material3);
// 轮廓填充几何体
const geometry4 = new THREE.ShapeGeometry(shape);
const material4 = new THREE.MeshLambertMaterial({
wireframe:true,
color: 0xfddc2a
})
const mesh = new THREE.Mesh(geometry4, material4);
const axesHelper = new THREE.AxesHelper(100);
const ambientLight = new THREE.AmbientLight(0x404040, 2); // 添加环境光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1); // 添加方向光
const pointLight = new THREE.PointLight(0xff0000, 2, 10); // 添加点光源,红色的点光源
const controls = new OrbitControls(camera, renderer.domElement); // 添加轨道控制器
directionalLight.position.set(5, 5, 5).normalize();
directionalLight.castShadow = true; // 方向光投射阴影
pointLight.position.set(2, 2, 2);
pointLight.castShadow = true; // 点光源投射阴影
controls.enableDamping = true; // 启用阻尼效果
controls.dampingFactor = 0.05; // 阻尼系数
scene.add(mesh);
scene.add(curveMesh);
scene.add(curveLine2);
scene.add(curveLine3);
scene.add(axesHelper);
scene.add(directionalLight);
scene.add(ambientLight);
scene.add(pointLight);
// 设置相机位置
camera.position.set(200, 200, 200);
camera.lookAt(0, 0, 0);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.shadowMap.enabled = true; // 启用阴影
renderer.setClearColor(0x444444, 1);
document.body.appendChild(renderer.domElement);
// 动画循环
const animate = () => {
requestAnimationFrame(animate);
// 渲染场景
renderer.render(scene, camera);
};
// 启动动画
animate();
// 窗口大小调整时更新相机和渲染器
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
{
"dependencies": {
"three": "0.173.0"
}
}
预览