HTML5有强大的动画效果,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,但一直没有没有涉及到游戏方面的业务,所以对这方面知之甚少,感觉自己损失了一大片宝藏一样,好心疼,three.js,是对webGL 的一个封装,使我们不必纠结于一些数学问题(比如旋转啊,线性代数的求解啊,说实话,我真的忘了怎么解)
第一步,加载three.js,一般稍微有点名气的工具,都是有cdn的,threejs有个缺点,就是版本更新太快,都r83了,现在实现一个入门的雪花效果
<script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>
第二步,three.js中主要有三个概念,场景,相机,渲染器,初始化一下
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 100;
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
第三步,既然是雪花效果,所以需要一张图片,three.js中,一般这样处理,先得到一个纹理,然后得到材料,然后得到一个平面,最后将这个平面加入场景中,每一级都有依赖
// 纹理,应用于一个表面,或者作为一个反射或折射贴图。
textureLoader = new THREE.TextureLoader();
map = textureLoader.load('snow2.jpg');
// 传入纹理,得到材料
material = new THREE.SpriteMaterial({map: map});
for ( i = 0; i < amount; i ++ ){
// 精灵平面
var particle = new THREE.Sprite( material );
var randomScale = randomRange(20,40)
particle.position.x = randomRange(-1000, 800);
particle.position.y = randomRange(-1000, 1200);
particle.position.z = randomRange(-1000, 1000);
particle.scale.x = particle.scale.y = particle.scale.z = randomScale;
particle.v = new THREE.Vector3(0, -fallSpeen, 0);
particle.v.z = (1 * randomRange(-1, 1));
particle.v.x = (1 * randomRange(-1, 1));
particles.push(particle);
//将平面加入场景中
scene.add( particle );
}
第四步,将render生成的canvas插入到页面中
container.appendChild(renderer.domElement);
第五步,将场景,和相机传递到渲染器中,渲染出来
renderer.render( scene, camera );
第六步:不断的调整平面的位置,然后重复第五步,此处写一个方法,requestAnimationFrame可以按照浏览器最高的频率绘制,同时切换到别的tab页时,会停止计算,但是settimeout不会。
function animate() {
requestAnimationFrame(animate);
render();
}
完整代码,直接copy就可以使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>
</head>
<body>
<script>
console.log(THREE)
var container, camera, scene, renderer, particles = [], material, map, textureLoader;
var halfX = window.innerWidth / 2;
var halfY = window.innerHeight / 2;
var mouseX = 0, mouseY = 0;
var fallSpeen = 2;
var amount = 1000;
// 返回一个范围内内的随机数
function randomRange(min, max) {
return ((Math.random() * (max - min)) + min);
}
function init() {
container = document.createElement('div');
document.body.appendChild(container);
// 相机
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 100;
// 场景
scene = new THREE.Scene();
// 纹理,应用于一个表面,或者作为一个反射或折射贴图。
textureLoader = new THREE.TextureLoader();
map = textureLoader.load('snow2.jpg');
// 传入纹理,得到材料
material = new THREE.SpriteMaterial({map: map});
for ( i = 0; i < amount; i ++ ){
// 精灵平面
var particle = new THREE.Sprite( material );
var randomScale = randomRange(20,40)
particle.position.x = randomRange(-1000, 800);
particle.position.y = randomRange(-1000, 1200);
particle.position.z = randomRange(-1000, 1000);
particle.scale.x = particle.scale.y = particle.scale.z = randomScale;
particle.v = new THREE.Vector3(0, -fallSpeen, 0);
particle.v.z = (1 * randomRange(-1, 1));
particle.v.x = (1 * randomRange(-1, 1));
particles.push(particle);
scene.add( particle );
}
renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// renderer.domElement 就是canvas
container.appendChild(renderer.domElement);
animate();
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
for(var i = 0; i < particles.length; i++){
var particle = particles[i];
var pp = particle.position;
pp.add(particle.v);
// 调整位置,从左边出去的,从右边回来
if(pp.y < -1000) pp.y = 1000;
if(pp.x > 1000) pp.x = -1000;
else if(pp.x < -1000) pp.x = 1000;
if(pp.z > 1000) pp.z=-1000;
else if(pp.z < -1000) pp.z = 1000;
}
// 重新渲染
renderer.render( scene, camera );
}
init()
</script>
</body>
</html>
最后附上几个链接:
three.js 中文文档
three.js Github
three.js 实例效果
网友评论