UNPKG

uix-kit

Version:

A free web kits for fast web design and development, compatible with Bootstrap v5.

372 lines (232 loc) 9.49 kB
/* ************************************* * <!-- 3D Background 1 with three.js --> ************************************* */ import { UixModuleInstance, } from '@uixkit/core/_global/js'; import ShaderRuntime from '@uixkit/plugins/THREE/esm/extensions/ShaderRuntime.custom'; export const THREE_BACKGROUND_THREE = ( ( module, $, window, document ) => { if ( window.THREE_BACKGROUND_THREE === null ) return false; module.THREE_BACKGROUND_THREE = module.THREE_BACKGROUND_THREE || {}; module.THREE_BACKGROUND_THREE.version = '0.0.9'; // via threejs 151 module.THREE_BACKGROUND_THREE.documentReady = function( $ ) { //Prevent this module from loading in other pages if ( $( '#3D-background-three-canvas' ).length == 0 || ! Modernizr.webgl ) return false; let sceneSubjects = []; // Import objects and animations dynamically const MainStage = function() { let windowWidth = window.innerWidth, windowHeight = window.innerHeight; const rendererCanvasID = '3D-background-three-canvas'; // Generate one plane geometries mesh to scene //------------------------------------- let camera, scene, light, renderer, displacementSprite, shaderSprite, clock = new THREE.Clock(); // controls let spriteAnim = false; let mouseX = 0, mouseY = 0, windowHalfX = windowWidth / 2, windowHalfY = windowHeight / 2; let targetX = 0.0, targetY = 0.0, angle = 0.0, height = 0.0, target = new THREE.Vector3(); // Load multiple ShaderFrog shaders const runtime = new ShaderRuntime(); runtime.load([ $( '#' + rendererCanvasID ).data( 'shader-url' ) ], function( shaders ) { // Get the Three.js material you can assign to your objects const material = runtime.get( shaders[0].name ); shaderSprite.material = material; }); function init() { //camera camera = new THREE.PerspectiveCamera( 60, windowWidth / windowHeight, 100, 2000000 ); camera.position.set( 0, 100, 2000 ); runtime.registerCamera( camera ); //Scene scene = new THREE.Scene(); //HemisphereLight scene.add( new THREE.AmbientLight( 0x555555 ) ); light = new THREE.SpotLight( 0xffffff, 1.5 ); light.position.set( 0, 500, 2000 ); light.decay = 0; // !!!Important scene.add( light ); //WebGL Renderer renderer = new THREE.WebGLRenderer( { canvas : document.getElementById( rendererCanvasID ), //canvas alpha : true, antialias: true } ); renderer.setSize( windowWidth, windowHeight ); //Add shader background const geometry = new THREE.SphereGeometry(5, 32, 32, 0, Math.PI * 2, 0, Math.PI * 2); shaderSprite = new THREE.Mesh( geometry ); shaderSprite.scale.setScalar( 10000 ); shaderSprite.renderDepth = 0; scene.add( shaderSprite ); // Immediately use the texture for material creation const defaultMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true, vertexColors: true } ); displacementSprite = generateGeometry( 'sphere', 200, defaultMaterial); scene.add( displacementSprite ); // Fires when the window changes window.addEventListener( 'resize', onWindowResize, false ); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); document.addEventListener( 'mousedown', onDocumentMouseDown, false ); document.addEventListener( 'mouseup', onDocumentMouseUp, false ); } function render() { requestAnimationFrame( render ); const objVector = new THREE.Vector3(0,0.2,0.1), delta = clock.getDelta(); if ( ! spriteAnim ) { displacementSprite.rotation.x += delta * objVector.x; displacementSprite.rotation.y += delta * objVector.y; displacementSprite.rotation.z += delta * objVector.z; } //To set a background color. renderer.setClearColor( 0x000000 ); //update shaders runtime.updateShaders( clock.getElapsedTime() ); // update camera targetX = mouseX * .002; targetY = mouseY * .002; angle += 0.01 * ( targetX - angle ); height += 0.01 * ( targetY - height ); const x = -Math.sin( angle * 1.5 ) * 35; const z = Math.cos( angle * 1.5 ) * 35; const y = 130 * height + 0; camera.position.set( x, y, z ); camera.lookAt( target ); //push objects /* @Usage: function CustomObj( scene ) { const elements = new THREE...; scene.add( elements ); this.update = function( time ) { elements.rotation.y = time*0.003; } } sceneSubjects.push( new CustomObj( MainStage.getScene() ) ); */ for( let i = 0; i < sceneSubjects.length; i++ ) { sceneSubjects[i].update( clock.getElapsedTime()*1 ); } //render the scene to display our scene through the camera's eye. renderer.render( scene, camera ); } function onWindowResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize( window.innerWidth, window.innerHeight ); } function onDocumentMouseMove( event ) { mouseX = event.clientX - windowHalfX; mouseY = event.clientY - windowHalfY; } function onDocumentMouseDown( event ) { event.preventDefault(); spriteAnim = true; mouseX = event.clientX - windowHalfX; mouseY = event.clientY - windowHalfY; } function onDocumentMouseUp( event ) { event.preventDefault(); spriteAnim = false; mouseX = event.clientX - windowHalfX; mouseY = event.clientY - windowHalfY; } /* * Batch generation of geometry * * @param {String} objectType - String of geometry type identifier. * @param {Number} numObjects - The total number of generated objects. * @param {THREE.Material} customMaterial - The Material. * @return {Void} */ function generateGeometry( objectType, numObjects, customMaterial ) { const group = new THREE.Group(); const applyVertexColors = function(geometry, color) { // Creates an array of vertex colors const positions = geometry.attributes.position; const colors = new Float32Array(positions.count * 3); for (let i = 0; i < positions.count; i++) { colors[i * 3] = color.r; colors[i * 3 + 1] = color.g; colors[i * 3 + 2] = color.b; } geometry.setAttribute('color', new THREE.BufferAttribute(colors, 3)); }; for ( let i = 0; i < numObjects; i ++ ) { const position = new THREE.Vector3(); position.x = Math.random() * 10000 - 5000; position.y = Math.random() * 6000 - 3000; position.z = Math.random() * 8000 - 4000; const rotation = new THREE.Euler(); rotation.x = Math.random() * 2 * Math.PI; rotation.y = Math.random() * 2 * Math.PI; rotation.z = Math.random() * 2 * Math.PI; const scale = new THREE.Vector3(); scale.x = Math.random() * 200 + 100; let geom; const color = new THREE.Color(); if ( objectType == "cube" ) { geom = new THREE.BoxGeometry( 1, 1, 1 ); scale.y = Math.random() * 200 + 100; scale.z = Math.random() * 200 + 100; color.setRGB( 0, 0, Math.random() + 0.1 ); } else if ( objectType == "sphere" ) { geom = new THREE.IcosahedronGeometry( 1, 1 ); scale.y = scale.z = scale.x; color.setRGB( 0.35, getRandomFloat( 0.12, 0.3 ), 0.2 ); } else if ( objectType == "poly" ) { geom = new THREE.CylinderGeometry( 3, 6, 3, 5, 1 ); scale.y = Math.random() * 30; scale.z = Math.random() * 30; color.setRGB( Math.random() + 0.1, 0, 0 ); } // give the geom's vertices a random color, to be displayed applyVertexColors( geom, color ); const object = new THREE.Mesh( geom, customMaterial ); object.position.copy( position ); object.rotation.copy( rotation ); object.scale.copy( scale ); object.updateMatrix(); // Updates the local transform. group.add( object ); } return group; } //Generate random number between two numbers function getRandomFloat(min, max) { return Math.random() * (max - min) + min; } // //------------------------------------- return { init : init, render : render, getRendererCanvasID : function () { return rendererCanvasID; }, getScene : function () { return scene; }, getCamera : function () { return camera; } }; }(); MainStage.init(); MainStage.render(); }; module.components.documentReady.push( module.THREE_BACKGROUND_THREE.documentReady ); return class THREE_BACKGROUND_THREE { constructor() { this.module = module; } }; })( UixModuleInstance, jQuery, window, document );