gsap+three实现鼠标滚动tab切换丝带跟随扭动动画背景效果代码
代码语言:html
所属分类:选项卡
代码描述:gsap+three实现鼠标滚动tab切换丝带跟随扭动动画背景效果代码,顶部指示条显示当前tab位置,通过点击或滚动鼠标切换tab更换纽带。
代码标签: gsap three 鼠标 滚动 tab 切换 丝带 跟随 扭动 动画 背景
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> :root { --c0: white; --c8: #494942; --c9: #31312c; --c10: #181816; --c11: black; --filter-01:url(#turbulence-effect); } ::-webkit-scrollbar { width: 8px; height: 3px; background-color: var(--c11); } ::-webkit-scrollbar-thumb { height: 50px; background-color: var(--c0); border-radius: 0px; } ::-webkit-scrollbar-button { background-color: var(--c8); display: none; } ::-webkit-scrollbar-track { background-color: var(--c8); } ::-webkit-scrollbar-track-piece { background-color: var(--c8); } ::-webkit-scrollbar-corner { background-color: var(--c9); } ::-webkit-resizer { background-color: var(--c9); } * { box-sizing: border-box; font-family: sans-serif; } html, body { height: 100%; width: 100%; margin: 0; padding: 0; user-select:none; } body { margin: 0; overflow-x: hidden; background: #000; } a { color:#fff; text-decoration:none; font-size : 12px; font-weight:bold; } nav { position:absolute; z-index:6; top:30rem; } menu{ position: fixed; top: 1rem; left: 0; width: 100%; text-align: center; z-index: 1000; } menu ul{ list-style-type: none; display: inline-flex; justify-content: center; } menu ul li{ display: inline; margin:.3rem; padding:.7rem 1rem; border-radius: .4rem; background : rgba(0,0,0,0.5); } #underline { position: fixed; top: 0; height: 6px; background: white; border-bottom: solid 1px #f00; width: 0; transform-origin: left center; pointer-events: none; transition: width 0.3s ease, left 0.3s ease; } .scrollTarget { position: absolute; height: 600%; /* Adjusted to match the number of sections */ width: 100%; top: 0; z-index: 0; } .experience { display: block; position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; } main { position: relative; width: 100%; height: 100%; z-index: 3; } section.panel { padding-top: 60px; position: relative; display: block; width: 100%; height: 100vh; /* Ensure each section takes the full viewport height */ border-bottom: solid 1px rgba(255,255,255,0.1); z-index: 4; } .panel p { font-size: 16px; color: #fff; padding: 10vw; } </style> </head> <body> <nav> <menu> <ul> <li><a href="#section-1">Section 1</a></li> <li><a href="#section-2">Section 2</a></li> <li><a href="#section-3">Section 3</a></li> <li><a href="#section-4">Section 4</a></li> <li><a href="#section-5">Section 5</a></li> <li><a href="#section-6">Section 6</a></li> </ul> </menu> <div id="underline"></div> </nav> <main> <section class="panel" id="section-1"><p>Section 1</p></section> <section class="panel" id="section-2"><p>Section 2</p></section> <section class="panel" id="section-3"><p>Section 3</p></section> <section class="panel" id="section-4"><p>Section 4</p></section> <section class="panel" id="section-5"><p>Section 5</p></section> <section class="panel" id="section-6"><p>Section 6</p></section> </main> <div class="scrollTarget"></div> <canvas class="experience"></canvas> <script type="importmap"> { "imports": { "three": "//repo.bfw.wiki/bfwrepo/js/module/three/build/164/three.module.js", "three/addons/": "//repo.bfw.wiki/bfwrepo/js/module/three/examples/164/jsm/" } } </script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.12.2.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/ScrollTrigger.3.12.5.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/ScrollToPlugin3.min.js"></script> <script type="module"> import * as THREE from 'three'; import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; import { TextGeometry } from 'three/addons/geometries/TextGeometry.js'; import { FontLoader } from 'three/addons/loaders/FontLoader.js'; import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; import { RenderPass } from 'three/addons/postprocessing/RenderPass.js'; import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js'; import { UnrealBloomPass } from 'three/addons/postprocessing/UnrealBloomPass.js'; import { GlitchPass } from 'three/addons/postprocessing/GlitchPass.js'; gsap.registerPlugin(ScrollTrigger); gsap.registerPlugin(ScrollToPlugin); document.addEventListener("DOMContentLoaded", function() { const menuLinks = document.querySelectorAll('menu ul li a'); const underline = document.getElementById('underline'); function updateUnderline(target) { const linkRect = target.getBoundingClientRect(); const menuRect = target.closest('menu').getBoundingClientRect(); gsap.to(underline, { duration: 0.3, width: linkRect.width, left: linkRect.left - menuRect.left, ease: "power3.out" }); } menuLinks.forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const targetId = this.getAttribute('href'); gsap.to(window, { duration: 1, scrollTo: targetId, onComplete: () => { updateUnderline(this); } }); }); }); // Update underline on scroll window.addEventListener('scroll', function() { const fromTop = window.scrollY + 60; // 60 to account for the fixed nav height menuLinks.forEach(link => { const section = document.querySelector(link.getAttribute('href')); if ( section.offsetTop <= fromTop && section.offsetTop + section.offsetHeight > fromTop ) { updateUnderline(link); } }); }); // Initialize underline position if (menuLinks.length > 0) { updateUnderline(menuLinks[0]); } }); const scene = new THREE.Scene(); scene.fog = new THREE.Fog(0x000000, -800, 800); const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); const renderer = new THREE.WebGLRenderer({ antialias: true, canvas: document.querySelector('.experience'), shadowMapEnabled: true, shadowMapType: THREE.PCFSoftShadowMap }); renderer.setSize(window.innerWidth, window.innerHeight); const points = [ new THREE.Vector3(0, 0, 0), new THREE.Vector3(5, -5, 100), new THREE.Vector3(20, 0, 200), new THREE.Vector3(30, -10, 300), new THREE.Vector3(0, 0, 400), new THREE.Vector3(5, 5, 500), new THREE.Vector3(-5, 5, 600), new THREE.Vector3(5, -5, 700), ]; const path = new THREE.CatmullRomCurve3(points); const initialPoint = path.getPointAt(0); const initialLookAtPoint = path.getPointAt(0.01); camera.position.copy(initialPoint); camera.lookAt(initialLookAtPoint); let composer, params = { exposure: .3, bloomStrength: .7, bloomThreshold: 0, bloomRadius: 0 }; const renderScene = new RenderPass(scene, camera); // --------------- // bloomPass, noisePass, scanLinePass // --------------- const bloomPass = new UnrealBloomPass(new THREE.Vector2(window.innerWidth, window.innerHeight), 1.5, 0.4, 0.85); bloomPass.renderToScreen = true; bloomPass.threshold = params.bloomThreshold; bloomPass.strength = params.bloomStrength; bloomPass.radius = params.bloomRadius; composer = new EffectComposer(renderer); composer.setSize(window.innerWidth, window.innerHeight); composer.addPass(renderScene); composer.addPass(bloomPass); let noisePass; const noiseShader = { uniforms: { 'tDiffuse': { value: null }, 'amount': { value: 0.05 } }, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` uniform sampler2D tDiffuse; uniform float amount; varying vec2 vUv; float rand(vec2 co) { return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); } void main() { vec4 color = texture2D(tDiffuse, vUv); float noise = rand(gl_FragCoord.xy) * amount; gl_FragColor = vec4(color.rgb + noise, color.a); } ` }; noisePass = new ShaderPass(noiseShader); composer.addPass(noisePass); const scanLinePass = new ShaderPass({ uniforms: { "tDiffuse": { value: null }, "time": { value: 0.0 }, "lineHeight": { value: 4.0 }, "lineSpacing": { value: 2.0 }, "opacity": { value: 0.1 } }, vertexShader: ` varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); } `, fragmentShader: ` uniform sampler2D tDiffuse; uniform float time; uniform float lineHeight; uniform float lineSpacing; uniform float opacity; varying vec2 vUv; void main() { vec4 color = texture2D(tDiffuse, vUv); float scanline = step(lineSpacing, mod(gl_FragCoord.y, lineHeight)) * opacity; color.rgb += scanline; gl_FragColor = color; } `, blending: THREE.AdditiveBlending }); composer.addPass(scanLinePass); // --------------- // shaderMat.........完整代码请登录后点击上方下载按钮下载查看
网友评论0