three打造一个聚光灯下的三维画展展厅动态效果代码
代码语言:html
所属分类:三维
代码描述:three打造一个聚光灯下的三维画展展厅动态效果代码,点击按钮可实现开灯关灯不同效果
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <link href="https://fonts.googleapis.com/css2?family=Rajdhani&display=swap" rel="stylesheet"> <style> body { height: 100vh; width: 100%; margin: 0; overflow: hidden; background-color: #79838b; display: flex; flex-flow: column; position: relative; } .bg { position: relative; width: 100%; height: 100vh; max-height: 500px; background-image: url("//repo.bfw.wiki/bfwrepo/image/5f88dabb9e9a2.png"); background-size: contain; background-repeat: repeat-x; background-position: 50% 50%; } .pngLights { position: absolute; z-index: 8; width: 100%; height: 100vh; max-height: 500px; background-image: url("//repo.bfw.wiki/bfwrepo/image/5f88dacb2c662.png"), url("//repo.bfw.wiki/bfwrepo/image/5f88daa17dbde.png"), url("//repo.bfw.wiki/bfwrepo/image/5f88daa17dbde.png"); background-size: contain; background-repeat: no-repeat; background-position: 50% -22px; } .pngLights.active { background-image: url("//repo.bfw.wiki/bfwrepo/image/5f88dacb2c662.png"), url("//repo.bfw.wiki/bfwrepo/image/5f88daa17dbde.png"), url(""); } .cc { width: 100%; height: 100vh; position: absolute; top: 0; left: 0; } #canvas_container1 { max-height: 500px; z-index: 1; } #canvas_container2 { height: 100vh; z-index: 2; } .floor { flex: 1 1 auto; background-image: url("//repo.bfw.wiki/bfwrepo/image/5f88da81bd562.png"); background-size: cover; background-repeat: no-repeat; background-position: 50% 0%; } /**** Buttons *****/ .buttons { position: absolute; width: 100%; height: 100vh; max-height: 500px; } .btn { position: absolute; bottom: 5%; z-index: 10; border: 1px solid white; border-radius: 5px; padding: 3px 15px; background-color: #1f1f1f; color: #fdfcfc; -webkit-font-smoothing: antialiased; font-size: 18px; font-family: 'Rajdhani', sans-serif; letter-spacing: 1px; cursor: pointer; user-select: none; box-shadow: 5px 3px 12px 0px rgba(0, 0, 0, 0.75); transition: color .3s; } .btn_Works { left: 5%; text-decoration: none; } .btn_Light { left: 50%; transform: translateX(-50%); transform-origin: 25% 50%; color: #feaeae; } .btn_Works:hover { background-color: #3d3d3d; color: #6286f4; } .btn_Light:hover { background-color: #3d3d3d; color: #da1616; } .btn_Light.blink { animation: blinkAni 500ms; } @keyframes blinkAni { 0% { background: #f5f6e4; transform: scale(1) translateX(-50%); } 50% { transform: scale(1.2) translateX(-50%); } 100% { transform: scale(1) translateX(-50%); } } @media only screen and (max-height: 350px) { .btn { font-size: 4.5vh; bottom: 2%; box-shadow: none; color: #fdfcfc; } } </style> </head> <body translate="no" > <div class="cc" id="canvas_container1"></div> <div class="cc" id="canvas_container2"></div> <div class="pngLights"></div> <div class="bg"></div> <div class="buttons"> <div class="btn btn_Light">Light OFF</div> </div> <div class="floor"></div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.121.js"></script> <script > let camera, renderer1, scene, uniformsBlob, uniformsPano, container1 = document.getElementById("canvas_container1"), bg = document.querySelector(".bg"), floor = document.querySelector(".floor"), btn_Light = document.querySelector(".btn_Light"), timeout_Debounce, lightOFF = true, renderer2, camera2, scene2, sprites = new THREE.Group(), container2 = document.getElementById("canvas_container2"), mouse = { x: 1 }; init(); animate(); function init() { renderer1 = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer1.setSize(container1.clientWidth, container1.clientHeight); renderer1.setPixelRatio(window.devicePixelRatio); container1.appendChild(renderer1.domElement); scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, container1.clientWidth / container1.clientHeight, 0.1, 1000); camera.position.set(0, 0, 40); const light1 = new THREE.DirectionalLight("#ffffff", 0.7); light1.position.set(-10, 30, 20); scene.add(light1); const light2 = new THREE.DirectionalLight("#ffffff", 0.7); light2.position.set(10, 30, 20); scene.add(light2); const light3 = new THREE.DirectionalLight("#fcfcfc", 0.3); light3.position.set(0, -20, 10); scene.add(light3); const textureLoader = new THREE.TextureLoader(); const blobTexture = textureLoader.load("//repo.bfw.wiki/bfwrepo/image/5f88dbb5ecffc.png"); const panoTexture = textureLoader.load("//repo.bfw.wiki/bfwrepo/image/5f88dbeb95c03.png"); /*** Blob ***/ let blobGeometry = new THREE.IcosahedronBufferGeometry(10, 50); uniformsBlob = THREE.UniformsUtils.merge([uniformsBlob, THREE.UniformsLib["lights"]]); Object.assign(uniformsBlob, { t_texture: { type: "t", value: blobTexture }, u_time: { type: "f", value: 0.0 }, u_mouse1: { type: "v2", value: new THREE.Vector2(1, 1) }, u_mouse2: { type: "v2", value: new THREE.Vector2(20, 20) }, u_lightOFF: { type: "b", value: lightOFF }, u_effect_Switch: { type: "f", value: 0.0 }, u_textura_Zoom: { type: "f", value: 1.0 } }); uniformsBlob.t_texture.value.anisotropy = 16; uniformsBlob.t_texture.value.wrapS = THREE.MirroredRepeatWrapping; uniformsBlob.t_texture.value.wrapT = THREE.ClampToEdgeWrapping; let shaderMaterialBlob = new THREE.ShaderMaterial({ uniforms: uniformsBlob, fragmentShader: blobFragmentShader(), vertexShader: blobVertexShader(), lights: true }); blob = new THREE.Mesh(blobGeometry, shaderMaterialBlob); blob.position.set(2, -2.2, 10); scene.add(blob); /*** Pano ****/ let panoGeometry = new THREE.PlaneBufferGeometry(54.5, 27.3); uniformsPano = { t_texture: { type: "t", value: panoTexture }, u_resolution: { type: "v2", value: new THREE.Vector2() }, u_time: { type: 'f', value: 0 }, u_mouse: { type: "v2", value: new THREE.Vector2() }, u_lightOFF: { type: "b", value: lightOFF }, u_randomColor: { type: "v3", value: new THREE.Vector3(0.2, 0.2, 0.2) }, u_panoScale: { type: "v2", value: new THREE.Vector2(10.1, 0.2) } }; uniformsPano.u_resolution.value.x = renderer1.domElement.width; uniformsPano.u_resolution.value.y = renderer1.domElement.height; uniformsPano.t_texture.value.wrapS = THREE.ClampToEdgeWrapping; uniformsPano.t_texture.value.wrapT = THREE.ClampToEdgeWrapping; let shaderMaterialPano = new THREE.ShaderMaterial({ uniforms: uniformsPano, fragmentShader: panoFragmentShader(), vertexShader: panoVertexShader() }); pano = new THREE.Mesh(panoGeometry, shaderMaterialPano); pano.position.set(0.5, -1.6, 10); scene.add(pano); /* Mouse Event Handler */ function norm(val, max, min) {return (val - min) / (max - min);} window.addEventListener("mousemove", e => { mouse.x = e.x; let x = norm(-(container1.clientWidth / 2 - e.x), container1.clientWidth / 2, 0) + 0.999; if (x > 0) uniformsBlob.u_mouse1.value.x = x - 1;else uniformsBlob.u_mouse1.value.x = x + 1; uniformsBlob.u_mouse1.value.y = norm(container1.clientHeight / 2 - e.y, container1.clientHeight / 2, 0); uniformsBlob.u_mouse2.value.x = norm(e.x, container1.clientWidth, 0) + 0.5; uniformsPano.u_mouse.value.x = uniformsBlob.u_mouse2.value.x - 0.5; uniformsPano.u_mouse.value.y = uniformsBlob.u_mouse1.value.y; }); /* CANVAS 2 Particles */ let spriteSet = function () { let h = window.innerHeight; renderer2 = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer2.setSize(window.innerWidth, h); renderer2.setPixelRatio(window.devicePixelRatio); container2.appendChild(renderer2.domElement); scene2 = new THREE.Scene(); //better to do this dynamically camera2 = new THREE.PerspectiveCamera(75, window.innerWidth / h, 0.1, 1000); camera2.position.set(0, 0, 40); if (h <= 500) camera2.position.set(0, 0, 40);else if (h > 500 && h <= 600) camera2.position.set(0, -3, 50);else if (h > 600 && h <= 700) camera2.position.set(0, -12, 60);else if (h > 700 && h <= 800) camera2.position.set(0, -18, 60);else if (h > 800 && h <= 900) camera2.position.set(0, -25, 60);else camera2.position.set(0, -28, 60); for (var i = 0; i < 1000; i++) { spriteMaterial = new THREE.SpriteMaterial({ transparent: true, opacity: 0.8 }); let sprite = new THREE.Sprite(spriteMaterial); sprite.position.set( THREE.MathUtils.randFloat(-40, 40), //x THREE.MathUtils.randFloat(-22, 17), //y THREE.MathUtils.randFloat(-1, -6) //z ); sprite.scale.set(0.8, 0.8); //can't do in shader because is difference renderer from pano if (sprite.position.y > 12 && sprite.position.y <= 17) spriteMaterial.color.set("#F9BE6E");else if (sprite.position.y > 8 && sprite.position.y <= 12) spriteMaterial.color.set("#F9DA8A");else if (sprite.position.y > 3 && sprite.position.y <= 8) spriteMaterial.color.set("#E29A50");else if (sprite.position.y > 0 && sprite.position.y <= 3) spriteMaterial.color.set("#7A5437");else if (sprite.position.y > -11 && sprite.position.y <= 0) spriteMaterial.color.set("#1B5A7D");else if (sprite.position.y > -16 && sprite.position.y <= -11) spriteMaterial.color.set("#038BA5");else if (sprite.position.y >= -22 && sprite.position.y <= -16) spriteMaterial.color.set("#CCD79F"); sprite.velocity = { x: (Math.random() - 0.5) / 6, z: -0.1 - Math.random() / 4 }; sprites.add(sprite); } scene2.add(sprites); spriteSet = function () {}; }; btn_Light.addEventListener("click", e => { if (lightOFF) { sprites.visible = true; bg.style.webkitFilter = "brightness(25%)"; floor.style.webkitFilter = "brightness(25%)"; btn_Light.innerHTML = "Light ON"; lightOFF = false; btn_Light.style.color = "#3ef93e"; uniformsPano.u_lightOFF.value = false; uniformsBlob.u_lightOFF.value = false; spriteSet(); uniformsPano.u_panoScale.value.x = 80; uniformsPano.u_panoScale.v.........完整代码请登录后点击上方下载按钮下载查看
网友评论0