1 Star 1 Fork 3

左本/threejs-project

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
case-033.html 4.69 KB
一键复制 编辑 原始数据 按行查看 历史
路昊鑫 提交于 2022-07-12 14:01 +08:00 . 更新
<!DOCTYPE html>
<html>
<head>
<title>Threejs实现镜头跟随物体移动效果,镜头拐弯并保持运动方向</title>
<meta charset="UTF-8">
<script type="text/javascript" src="libs/statistics.js"></script>
<script type="text/javascript" src="libs/steak.js"></script>
<script type="text/javascript" src="libs/three.js"></script>
<script type="text/javascript" src="libs/OrbitControls.js"></script>
<script type="text/javascript" src="libs/GLTFLoader.js"></script>
<script type="text/javascript" src="libs/dat.gui.js"></script>
<script type="text/javascript" charset="UTF-8" src="libs/Tween.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="dom"></div>
<script type="text/javascript">
var camera;
var renderer;
var mesh;
var curve;
var cube1;
var cube2;
function init() {
// 创建一个场景,它将包含我们所有的元素,如物体,相机和灯光。
var scene = new THREE.Scene();
// 创建一个摄像机,它定义了我们正在看的地方
camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 100000);
// 将摄像机对准场景的中心
camera.position.z = -5746;
camera.position.y = 3289;
camera.position.x = -15945;
camera.lookAt(scene.position);
var orbit = new THREE.OrbitControls(camera);
// 创建一个渲染器并设置大小,WebGLRenderer将会使用电脑显卡来渲染场景
renderer = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true,
});
renderer.setClearColor(new THREE.Color("#0e0934"));
renderer.setSize(window.innerWidth, window.innerHeight);
var ambientLight = new THREE.AmbientLight("#ffffff", 1);
scene.add(ambientLight);
// 将呈现器的输出添加到HTML元素
document.getElementById("dom").appendChild(renderer.domElement);
// 启动动画
renderScene();
initFeiji();
function initFeiji() {
var loader = new THREE.GLTFLoader();
loader.load('assets/models/feiji/feiji.glb', function(result) {
mesh = result.scene;
mesh.position.set(-1000, -5000, -5000);
scene.add(mesh);
motion()
});
}
function motion() {
// 通过类CatmullRomCurve3创建一个3D样条曲线
curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-1000, -5000, -5000),
new THREE.Vector3(1000, -5000, 0),
new THREE.Vector3(1800, 800, 1000),
new THREE.Vector3(800, 5000, 5000),
new THREE.Vector3(0, 0, 10000)
]);
// 样条曲线均匀分割100
var points = curve.getPoints(100);
var geometry = new THREE.Geometry();
// 把从曲线轨迹上获得的顶点坐标赋值给几何体
geometry.vertices = points
var material = new THREE.LineBasicMaterial({
color: "#4488ff"
});
var line = new THREE.Line(geometry, material);
scene.add(line);
//管道体
const tubeGeometry = new THREE.TubeGeometry(curve, 100, 500, 30); // 101取点数 3为r 30为三角切面数
const tubeMesh = new THREE.Mesh(tubeGeometry, new THREE.MeshBasicMaterial({
color: "#00aa00",
side: THREE.DoubleSide,
wireframe: true
}))
scene.add(tubeMesh)
}
function changeLookAt(t) {
// 当前点在线条上的位置
const position = curve.getPointAt(t);
var nPos = new THREE.Vector3(position.x, position.y - 100, position.z);
mesh.position.copy(nPos);
// 返回点t在曲线上位置切线向量
const tangent = curve.getTangentAt(t);
// 位置向量和切线向量相加即为所需朝向的点向量
const lookAtVec = tangent.add(nPos);
mesh.lookAt(lookAtVec);
if (t > 0.03) {
var pos = curve.getPointAt(t - 0.03);
camera.position.copy(pos);
camera.lookAt(position)
}
}
var clock = new THREE.Clock(); //声明一个时钟对象
const loopTime = 10 * 1000; // loopTime: 循环一圈的时间
let i = 0;
function renderScene() {
// 使用requestAnimationFrame函数进行渲染
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
if (curve) {
let time = Date.now();
let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比
setTimeout(function() {
changeLookAt(t);
}, 500)
}
}
}
window.onload = init;
// 随着窗体的变化修改场景
function onResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
// 监听窗体调整大小事件
window.addEventListener('resize', onResize, false);
</script>
</body>
</html>
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zuoben/threejs-project.git
git@gitee.com:zuoben/threejs-project.git
zuoben
threejs-project
threejs-project
master

搜索帮助