three打造3D幕布垂帘撩动交互效果
代码语言:html
所属分类:三维
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Montserrat'> <style> body { margin: 0; height: 100%; font-family: 'Montserrat', sans-serif; background-image: radial-gradient(circle, #ffffff, #aaaaaa); } canvas { position: fixed; top: 0; bottom: 0; z-index: 1; } h1 { font-size: 50px; text-align: center; width: 60%; margin: 0 auto; padding-top: 10%; } p { font-size: 30px; text-align: center; width: 50%; margin: 1em auto 0; } </style> </head> <body translate="no"> <canvas id="canvas"></canvas> <h1>What's behind the curtain ?</h1> <p>This funny interactive curtain is made with ThreeJS, polylines and verlet constraints (adapted from verlet-js).</p> <script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/three.109.js"></script> <script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/chroma.min.js"></script> <script type="text/javascript" src="http://repo.bfw.wiki/bfwrepo/js/verlet-1.0.0.min.js"></script> <script > function App() { const conf = { el: 'canvas', gravity: -0.3, nx: 60, ny: 40, size: 1.5, mouseRadius: 10, mouseStrength: 0.4 }; let renderer, scene, camera; let width, height; const { randFloat: rnd, randFloatSpread: rndFS } = THREE.Math; const mouse = new THREE.Vector2(),oldMouse = new THREE.Vector2(); const verlet = new VerletJS(),polylines = []; const uCx = { value: 0 },uCy = { value: 0 }; init(); function init() { renderer = new THREE.WebGLRenderer({ canvas: document.getElementById(conf.el), antialias: true, alpha: true }); camera = new THREE.PerspectiveCamera(); verlet.width = 256; verlet.height = 256; updateSize(); window.addEventListener('resize', updateSize, false); initScene(); initListeners(); animate(); } function initScene() { scene = new THREE.Scene(); verlet.gravity = new Vec2(0, conf.gravity); initCurtain(); } function initCurtain() { const material = new THREE.ShaderMaterial({ transparent: true, uniforms: { uCx, uCy, uSize: { value: conf.size / conf.nx } }, vertexShader: ` uniform float uCx; uniform float uCy; uniform float uSize; attribute vec3 color; attribute vec3 next; attribute vec3 prev; attribute float side; varying vec4 vColor; void main() { vec3 pos = vec3(position.x * uCx, position.y * uCy, 0.0); vec2 sprev = vec2(prev.x * uCx, prev.y * uCy); vec2 snext = vec2(next.x * uCx, next.y * uCy); vec2 tangent = normalize(snext - sprev); vec2 normal = vec2(-tangent.y, tangent.x); float dist = length(snext - sprev); normal *= smoothstep(0.0, 0.02, dist); vColor = vec4(color, 1.0 - smoothstep(0.5, 1.0, uv.y) * 0.5); normal *= uSize;// * (1.0 - uv.y); pos.xy -= normal * side; gl_Position = vec4(pos, 1.0); } `, fragmentShader: ` varying vec4 vColor; void main() { gl_FragColor = vColor; } ` }); const dx = verlet.width / conf.nx,dy = -verlet.height / conf.ny; const ox = -dx * (conf.nx / 2 - 0.5),oy = verlet.height / 2 - dy / 2; // const cscale = chroma.scale([chroma.random(), chroma.random()]); const cscale = chroma.scale([0x09256f, 0x6efec8]); for (let i = 0; i < conf.nx; i++) { const points = []; const vpoints = []; for (let j = 0; j < conf.ny; j++) { const x = ox + i * dx,y = oy + j * dy; points.push(new THREE.Vector3(x, y, 0)); vpoints.push(new Vec2(x, y)); } const polyline = new Polyline({ points, color1: cscale(rnd(0, 1)), color2: cscale(rnd(0, 1)) }); polylines.push(polyline); polyline.segment = verlet.lineSegments(vpoints, 5); polyline.segment.pin(0); polyline.segment.particles.forEach(p => {p.pos.x += rndFS(10);}); const mesh = new THREE.Mesh(polyline.geometry, material); scene.add(mesh); } } function updatePoints() { polylines.forEach(line => { for (let i = 0; i < line.points.length; i++) { const p = line.segment.particles[i].pos; line.points[i].x = p.x; line.points[i].y = p.y; } line.updateGeometry(); }); } function updateColors() { const c1 = chroma.random(),c2 = chroma.random(); const cscale = chroma.scale([c1, c2]); console.log(c1.hex(), c2.hex()); // #21a25f #a0fa42 // #09256f #6efec8 polylines.forEach(line => { line.color1 = cscale(rnd(0, 1)); line.color2 = cscale(rnd(0, 1)); const cscale1 = chroma.scale([line.color1, line.color2]); const colors = line.geometry.attributes.color.array; const c = new THREE.Color(); f.........完整代码请登录后点击上方下载按钮下载查看
网友评论0