「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战」
背景
最近写了一些关于threejs
的文章,大家很感兴趣,浏览量很高,因为threejs
的可玩性很高,但是对于小白用户操作就没有那么容易上手,毕竟threejs
还是有一定的学习门槛的,为了降低大家对threejs
的学习门槛,也方便大家实现效果,我在这介绍一个超级炫酷的threejs
插件(three.proton.js
)给大家看看,下面是效果:
介绍
three.proton
是一个使用three.js
的神奇 3D 粒子引擎。它基于质子引擎库Proton。它继承了 Proton
最多的 Api
,而且非常简单非常好用。
文档
官网:drawcall.github.io/three.proto…
github:github.com/drawcall/th…
npmjs: www.npmjs.com/package/thr…
实现
因为threejs
更新很快,有些属性有所不一样,所以最好用官网给的版本,这样就不会出现错误了!(或者直接用我给的链接也可以)。
准备
- three.js: drawcall.github.io/three.proto…
- three.proton.js: drawcall.github.io/three.proto…
- stats.js: drawcall.github.io/three.proto…
- TrackballControls.js: drawcall.github.io/three.proto…
- 光的图片,如下:drawcall.github.io/three.proto…
开始
html代码
创造一个容器
<div id="container"></div>
复制代码
css 代码
body {
font-family: Monospace;
background-color: #fff;
margin: 0;
padding: 0;
overflow: hidden;
}
复制代码
引入js 库
<script src="../lib/stats.min.js"></script>
<script src="../lib/three.min.js"></script>
<script src="../build/three.proton.min.js"></script>
<script src="./js/lib/TrackballControls.js"></script>
复制代码
js 代码
- 变量初始化
var proton, emitter;
复制代码
- 创建粒子对象
proton = new Proton();
复制代码
- 创建火焰
function createEmitter() {
emitter = new Proton.Emitter();
emitter.rate = new Proton.Rate(new Proton.Span(10, 15), new Proton.Span(.05, .1));
emitter.addInitialize(new Proton.Body(createSprite()));
emitter.addInitialize(new Proton.Mass(1));
emitter.addInitialize(new Proton.Life(1, 3));
emitter.addInitialize(new Proton.Position(new Proton.SphereZone(20)));
emitter.addInitialize(new Proton.V(new Proton.Span(500, 800), new Proton.Vector3D(0, 1, 0), 30));
emitter.addBehaviour(new Proton.RandomDrift(10, 10, 10, .05));
//emitter.addBehaviour(new Proton.Alpha(1, 0.1));
emitter.addBehaviour(new Proton.Scale(new Proton.Span(2, 3.5), 0));
emitter.addBehaviour(new Proton.G(6));
emitter.addBehaviour(new Proton.Color('#FF0026', ['#ffff00', '#ffff11'], Infinity, Proton.easeOutSine));
emitter.p.x = 0;
emitter.p.y = -150;
emitter.emit();
return emitter;
}
复制代码
- 创建火苗轨迹
function addInteraction() {
window.addEventListener('mousemove', onMouseMove, false);
var pos = {
x: 0,
y: 0
};
function onMouseMove(event) {
pos.x = event.clientX;
pos.y = event.clientY;
var target = Proton.THREEUtil.toSpacePos(pos, camera, renderer.domElement);
emitter.p.x += (target.x - emitter.p.x) / 10;
emitter.p.y += (target.y - emitter.p.y) / 10;
emitter.p.z += (target.z - emitter.p.z) / 10;
}
}
复制代码
- 给火苗贴图
function createSprite() {
var map = new THREE.TextureLoader().load("https://drawcall.github.io/three.proton/engine/example/img/dot.png");
var material = new THREE.SpriteMaterial({
map: map,
color: 0xff0000,
blending: THREE.AdditiveBlending,
fog: true
});
return new THREE.Sprite(material);
}
复制代码
- 渲染火焰
proton.addEmitter(createEmitter());
proton.addRender(new Proton.SpriteRender(scene));
复制代码
- 页面渲染
function render() {
proton.update(clock.getDelta());
renderer.render(scene, camera);
controls.update();
Proton.Debug.renderInfo(proton, 3);
}
复制代码
- 添加动画
function animate() {
stats.begin();
requestAnimationFrame(animate);
render();
stats.end();
}
复制代码
threejs 初始化
- 变量初始化
var camera, scene, renderer, clock, spring, controls;
复制代码
- 新建一个场景
function addScene() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 500;
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xffffff, 1, 10000);
clock = new THREE.Clock();
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
复制代码
- 添加控制器
function addControls() {
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
}
复制代码
- 添加灯光
function addLights() {
var ambientLight = new THREE.AmbientLight(0x101010);
scene.add(ambientLight);
var pointLight = new THREE.PointLight(0xffffff, 2, 1000, 1);
pointLight.position.set(0, 200, 200);
scene.add(pointLight);
}
复制代码
- 性能监控
function addStats() {
stats = new Stats();
stats.showPanel(0);
stats.dom.style.position = 'absolute';
stats.dom.style.left = '0px';
stats.dom.style.top = '0px';
container.appendChild(stats.dom);
}
复制代码
效果
总结
本文写的很简单,有些坑,大家可以去官网上查看,上面有粒子和完整的代码,大家可以直接下载查看,效果很好看,实现也很容易,大家可以自己动手操作一遍。最后谢谢大家的观看!