three将照片视频进行粒子打碎三维漂浮交互效果代码
代码语言:html
所属分类:粒子
代码描述:three将照片视频进行粒子打碎三维漂浮交互效果代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Lots of Particles</title> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" user-scalable="yes"> <style> * { margin: 0; padding: 0; } body { overflow: hidden; } #bg { height: 100vh; background-color: #2A2B2F; } #wrapper { position: relative; background-color: #161616; font-family: 'Josefin Sans', sans-serif; } #canvas_container { position: absolute; left: 0; top: 0; width: 100%; height: 100vh; z-index: 0; } canvas { display: block; } .text { width: 100%; text-align: center; position: absolute; left: 0; top: -80px; font-weight: 600; z-index: 10; cursor: pointer; color: #F9B31C; background-color: rgba(23, 23, 23, 0.9); padding: 10px 0; font-size: 25px; } .btn { position: absolute; bottom: 5%; right: 0px; transform: translateX(-50%); border: 1px solid white; border-radius: 5px; font-size: 0.9rem; padding: 0.5rem 0.7em; background: #2a2b2f; color: #F9B31C; -webkit-font-smoothing: antialiased; font-weight: bold; cursor: pointer; transition: all .3s; z-index: 11; } .btn_works { left: 100px; right: unset; text-decoration: none; } .btn:hover { background: #ffffff; color: #2a2b2f; } </style> </head> <body> <div id="wrapper"> <div id="bg"></div> <div id="canvas_container"></div> <video id="video" playsinline webkit-playsinline muted loop width="280" height="108" crossorigin="anonymous" src="//repo.bfw.wiki/bfwrepo/video/602efb889f941.mp4" style="display: none;"></video> <p class="text">点击页面查看惊人特效</p> <button class="btn" id="fullscr">全屏查看</button> </div> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.115.js"></script> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/gsap.3.5.2.js"></script> <script> let webgl = {}; let tail = {}; (function initThree() { webgl.container = document.getElementById("canvas_container"); webgl.scene = new THREE.Scene(); webgl.camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10000); webgl.camera.position.z = 180; webgl.renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); webgl.renderer.setSize(webgl.container.clientWidth, webgl.container.clientHeight); webgl.renderer.setPixelRatio(window.devicePixelRatio); webgl.container.appendChild(webgl.renderer.domElement); webgl.clock = new THREE.Clock(true); webgl.phase = "wall"; webgl.loader = new THREE.TextureLoader(); webgl.texture = webgl.loader.load('//repo.bfw.wiki/bfwrepo/image/5fbedf8f5349c.png?x-oss-process=image/auto-orient,1/resize,m_fill,w_450,h_150,/quality,q_90', setup); })(); function setup() { pixelExtraction(); if (webgl.phase == "video") webgl.threshold = -1; initParticles(); initTail(); initRaycaster(); window.addEventListener("resize", () => { clearTimeout(webgl.timeout_Debounce); webgl.timeout_Debounce = setTimeout(resize, 50); }); resize(); webgl.scene.add(webgl.particlesMesh); // ! if (webgl.phase == "wall") { callTOaction(); document.getElementById("wrapper").addEventListener("click", brakeWall, false); startWallAnimation(); } else startVideoParticles(); animate(); } function pixelExtraction() { webgl.texture.minFilter = THREE.LinearFilter; webgl.texture.magFilter = THREE.LinearFilter; webgl.texture.format = THREE.RGBFormat; webgl.width = webgl.texture.image.width; webgl.height = webgl.texture.image.height; webgl.totalPoints = webgl.width * webgl.height; if (webgl.phase == "video") { webgl.visiblePoints = webgl.totalPoints; //console.log('pixelExtraction: visiblePoints', webgl.visiblePoints, webgl.totalPoints); return; } webgl.visiblePoints = 0; webgl.threshold = 60; const img = webgl.texture.image; const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); canvas.width = webgl.width; canvas.height = webgl.height; ctx.scale(1, -1); ctx.drawImage(img, 0, 0, webgl.width, webgl.height * -1); const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); webgl.arrayOfColors = Float32Array.from(imgData.data); for (let i = 0; i < webgl.totalPoints; i++) { if (webgl.arrayOfColors[i * 4 + 0] > webgl.threshold) webgl.visiblePoints++; } //console.log('pixelExtraction: visiblePoints', webgl.visiblePoints, webgl.totalPoints); } function initParticles() { const geometryParticles = new THREE.InstancedBufferGeometry(); const positions = new THREE.BufferAttribute(new Float32Array(4 * 3), 3); positions.setXYZ(0, -0.5, 0.5, 0.0); positions.setXYZ(1, 0.5, 0.5, 0.0); positions.setXYZ(2, -0.5, -0.5, 0.0); positions.setXYZ(3, 0.5, -0.5, 0.0); geometryParticles.setAttribute('position', positions); const uvs = new THREE.BufferAttribute(new Float32Array(4 * 2), 2); uvs.setXYZ(0, 0.0, 0.0); uvs.setXYZ(1, 1.0, 0.0); uvs.setXYZ(2, 0.0, 1.0); uvs.setXYZ(3, 1.0, 1.0); geometryParticles.setAttribute('uv', uvs); geometryParticles.setIndex(new THREE.BufferAttribute(new Uint16Array([0, 2, 1, 2, 3, 1]), 1)); const offsets = new Float32Array(webgl.visiblePoints * 3); const indices = new Uint16Array(webgl.visiblePoints); const angles = new Float32Array(webgl.visiblePoints); for (let i = 0, j = 0; i < webgl.totalPoints; i++) { if (webgl.arrayOfColors[i * 4 + 0] <= webgl.threshold) continue; offsets[j * 3 + 0] = i % webgl.width; offsets[j * 3 + 1] = Math.floor(i / webgl.width); indices[j] = i; angles[j] = Math.random() * Math.PI; j++; } geometryParticles.setAttribute('offset', new THREE.InstancedBufferAttribute(offsets, 3, false)); geometryParticles.setAttribute('angle', new THREE.InstancedBufferAttribute(angles, 1, false)); geometryParticles.setAttribute('pindex', new THREE.InstancedBufferAttribute(indices, 1, false)); const uniforms = { uTime: { value: 0 }, uRandom: { value: 2.0 }, uDepth: { value: 40.0 }, uSize: { value: 2.0 }, uTextureSize: { value: new THREE.Vector2(webgl.width, webgl.height) }, uTexture: { value: webgl.texture }, uTouch: { value: null }, uAlphaCircle: { value: 0.0 }, uAlphaSquare: { value: 1.0 }, uCircleORsquare: { value: 0.0 }, }; const materialParticles = new THREE.RawShaderMaterial({ uniforms: uniforms, vertexShader: vertexShader(), fragmentShader: fragmentShader(), depthTest: false, transparent: true, //side: THREE.DoubleSide, //toneMapped: false, //blending: THREE.AdditiveBlending }); webgl.particlesMesh = new THREE.Mesh(geometryParticles, materialParticles); } function initTail() { tail.array = []; tail.size = 80; tail.maxAge = 120; tail.radius = 0.1; tail.red = 255; tail.canvas = document.createElement('canvas'); tail.canvas.width = tail.canvas.height = tail.size; tail.ctx = tail.canvas.getContext('2d'); tail.ctx.fillStyle = 'black'; tail.ctx.fillRect(0, 0, tail.canvas.width, tail.canvas.height); tail.texture = new THREE.Texture(tail.canvas); webgl.particlesMesh.material.uniforms.uTouch.value = tail.texture; } function initRaycaster() { const geometryPlate = new THREE.PlaneGeometry(webgl.width, webgl.height, 1, 1); const materialPlate = new THREE.MeshBasicMaterial({ color: 0xFFFFFF, wireframe: true, depthTest: false }); materialPlate.visible = false; webgl.hoverPlate = new THREE.Mesh(geometryPlate, materialPlate) webgl.scene.add(webgl.hoverPlate); webgl.raycaster = new THREE.Raycaster(); webgl.mouse = new THREE.Vector2(0, 0); window.addEventListener("mousemove", onMouseMove, false); } function onMouseMove(event) { webgl.mouse.x = (event.clientX / webgl.renderer.domElement.clientWidth) * 2 - 1; webgl.mouse.y = - (event.clientY / webgl.renderer.domElement.clientHeight) * 2 + 1; webgl.raycaster.setFromCamera(webgl.mouse, webgl.camera); let intersects = webgl.raycaster.intersectObjects([webgl.hoverPlate]); if (webgl.phase == "video") { webgl.particlesMesh.rotation.y = webgl.mouse.x / 8; webgl.particlesMesh.rotation.x = -webgl.mouse.y / 8; } if (intersects[0]) buildTail(intersects[0].uv); } function buildTail(uv) { let force = 0; const last = tail.array[tail.array.length - 1]; if (last) { const dx = last.x - uv.x; const dy = last.y - uv.y; const dd = dx * dx + dy * dy; force = Math.min(dd * 10000, 1); } tail.array.push({ x: uv.x, y: uv.y, age: 0, force }); } function callTOaction() { timeout = window.setTimeout(() => { if (webgl.phase == "wall") { gsap.to(document.querySelector(".text"), 1.5, { css: { top: 0 .........完整代码请登录后点击上方下载按钮下载查看
网友评论0