three实现三维能量场波动流动连线动画效果代码
代码语言:html
所属分类:三维
代码描述:three实现三维能量场波动流动连线动画效果代码
代码标签: three 三维 能量 场 波动 连线 动画 流动
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> body, html{ margin: 0; height: 100vh; background: linear-gradient(-45deg, #333, #000); overflow: hidden; } canvas{ display: none; border: 3px solid #fff3; position: absolute; background: #04f1; left: 50%; top: 50%; border-radius: 10px; transform: translate(-50%, -50%); } canvas:focus{ outline: none; } </style> </head> <body translate="no"> <div id="container"></div> <canvas id=c></canvas> <script type="text/javascript" src="//repo.bfw.wiki/bfwrepo/js/three.160.js"></script> <script type="module"> var camera let scene, renderer let isUserInteracting = false, lon = 0, lat = 0, phi = 0, theta = 0, onPointerDownPointerX = 0, onPointerDownPointerY = 0, onPointerDownLon = 0, onPointerDownLat = 0 const distance = 1e4-9e3 var func = navigator.userAgent.toLowerCase().indexOf('firefox') != -1 ? "onwheel" : "onmousewheel" window[func]= e => { let delta = camera.fov delta += e.deltaY/25 camera.fov = Math.min(140, Math.max(10, delta)) camera.updateProjectionMatrix() } var material, loadScene, texture, sceneLoaded = false, geometry function init(url){ const container = document.getElementById( 'container' ) camera = new THREE.PerspectiveCamera( 100, 16/9, .05, 1e6) loadScene = () =>{ scene = new THREE.Scene() geometry = new THREE.SphereGeometry( 1e4, 64, 240 ) geometry.scale( - 1, 1, 1 ) texture = new THREE.CanvasTexture(c) /* if(url.toLowerCase().indexOf('.mp4') != -1 || url.toLowerCase().indexOf('.webm') != -1){ const vid = document.createElement('video') vid.muted = true vid.loop = true vid.crossOrigin = true vid.src = url vid.play() texture = new THREE.VideoTexture( vid ) }else{ texture = new THREE.TextureLoader().load(url) texture.wrapS = THREE.RepeatWrapping texture.wrapT = THREE.RepeatWrapping texture.repeat.set( 1, 1 ) } */ texture.colorSpace = THREE.SRGBColorSpace texture.anisotropy = renderer.capabilities.getMaxAnisotropy() texture.wrapS = THREE.RepeatWrapping texture.wrapT = THREE.RepeatWrapping texture.repeat.set( 1, 1 ) material = new THREE.MeshBasicMaterial( { map: texture } ) material.map.minFilter = THREE.LinearFilter const mesh = new THREE.Mesh( geometry, material ) scene.add( mesh ) sceneLoaded = true } renderer = new THREE.WebGLRenderer() renderer.setSize( 1920, 1080 ) renderer.setPixelRatio(window.devicePixelRatio); renderer.setAnimationLoop( animate ) container.appendChild( renderer.domElement ) document.addEventListener( 'pointerdown', onPointerDown ) document.addEventListener( 'pointermove', onPointerMove ) document.addEventListener( 'pointerup', onPointerUp ) document.addEventListener( 'touchstart', onPointerDown ) document.addEventListener( 'touchmove', onPointerMove ) document.addEventListener( 'touchend', onPointerUp ) loadScene() } function onPointerDown( event ) { isUserInteracting = true onPointerDownPointerX = event.clientX onPointerDownPointerY = event.clientY onPointerDownLon = lon onPointerDownLat = lat } function onPointerMove( event ) { if ( isUserInteracting === true ) { var mag = .01 + camera.fov/450 lon = ( onPointerDownPointerX - event.clientX ) * mag + onPointerDownLon lat = ( onPointerDownPointerY - event.clientY ) * mag + onPointerDownLat } } function onPointerUp() { isUserInteracting = false } function animate() { if(typeof showRender != 'undefined' && showRender){ if(!sceneLoaded) loadScene() lat = Math.max( - 89.9, Math.min( 89.9, lat ) ) phi = ( 90 - lat )/180*Math.PI theta = lon/180*Math.PI camera.position.x = distance * Math.sin( phi ) * Math.cos( theta ) camera.position.y = distance * Math.cos( phi ) camera.position.z = distance * Math.sin( phi ) * Math.sin( theta ) camera.lookAt( 0, 0, 0 ) renderer.render( scene, camera ) material.map.needsUpdate = true }else{ sceneLoaded = false } } var url var l = location.href.split('url=') if(l.length>1){ url = l[1].split('&')[0] init(url) }else{ init('') } </script> <script id="rendered-js" > c = document.querySelector('#c'); c.tabIndex = 0; x_ = c.getContext('2d'); c.width = 1920; c.height = 1080; camMode = 'HDRI'; HDRIwidth = c.width; outputAspectRatio = 16 / 9; output = document.createElement('canvas'); octx = output.getContext('2d'); output.width = c.width; output.height = output.width / outputAspectRatio; showOutput = false; // HDRI view, for recording showRender = false; // actual pipe to environment, for render eval etc showPreview = false; // thumbnail in upper right // (only visible in default or HDRI output, not render) if (showRender) { outputAspectRatio = 2; showOutput = true; showPreview = false; c.style.display = 'none'; } else { //showPreview = true //showOutput = false setTimeout(() => { c.style.display = 'block'; c.style.borderRadius = showOutput ? '0' : '10px'; c.style.border = showOutput ? 'none' : '3px solid #fff3'; c.style.margin = showOutput ? 0 : 10; }, 0); } // tempBuffer, needed for optional preview [P] tempBuffer = document.createElement('canvas'); tempBuffer.width = c.width; tempBuffer.height = c.height; tbctx = tempBuffer.getContext('2d'); C = Math.cos; S = Math.sin; t = 0; T = Math.tan; rsz = window.onresize = () => { let b = document.body; let margin = showOutput ? 0 : 10; let n; let d = showOutput ? 1 / outputAspectRatio : .5625; c.style.borderRadius = showOutput ? '0' : '10px'; c.style.border = showOutput ? 'none' : '3px solid #fff3'; //c.width = 1920 c.height = c.width * d; output.width = c.width; output.height = output.width * d; if (b.clientHeight / b.clientWidth > d) { c.style.width = `${(n = b.clientWidth) - margin * 2}px`; c.style.height = `${n * d - margin * 2}px`; } else { c.style.height = `${(n = b.clientHeight) - margin * 2}px`; c.style.width = `${n / d - margin * 2}px`; } }; rsz(); keyTimer = 0; keyTimerInterval = .25; keys = Array(256).fill(false); window.onkeyup = e => { keyTimer = 0; keys[e.keyCode] = false; }; window.onkeydown = e => { keys[e.keyCode] = true; if (keyTimer <= t) { keyTimer = t + keyTimerInterval; if (e.keyCode == 72) { showOutput = !showOutput; if (showRender) { if (typeof can != 'undefined') { outputAspectRatio = 2; showOutput = true; showPreview = false; can.style.display = 'block'; c.style.display = 'none'; rsz2(); } } else { showPreview = true; if (typeof can != 'undefined') can.style.display = 'none'; c.style.display = 'block'; rsz(); } } if (e.keyCode == 80) { showPreview = !showPreview; } if (e.keyCode == 82) { showRender = !showRender; if (showRender) { outputAspectRatio = 2; showPreview = false; showOutput = true; can.style.display = 'block'; c.style.display = 'none'; } else { showPreview = true; can.style.display = 'none'; c.style.display = 'block'; } } if (e.keyCode == 70) { if (showRender || outputAspectRatio == 16 / 9) { outputAspectRatio = 2; } else { outputAspectRatio = 16 / 9; } rsz(); } } }; window.addEventListener('resize', rsz2 = () => { can = document.querySelectorAll('canvas')[0]; if (typeof can != 'undefined') { can.tabindex = 0; can.focus(); let b = document.body; let margin = 10; let n; let d = .5625; can.style.borderRadius = '10px'; can.style.border = '3px solid #fff3'; if (b.clientHeight / b.clientWidth > d) { can.style.width = `${(n = b.clientWidth) - margin * 2}px`; can.style.height = `${n * d - margin * 2}px`; } else { can.style.height = `${(n = b.clientHeight) - margin * 2}px`; can.style.width = `${n / d - margin * 2}px`; } } if (showRender) { showRender = false; setTimeout(() => { showRender = true; }, 0); } }); for (let i = 10; i--;) setTimeout(() => {rsz2(), rsz();}, i * 60); async function Draw() { if (!t) { X = Y = Z = 0; oX = oY = oZ = 0; Rl = Pt = Yw = 0; camX = camY = camZ = camD = 0; camposX = camposY = camposZ = 0; camRl = camPt = camYw = 0; Rn = Math.random; cls = () => { Z = camZ = 1E6; x_['globalAlpha'] = 1; x_.fillStyle = showOutput && showPreview ? '#0008' : '#000a'; x_.fillRect(0, 0, 1e5, 1e5, 0, 0, 1e5, 1e5); x_.lineJoin = 'roud'; x_.lineCap = 'roud'; octx['globalAlpha'] = 1; octx.fillStyle = '#000a'; octx.fillRect(0, 0, 1e5, 1e5, 0, 0, 1e5, 1e5); octx.lineJoin = 'roud'; octx.lineCap = 'roud'; override = false; }; hoff = .5; // horizontal offset of HDRI output, note it wraps invertY = true; x = (func, ...vals) => { let p = 0,q = 0,d,ox,oy,oz,ox1,oy1,oz1,X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3,X4,Y4,Z4; let ox2, oy2, oz2, s, s2, split, onscreen1, onscreen2; switch (func) { // assignments case 'strokeStyle': if (vals.length) { x_[func] = vals[0]; octx[func] = vals[0]; } else { return x_[func]; } break; case 'fillText': if (Z > 0 && (!showOutput || showPreview || override)) x_[func](vals[0], vals[1], vals[2]); if (showOutput || showPreview) { let text = vals[0]; ox = camX - camposX; oy = camY - camposY; oz = camZ - camposZ; p = ((Math.atan2(ox, oz) + Math.PI * 2) / Math.PI / 2 + hoff) % 1; d = Math.hypot(ox, oy, oz) + .0001; q = invertY ? 1 - Math.acos(oy / d) / Math.PI : Math.acos(oy / d) / Math.PI; ox1 = p * output.width; oy1 = q * output.height; X1 = ox1 + vals[3]; Y1 = oy1 + vals[4]; octx[func](text, X1, Y1); if (X1 < 0) octx[func](text, X1 + output.width, Y1); if (X1 + X2 > output.width) octx[func](text, X1 - output.width, Y1); } break; case 'textAlign': if (vals.length) { x_[func] = vals[0]; octx[func] = vals[0]; } else { return x_[func]; } break; case 'globalCompositeOperation': if (vals.length) { x_[func] = vals[0]; octx[func] = vals[0]; } else { return x_[func]; } break; case 'lineWidth': if (vals.length) { x_[func] = vals[0]; ox = camX - camposX; oy = camY - camposY; oz = camZ - camposZ; p = ((Math.atan2(ox, oz) + Math.PI * 2) / Math.PI / 2 + hoff) % 1; d = Math.hypot(ox, oy, oz) + .0001; q = invertY ? 1 - Math.acos(oy / d) / Math.PI : Math.acos(oy / d) / Math.PI; //modsize = .4+Math.abs(.5 - q)*2 modsize = .5 + (2 * Math.abs(.5 - q) * 1.5) ** 2 / 1.5; .........完整代码请登录后点击上方下载按钮下载查看
网友评论0