您的位置:首页 > 汽车 > 新车 > 青岛关键词网站排名_深圳网站建设主页_十大营销案例分析_百度seo排名培训优化

青岛关键词网站排名_深圳网站建设主页_十大营销案例分析_百度seo排名培训优化

2025/3/11 14:48:59 来源:https://blog.csdn.net/m0_64455070/article/details/146158216  浏览:    关键词:青岛关键词网站排名_深圳网站建设主页_十大营销案例分析_百度seo排名培训优化
青岛关键词网站排名_深圳网站建设主页_十大营销案例分析_百度seo排名培训优化

目录

1. 浏览器渲染机制底层原理

1.1 JavaScript事件循环与渲染帧

宏任务/微任务对动画的影响 

1.2 帧率控制科学

Delta Time标准化计算:

帧率波动补偿策略:

2. Three.js动画体系深度解析

2.1 原生动画循环优化

性能黑洞检测:

渲染节流技术:

2.2 补间动画工业级解决方案

2.2.1 Tween.js源码级剖析

2.2.2 高级路径动画

2.3 动画系统架构设计

状态机管理:

动画轨道系统:

动画混合与层叠

性能优化:


本篇文章适合基本掌握three.js基础知识的开发者,所以本文不过于重复之前的内容,但是也会适当回顾关键概念

1. 浏览器渲染机制底层原理

1.1 JavaScript事件循环与渲染帧

宏任务/微任务对动画的影响 

        setTimeout vs requestAnimationFrame(rAF):

        setTimeout是基于事件循环的宏任务调度,无法保证精确的动画时间间隔。

        requestAnimationFrame是专门为动画设计的API,与浏览器的渲染管线同步,能够提供更加平滑的动画效果。

浏览器渲染管线

        解析 → 样式计算 → 布局 → 绘制 → 合成

        以上步骤是浏览器渲染页面的关键流程

垂直同步(VSync)

        rAF如何与显示器刷新率同步(60Hz/120Hz):rAF 通常会尝试与显示器的刷新率同步,以减少画面撕裂和卡顿。

1.2 帧率控制科学

Delta Time标准化计算
const clock = new THREE.Clock();
let delta = 0;
const targetFPS = 60;function animate() {delta = clock.getDelta(); // 获取精确到毫秒的时间差// 基于实际耗时计算运动增量cube.rotation.y += (Math.PI / 2) * delta; // 每秒旋转90度requestAnimationFrame(animate);
}
帧率波动补偿策略

        当delta > 0.1时启用插值算法来平滑动画

        丢帧处理:使用累积时间算法避免动画跳跃

let accumulator = 0;
const fixedStep = 1 / 60; // 固定步长function animate() {accumulator += clock.getDelta();while (accumulator >= fixedStep) {updatePhysics(fixedStep); // 物理模拟需固定步长accumulator -= fixedStep;}render(accumulator / fixedStep); // 插值渲染
}

2. Three.js动画体系深度解析

2.1 原生动画循环优化

