preface

When I visited the forum before, I saw a shared article using three.js to realize particle model switching animation. The specific effects are as follows:

You can also preview it.

But the author did not share the source code, just recently in the study of Threejs, just took the time to write a similar demo, hoping to help some like Threejs beginners. The effect is as follows:

Next, let’s look at how to implement such a particle system switch animation.

Access model

In order to realize the first step in a 3 d animation is designed in the scene 3 d models, and we are doing 3 d particle model switching animation, it will take to transform into a 3 d model we need particle model, however, I’m just a front-end development, modeling, so had to steal other people’s work achievement, propaganda page, Open debugging panel-network-XHR, click F5 to refresh the page, and get the 3D particle model we need:

Save the obtained JSON file locally.

Implementation approach

Threejs initialization work

First, initialize threejs three elements: scene, camera, and renderer. We need a carrier particle system for switching and multiple environment particle systems (for simplicity, I just initialized one environment particle system that rotated up and down). The number of particles in the vector system is larger than the maximum number of vertices in all the models, so that when you switch to each model, you don’t have any missing points, and the extra points just overlap from the beginning.

Initialization code:

Container = document.createElement('div'); document.body.appendChild(container); // PerspectiveCamera = new THREE.PerspectiveCamera(105, window.innerwidth/window.innerheight, 10, 10000); camera.position.z = 100; // Initialize scene scene = new three.scene (); Scene.Fog = new THREE.FogExp2(0x000000, 0.001); Renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); container.appendChild(renderer.domElement); // Initialize the geometry = new THREE.Geometry(); around = new THREE.Geometry(); Var textureLoader = new three.textureLoader (); textureLoader.crossOrigin =' ';
var mapDot = textureLoader.load('textures/gradient.png'); / / dotCopy the code

Initializing carrier particle system:

// Set of initial transformation pointsfor (let i = 0; i < 10000; i++) {

    var vertex = new THREE.Vector3();
    vertex.x = 800 * Math.random() - 400;
    vertex.y = 800 * Math.random() - 400;
    vertex.z = 800 * Math.random() - 400;

    geometry.vertices.push(vertex);

    geometry.colors.push(new THREE.Color(1, 1, 1));

}
material = new THREE.PointsMaterial({ size: 4, sizeAttenuation: true, color: 0xffffff, transparent: true, opacity: 1, map: mapDot });

material.vertexColors = THREE.VertexColors;
particles = new THREE.Points(geometry, material);
scene.add(particles);
Copy the code

After loading the obtained 3D model through JSONLoader, the geometry object obtained is put into an array GList for model switching:

Load model loadObject:

var loader = new THREE.JSONLoader();
loader.load('obj/game.js'.function (geo, materials) {
    var colors = [];
    for (var i = 0; i < geo.vertices.length; i++) {
        colors.push(new THREE.Color("rgb(255, 255, 255)")) } geo.colors = colors; Geo-.center (); // Adjust geometry's position and size in the scene. geo.normalize(); geo.scale(500, 500, 500) geo.rotateX(Math.PI / 4) geo.rotateY(-Math.PI / 8) glist.push(geo) })Copy the code

Add page event listening

The document / / event listeners. AddEventListener ('mousedown', onDocumentMouseDown, false);
document.addEventListener("mousewheel", onDocumentMouseWheel, false);
document.addEventListener("keydown", onDocumentKeyDown, false);
window.addEventListener('resize', onWindowResize, false);
Copy the code

For event listening, I did the following:

  1. Hold down the mouse and drag to rotate the particle system in the scene.
  2. Scroll the mouse wheel to zoom in or out of the camera.
  3. Display particle model toggle animation when pressing up and down arrow keys on keyboard.

Effect:

Determine the rotation Angle of the model according to the offset of mouse drag, code:

function onDocumentMouseMove(event) {
    geometry.rotateY((event.pageX - mouseX) / 1000 * 2 * Math.PI);
    geometry.rotateX((event.pageY - mouseY) / 500 * 2 * Math.PI);

    event.preventDefault();
    mouseX = event.pageX;
    mouseY = event.pageY;
}
Copy the code

Determine the height of the camera’s Z axis according to the scrolling amount of the scroll wheel to achieve zooming, code:

function onDocumentMouseWheel() {
    camera.position.z += event.deltaY;
}
Copy the code

Determine the key value of the keyboard to determine whether to render the tween animation, code:

function onDocumentKeyDown(event) {
    if (event.which == 40 && objIndex < 4) {
        objIndex++;
        tweenObj(objIndex);
        flag = true;
    } else if (event.which == 38 && objIndex > 0) {
        objIndex--;
        tweenObj(objIndex);
        flag = true; }}Copy the code

Display tween animations using Tweenjs

function tweenObj(index) {
    geometry.vertices.forEach(function (e, i, arr) {
        var length = glist[index].vertices.length;
        var o = glist[index].vertices[i % length];
        new TWEEN.Tween(e).to({
            x: o.x,
            y: o.y,
            z: o.z
        }, 1000).easing(TWEEN.Easing.Exponential.In).delay(1000 * Math.random()).start();
    })
    camera.position.z = 750;
}
Copy the code

Delay a random number within 1000ms in order to make the animation smoother.

Apply colours to a drawing

This is the most important step, and it’s what makes the whole scene move.

function render() {// The initial particle system rotates uniformly about the Y axisif(! Flag) {geometry. RotateY (math.pi / 200)} // The environment particle rotates around. RotateX (math.pi / 1000) //tween updates the particle position tween.update (); // Specify the camera Angle camera.lookat (scene.position); // Randomly transform the vertex color geometry. Colors.function(color) { color.setRGB(Math.random() * 1, Math.random() * 1, Math.random() * 1); }); / / set the geometry of the vertices and color can be updated geometry. VerticesNeedUpdate =true;
    geometry.colorsNeedUpdate = true; Renderer. render(scene, camera); }Copy the code

TWEEN the update () and geometry. VerticesNeedUpdate = true to the switch can be displayed animated particle system.

The source code

Making the address

conclusion

Although threejs is rarely used in day-to-day front-end business development, with the development of webGL and hardware devices, we expect threejs to shine in the webVR space in the future.

Welcome to follow, there will be threejs and wechat small program to share ^^!