我正在参加中秋创意投稿大赛,详情请看:中秋创意投稿大赛
前言
嫦娥应悔偷灵药,碧海青天夜夜心。
——李商隐
介绍
本期也是临时创作,由three.js创作了野兔奔月3D动画,野兔有个小想法也要找玉兔过中秋。。好吧,是我临时瞎编的,看效果吧:
正文
1.分析需求
- 环境搭建
- 导入月球
- 野兔奔跑
- 无尽循环
我们这里模型的是从sketchfab这样的资源网站上获取的,当然你有时间也可以自己创作3d模型,我一般用的是blender,只要不做细腻的毛发和质感这样的皮肤等特别细的,其他的方面算比较容易入门的。当然要不断减少面,毕竟是网页,面多了吃不消的。
2.环境搭建
<body>
<div id="app"></div>
<script src="./js/three.min.js"></script>
<script src="./js/GLTFLoader.js"></script>
<script src="./js/OrbitControls.js"></script>
<script type="module" src="./app.js"></script>
</body>
当然我们要把需要的three包和gltf模型加载器还有轨道控制器引入进去。
class Application {
constructor() {
this.app = document.getElementById("app");
this.w = 0;
this.h = 0;
this.scene = null;
this.camera = null;
this.renderer = null;
this.mixer = null;
this.clock = new THREE.Clock();
this.init();
}
init() {
// 初始化
this.scene = new THREE.Scene();
this.createCamera();
this.addLight();
this.renderer = new THREE.WebGLRenderer({
antialias: true,
});
this.renderer.setSize(document.body.clientWidth, document.body.clientHeight);
this.renderer.setClearColor(new THREE.Color(0x000000));
this.app.appendChild(this.renderer.domElement);
new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.render();
this.loop();
}
addLight() {
// 添加灯光
this.ambientLight = new THREE.AmbientLight(0xFFFFFF);
this.ambientLight.intensity = 1;
this.scene.add(this.ambientLight);
}
createCamera() {
// 添加相机
this.camera = new THREE.PerspectiveCamera(
90,
document.body.clientWidth / document.body.clientHeight,
0.2,
1000
);
this.camera.position.set(-12, 7, 10);
}
createMoon() {
// 创建月球
}
createRabbit() {
// 创建野兔
}
render() {
// 主渲染
this.createRabbit();
this.createMoon();
}
loop() {
// 循环
requestAnimationFrame(this.loop.bind(this));
const {renderer, scene, camera} = this;
renderer.render(scene, camera);
camera.lookAt(scene.position);
}
}
window.onload = new Application();
我们这主逻辑中完成了这些基础工作:
- 创建场景scene
- 创建渲染器renderer,将宽高铺满全屏,且将其视图放到dom中
- 创建相机
- 追加常光
- 追加轨道控制器
- 循环更新视图
2.导入月球
createMoon() {
let loader = new THREE.GLTFLoader();
loader.load("./assets/moon/scene.gltf", gltf => {
this.moon = gltf.scene;
this.moon.scale.set(.05, .05, .05)
this.scene.add(this.moon);
});
}
我们之前下载好的月球glft模型,通过glft模型加载器找到他的路径执行下载,并且追加到场景中。
3.野兔奔跑
createRabbit() {
let loader = new THREE.GLTFLoader();
loader.load("./assets/rabbit/scene.gltf", gltf => {
this.rabbit = gltf.scene;
this.rabbit.scale.set(.16, .16, .16)
this.rabbit.position.set(0, 5, 0)
this.mixer = new THREE.AnimationMixer(this.rabbit);
this.mixer.clipAction(gltf.animations[0]).play()
this.scene.add(this.rabbit);
});
}
还是一样,我们要导入野兔的gltf模型添加到场景中。这个gltf模型中带了一个奔跑动画,我们创建AnimationMixer,在混合器中中之前这个奔跑动画。这时你发现他并没有动,这是怎么回事呢?我们没有循环更新他的动作执行。
4.无尽循环
loop() {
requestAnimationFrame(this.loop.bind(this));
const {renderer, scene, camera, mixer, clock,moon} = this;
let delta = clock.getDelta();
mixer && mixer.update(delta);
renderer.render(scene, camera);
camera.lookAt(scene.position);
if(moon){
moon.rotation.x-=0.05
}
}
在这里我们在混合器中不断更新周期就能看到野兔动起来了。别忘了,月球还要来个旋转呢,很简单在x轴方向不断减值就转起来了。
讲到这里这个动画场景已经结束了,是不是超简单~
拓展
我们本期只是用到了three.js的皮毛就可以很简单构建出动画,主要还是模型给力,当然有时间的话,我们可以自己创作模型,blender就特别适合我们去学习导出模型。
创作不易,你们的支持就是我创作的动力,请各位看官老爷们多多点赞评论收藏,一键三连哟~