three打造一个三维图片粒子分解转场效果幻灯片
代码语言:html
所属分类:幻灯片
代码描述:three打造一个三维图片粒子分解转场效果幻灯片
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <style> body { margin: 0; width: 100%; height: 100%; } canvas { display: block; cursor: pointer; } </style> </head> <body translate="no"> <canvas id="canvas"></canvas> <p class="collection"> </p> <script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/gsap.3.3.1.js"></script> <script type="module"> import { BufferGeometry, Color, DoubleSide, Face3, Geometry, InstancedBufferAttribute, InstancedMesh, MathUtils, MeshBasicMaterial, Object3D, PerspectiveCamera, Scene, TextureLoader, Vector2, Vector3, WebGLRenderer } from 'https://unpkg.com/three@0.119.0/build/three.module.js'; function App() { const conf = { size: 10, images: [ { src: 'http://repo.bfw.wiki/bfwrepo/image/5e0c6f2cae508.png' }, { src: 'http://repo.bfw.wiki/bfwrepo/image/5e0c6f962a0d0.png' }, ] }; let renderer, scene, camera, cameraCtrl; const screen = { width: 0, height: 0, wWidth: 0, wHeight: 0, ratio: 0 }; const loader = new TextureLoader(); const textures = []; let planes, plane1, plane2; let progress = 0,targetProgress = 0; const mouse = new Vector2(); init(); function init() { renderer = new WebGLRenderer({ canvas: document.getElementById('canvas'), antialias: true }); camera = new PerspectiveCamera(50); camera.position.z = 150; updateSize(); window.addEventListener('resize', onResize); Promise.all(conf.images.map(loadTexture)).then(responses => { initScene(); initListeners(); gsap.fromTo(plane1.uProgress, { value: -2 }, { value: 0, duration: 2.5, ease: Power4.easeOut }); requestAnimationFrame(animate); }); } function initScene() { scene = new Scene(); scene.background = new Color(0); plane1 = new AnimatedPlane({ renderer, screen, size: conf.size, anim: 1, texture: textures[0] }); plane2 = new AnimatedPlane({ renderer, screen, size: conf.size, anim: 2, texture: textures[1] }); setPlanesProgress(0); planes = new Object3D(); planes.add(plane1.o3d); planes.add(plane2.o3d); scene.add(planes); } function initListeners() { document.addEventListener('mousemove', e => { mouse.x = e.clientX / screen.width * 2 - 1; mouse.y = -(e.clientY / screen.height) * 2 + 1; }); window.addEventListener('wheel', e => { e.preventDefault(); if (e.deltaY > 0) { targetProgress = limit(targetProgress + 1 / 20, 0, conf.images.length - 1); } else { targetProgress = limit(targetProgress - 1 / 20, 0, conf.images.length - 1); } }); document.addEventListener('click', e => { if (e.clientY < screen.height / 2) { navPrevious(); } else { navNext(); } }); document.addEventListener('keyup', e => { if (e.keyCode === 37 || e.keyCode === 38) { navPrevious(); } else if (e.keyCode === 39 || e.keyCode === 40) { navNext(); } }); } function navNext() { if (Number.isInteger(targetProgress)) targetProgress += 1;else targetProgress = Math.ceil(targetProgress); targetProgress = limit(targetProgress, 0, conf.images.length - 1); } function navPrevious() { if (Number.isInteger(targetProgress)) targetProgress -= 1;else targetProgress = Math.floor(targetProgress); targetProgress = limit(targetProgress, 0, conf.images.length - 1); } function updateProgress() { const progress1 = lerp(progress, targetProgress, 0.1); const pdiff = progress1 - progress; if (pdiff === 0) return; const p0 = progress % 1; const p1 = progress1 % 1; if (pdiff > 0 && p1 < p0 || pdiff < 0 && p0 < p1) { const i = Math.floor(progress1); plane1.setTexture(textures[i]); plane2.setTexture(textures[i + 1]); } progress = progress1; setPlanesProgress(progress % 1); } function setPlanesProgress(progress) { plane1.uProgress.value = progress; plane2.uProgress.value = -1 + progress; plane1.material.opacity = 1 - progress; plane2.material.opacity = progress; plane1.o3d.position.z = progress; plane2.o3d.position.z = progress - 1; } function animate() { requestAnimationFrame(animate); updateProgress(); const tiltX = lerp(planes.rotation.x, -mouse.y * 0.2, 0.1); const tiltY = lerp(planes.rotation.y, mouse.x * 0.2, 0.1); planes.rotation.set(tiltX, tiltY, 0); renderer.render(scene, camera); } let resizeTimeout; function onResize() { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(updateSize, 200); } function updateSize() { screen.width = window.innerWidth; screen.height = window.innerHeight; screen.ratio = screen.width / screen.height; if (renderer && camera) { renderer.setSize(screen.width, screen.height); camera.aspect = screen.ratio; camera.updateProjectionMatrix(); const wsize = getRendererSize(); screen.wWidth = wsize[0];screen.wHeight = wsize[1]; } if (plane1) plane1.resize(); if (plane2) plane2.resize(); } function getRendererSize() { const vFOV = camera.fov * Math.PI / 180; const h = 2 * Math.tan(vFOV / 2) * Math.abs(camera.position.z); const w = h * camera.aspect; return [w, h]; } function loadTexture(img, index) { return new Promise(resolve => { loader.load( img.src, texture => { textures[index] = texture; resolve(texture); }); .........完整代码请登录后点击上方下载按钮下载查看
网友评论0