性能黑洞检测

        在动画循环中创建对象(如new THREE.Vector3()

        频繁修改几何体顶点数据(应使用geometry.verticesNeedUpdate = true标记)

渲染节流技术

        通过setTimeout实现非活动状态降频渲染

let isActive = true;function conditionalAnimate() {if (isActive) {animate();setTimeout(conditionalAnimate, 1000 / 30); // 降为30FPS}
}

2.2 补间动画工业级解决方案

2.2.1 Tween.js源码级剖析

时间函数算法实现

        自定义三次贝塞尔缓动函数

function cubicBezier(t, p1x, p1y, p2x, p2y) {// 详细实现贝塞尔公式...
}

对象池优化

        复用Tween实例避免垃圾回收(GC)压力

const tweenPool = [];function createTween(target) {return tweenPool.length > 0 ? tweenPool.pop().reset(target): new TWEEN.Tween(target);
}
2.2.2 高级路径动画

贝塞尔曲线运动

const curve = new THREE.CubicBezierCurve3(new THREE.Vector3(0, 0, 0),new THREE.Vector3(2, 3, 1),new THREE.Vector3(-1, 2, 0),new THREE.Vector3(5, 0, 3)
);new TWEEN.Tween({ t: 0 }).to({ t: 1 }, 3000).onUpdate(({ t }) => {const point = curve.getPoint(t);object.position.copy(point);}).start();

跟随路径旋转

        使用curve.getTangent(t)计算朝向

2.3 动画系统架构设计

状态机管理

        定义IDLEPLAYINGPAUSED等状态,用于管理动画的生命周期

动画轨道系统

        通过THREE.AnimationClip实现多轨道融合

const clip = new THREE.AnimationClip('dance', 10, [new THREE.VectorKeyframeTrack('.position', [0, 3, 6], [0,0,0, 2,1,0, 2,1,3]),new THREE.QuaternionKeyframeTrack('.quaternion',[0, 5],[0,0,0,1, 0.707,0,0.707,0] // 绕Y轴旋转180度)
]);const mixer = new THREE.AnimationMixer(model);
const action = mixer.clipAction(clip);
action.play();
动画混合与层叠

        使用 THREE.AnimationMixer 和多个 THREE.AnimationClip 实现复杂的动画混合效果。

        通过调整 AnimationMixer 的权重来控制不同动画的混合比例。

案例:

性能优化:

        避免不必要的渲染和计算,使用 requestAnimationFrame 进行动画循环。

案例:

// 初始化场景、相机和渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);// 加载一个带有多个动画的GLTF模型
const loader = new THREE.GLTFLoader();
loader.load('path/to/your/model.glb', function (gltf) {const model = gltf.scene;scene.add(model);// 创建AnimationMixerconst mixer = new THREE.AnimationMixer(model);// 获取动画剪辑const clipWalk = gltf.animations[0];const clipRun = gltf.animations[1];// 创建动画动作const actionWalk = mixer.clipAction(clipWalk);const actionRun = mixer.clipAction(clipRun);// 播放动画并设置权重actionWalk.play();actionRun.play();// 初始化权重let walkWeight = 1.0;let runWeight = 0.0;// 动画循环function animate() {requestAnimationFrame(animate);// 更新权重(这里只是示例,你可以根据需求动态调整权重)walkWeight = Math.cos(Date.now() * 0.001) * 0.5 + 0.5;runWeight = 1.0 - walkWeight;// 设置权重actionWalk.setWeight(walkWeight);actionRun.setWeight(runWeight);// 更新mixermixer.update(0.01);// 渲染场景renderer.render(scene, camera);}animate();
}, undefined, function (error) {console.error(error);
});// 设置相机位置
camera.position.z = 5;

        尽量减少对DOM的操作,使用CSS动画或WebGL进行高效的渲染。

        利用GPU加速,减少CPU的负担。

案例:

// 创建一个几何体和材质
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });// 创建一个InstancedMesh
const count = 1000;
const instancedMesh = new THREE.InstancedMesh(geometry, material, count);// 设置每个实例的变换矩阵
for (let i = 0; i < count; i++) {const matrix = new THREE.Matrix4().makeTranslation(Math.random() * 10 - 5,Math.random() * 10 - 5,Math.random() * 10 - 5);instancedMesh.setMatrixAt(i, matrix);
}// 更新InstancedMesh的变换矩阵
instancedMesh.instanceMatrix.needsUpdate = true;// 将InstancedMesh添加到场景中
scene.add(instancedMesh);// 动画循环
function animate() {requestAnimationFrame(animate);// 更新每个实例的变换(这里只是简单的旋转示例)for (let i = 0; i < count; i++) {const matrix = instancedMesh.getMatrixAt(i);matrix.premultiply(new THREE.Matrix4().makeRotationY(0.01));instancedMesh.setMatrixAt(i, matrix);}instancedMesh.instanceMatrix.needsUpdate = true;// 渲染场景renderer.render(scene, camera);
}
animate();


 

码字不易,各位大佬点点赞呗

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com