<aside> ๐Ÿ’ก Description: Dynamic vertices animation based on microphone input.

</aside>

Image from iOS (2).MP4

  1. Add an empty object to the scene:

    sceneWrap.glb

  2. Open Custom Code โ€œ{}โ€

  3. Insert the code:

const startApp = () => {
		// remove dummy cube object
		this.object3D.remove(this.object3D.children[0]);

    let mouse = new this.THREE.Vector2( 0.2, 0.5 );

    let blobGeometry = new this.THREE.IcosahedronGeometry( 1, 10 );
    blobGeometry.setAttribute("basePosition", new this.THREE.BufferAttribute().copy(blobGeometry.attributes.position));
    let blobMaterial = new this.THREE.MeshNormalMaterial();
    const blob = new this.THREE.Mesh( blobGeometry, blobMaterial );

    this.object3D.add(blob);

    const setNewPoints = ( ) => {

            let time = performance.now() * 0.03;

		        const basePositionAttribute = blob.geometry.getAttribute("basePosition");
            const positionAttribute = blob.geometry.getAttribute( 'position' );
            const vertex = new this.THREE.Vector3();

            for ( let vertexIndex = 0; vertexIndex < positionAttribute.count; vertexIndex++ ) {

                vertex.fromBufferAttribute( basePositionAttribute, vertexIndex );

                var perlin = noise.simplex3(
                    vertex.x * 0.6 + time * 0.02,
                    vertex.y * 0.6 + time * 0.03,
                    vertex.z * 0.6 );

                var ratio = perlin * 0.4 * ( mouse.x + 0.1 ) + 0.8;
                vertex.multiplyScalar( ratio );
                
                positionAttribute.setXYZ(vertexIndex, vertex.x, vertex.y, vertex.z);

            }

            blob.geometry.attributes.position.needsUpdate = true; // required after the first render
            blob.geometry.computeBoundingSphere();
    }

    const screenWidth = window.innerWidth;
    document.addEventListener('mousemove', (e) => {
      mouse.x = ((e.clientX / screenWidth) - 0.5) + 0.5;
    })

    const render = () => {
            setNewPoints();
    }

    this.activeSceneModel.userCallbacks.onRender = render;
}

// ==============================

// this function will work cross-browser for loading scripts asynchronously
    const loadScript = (_name, src, callback) => {
        let s;
        let r;
        let t;
        r = false;
        s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = src;
        s.onload = s.onreadystatechange =  ()  => {
            if (!r && (!this.readyState || this.readyState == 'complete')) {
                r = true;
                callback(_name);
            }
        };
        t = document.getElementsByTagName('script')[ 0 ];
        t.parentNode.insertBefore(s, t);
    }

    // After all necessary scripts loaded 
    const onLoadScript = (_name) => {
        if (_name == 'my_script') {
            // do something after script loaded.
            // debugger;
            startApp();
        } 
    }

loadScript('my_script', '<https://www.fariskassim.com/stage/rebel9/teaf/blob/v4/js/perlin.js>', onLoadScript);