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; octx[func] = Math.min(250, vals[1] * modsize); } else { return [x_[func], octx[func]]; } break; case 'fillStyle': if (vals.length) { x_[func] = vals[0]; octx[func] = vals[0]; } else { return x_[func]; } break; case 'globalAlpha': if (vals.length) { x_[func] = vals[0]; octx[func] = vals.length > 1 ? vals[1] : vals[0]; } else { return x_[func]; } break; case 'font': if (vals.length) { x_[func] = vals[0]; octx[func] = vals.length > 1 ? vals[1] : vals[0]; } else { return x_[func]; } break; case 'lineJoin': if (vals.length) { x_[func] = vals[0]; octx[func] = vals[0]; } else { return x_[func]; } break; case 'lineCap': if (vals.length) { x_[func] = vals[0]; octx[func] = vals[0]; } else { return x_[func]; } break; // function calls default: if (vals.length) { switch (func) { case 'lineTo': if (Z > 0 && (!showOutput || showPreview || override)) x_[func](...vals); if (showOutput || showPreview) { ox = camX - camposX; oy = camY - camposY; oz = camZ - camposZ; p = ((Math.atan2(ox, oz) + Math.PI * 2) / Math.PI / 2 + hoff) % 1; if (op_ != -1) { if (op_ > .75 && p < .25) p += 1; if (op_ < .25 && p > .75) p -= 1; } op_ = p; d = Math.hypot(ox, oy, oz) + .0001; q = invertY ? 1 - Math.acos(oy / d) / Math.PI : Math.acos(oy / d) / Math.PI; HDRIqueue = [...HDRIqueue, [p * output.width, q * output.height]]; } break; case 'clearRect': if (Z > 0 && (!showOutput || showPreview)) x_[func](vals[0], vals[1], vals[2], vals[3]); if (showOutput || showPreview || override) { 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) + .01; q = invertY ? 1 - Math.acos(oy / d) / Math.PI : Math.acos(oy / d) / Math.PI; ox1 = p * output.width; oy1 = q * output.height; modsize = 1; octx[func](ox1 - vals[6] * modsize / 2, oy1 - vals[7] * modsize / 2, vals[6] * modsize, vals[7] * modsize); } break; case 'fillRect':case 'strokeRect': if (Z > 0 && (!showOutput || showPreview)) x_[func](vals[0], vals[1], vals[2], vals[3]); if (showOutput || showPreview || override) { 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; modsize = 1 + (2 * Math.abs(.5 - q) * 1.28) ** 11; X1 = ox1 - vals[6] * modsize / 4; Y1 = oy1 - vals[7] / 4; X2 = vals[6] * modsize / 2; Y2 = vals[7] / 2; octx[func](X1, Y1, X2, Y2); if (X1 < 0) octx[func](X1 + output.width, Y1, X2, Y2); if (X1 + X2 > output.width) octx[func](X1 - output.width, Y1, X2, Y2); } break; case 'drawImage': if (Z > 0 && (!showOutput || showPreview || override)) x_[func](vals[0], vals[1], vals[2], vals[3], vals[4]); if (showOutput || showPreview) { ox = camX - camposX; oy = camY - camposY; oz = camZ - camposZ; vals[7] /= 1; vals[8] /= 1; 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; modsize = 1 + (2 * Math.abs(.5 - q) * 1.28) ** 11; X1 = ox1 - vals[7] * modsize / 4; Y1 = oy1 - vals[8] / 4; X2 = vals[7] * modsize / 2; Y2 = vals[8] / 2; octx[func](vals[0], X1, Y1, X2, Y2); if (X1 < 0) octx[func](vals[0], X1 + output.width, Y1, X2, Y2); if (X1 + X2 > output.width) octx[func](vals[0], X1 - output.width, Y1, X2, Y2); } break; default: if (!showOutput || showPreview || override) x_[func](...vals); if (showOutput || showPreview || override) octx[func](...vals); break;} } else { switch (func) { case 'beginPath': if (!showOutput || showPreview || override) x_[func](); if (showOutput || showPreview || override) { octx[func](); HDRIqueue = []; op_ = -1; } break; case 'stroke': if (!showOutput || showPreview || override) x_[func](); if (showOutput || showPreview || override) { for (let m = 3; m--;) { let ofx; switch (m) { case 0:ofx = -output.width;break; case 1:ofx = 0;break; case 2:ofx = output.width;break;} polyOnBorder = false; onLeft = false; onRight = false; outsized = false; HDRIqueue.map((v, i) => { if (!outsized) { l1 = i; l2 = (i + 1) % HDRIqueue.length; el1 = HDRIqueue[l1]; el2 = HDRIqueue[l2]; if (Math.hypot(el2[0] + ofx - (el1[0] + ofx), el2[1] - el1[1]) > output.width / 1.1) { outsized = true; } else { if (el1[0] + ofx >= 0 && el2[0] + ofx < 0 || el1[0] + ofx >= output.width && el2[0] + ofx < output.width) polyOnBorder = true; } X = v[0] + ofx; Y = v[1]; if (X >= output.width) onRight = true; if (X < 0) onLeft = true; } }); if (!outsized && (polyOnBorder || !(onRight || onLeft))) { octx.beginPath(); HDRIqueue.map((v, i) => { octx.lineTo(v[0] + ofx, v[1]); }); octx.stroke(); } } } break; case 'fill': if (!showOutput || showPreview || override) x_[func](); if (showOutput || showPreview || override) { for (let m = 3; m--;) { let ofx; switch (m) { case 0:ofx = -output.width;break; case 1:ofx = 0;break; case 2:ofx = output.width;break;} polyOnBorder = false; onLeft = false; onRight = false; outsized = false; HDRIqueue.map((v, i) => { if (!outsized) { l1 = i; l2 = (i + 1) % HDRIqueue.length; el1 = HDRIqueue[l1]; el2 = HDRIqueue[l2]; if (Math.hypot(el2[0] + ofx - (el1[0] + ofx), el2[1] - el1[1]) > output.width / 1.1) { outsized = true; } else { if (el1[0] + ofx >= 0 && el2[0] + ofx < 0 || el1[0] + ofx >= output.width && el2[0] + ofx < output.width) polyOnBorder = true; } X = v[0] + ofx; Y = v[1]; if (X >= output.width) onRight = true; if (X < 0) onLeft = true; } }); if (!outsized && (polyOnBorder || !(onRight || onLeft))) { octx.beginPath(); HDRIqueue.map((v, i) => { octx.lineTo(v[0] + ofx, v[1]); }); octx.fill(); } } } break; default: if (!showOutput || showPreview) x_[func](); if (showOutput || showPreview) octx[func](); break;} } break;} return [p, q]; }; R = (Rl, Pt, Yw, m) => { M = Math; A = M.atan2; H = M.hypot; let X0_ = X; let Y0_ = Y; let Z0_ = Z; let p, d; // MAIN if (m) { //X -= oX //Y -= oY //Z -= oZ } X = S(p = A(X, Y) + Rl) * (d = H(X, Y)); Y = C(p) * d; X = S(p = A(X, Z) + (Yw + .0000)) * (d = H(X, Z)); Z = C(p) * d; Y = S(p = A(Y, Z) + Pt) * (d = H(Y, Z)); Z = C(p) * d; if (m) { X += oX; Y += oY; Z += oZ; } let X1_ = X; let Y1_ = Y; let Z1_ = Z; // CAM X = X0_; Y = Y0_; Z = Z0_; if (m) { //X -= camposX //Y -= camposY //Z -= camposZ } let mod = Rl == 0 && Pt == 0 && Yw == 0 ? 0 : 1; X = S(p = A(X, Y) + camRl * mod) * (d = H(X, Y)); Y = C(p) * d; X = S(p = A(X, Z) + (camYw + .00001) * mod) * (d = H(X, Z)); Z = C(p) * d; Y = S(p = A(Y, Z) + camPt * mod) * (d = H(Y, Z)); Z = C(p) * d; if (m) { X += camposX; Y += camposY; Z += camposZ; } if (camMode == 'HDRI') { camD = H(X, Y, Z); X = camposX + X / camD; Y = camposY + Y / camD; Z = camposZ + Z / camD; } camX = X; camY = Y; camZ = Z; //camD += Z X = X1_; Y = Y1_; Z = Z1_; }; HSVFromRGB = (R, G, B) => { let R_ = R / 255; let G_ = G / 255; let B_ = B / 255; let Cmin = Math.min(R_, G_, B_); let Cmax = Math.max(R_, G_, B_); let val = Cmax; //(Cmax+Cmin) / 2 let delta = Cmax - Cmin; let sat = Cmax ? delta / Cmax : 0; let min = Math.min(R, G, B); let max = Math.max(R, G, B); let hue = 0; if (delta) { if (R >= G && R >= B) hue = (G - B) / (max - min); if (G >= R && G >= B) hue = 2 + (B - R) / (max - min); if (B >= G && B >= R) hue = 4 + (R - G) / (max - min); } hue *= 60; while (hue < 0) hue += 360; while (hue >= 360) hue -= 360; return [hue, sat, val]; }; R3 = (Rl, Pt, Yw, m = false) => { M = Math; A = M.atan2; H = M.hypot; if (m) { X -= oX; Y -= oY; Z -= oZ; } X = S(p = A(X, Y) + Rl) * (d = H(X, Y)); Y = C(p) * d; Y = S(p = A(Y, Z) + Pt) * (d = H(Y, Z)); Z = C(p) * d; X = S(p = A(X, Z) + Yw) * (d = H(X, Z)); Z = C(p) * d; }; Q = () => [c.width / 2 + X / (Z + .01) * 700, c.height / 2 + Y / (Z + .01) * 700, output.width / 2 + camX / (camZ + .01) * 700, output.height / 2 + camY / (camZ + .01) * 700]; Q2 = () => [c.width / 2 + X * 75, c.height / 2 + Y * 75, output.width / 2 + camX * 75, output.height / 2 + camY * 75]; I = (A, B, M, D, E, F, G, H) => (K = ((G - E) * (B - F) - (H - F) * (A - E)) / (J = (H - F) * (M - A) - (G - E) * (D - B))) >= 0 && K <= 1 && (L = ((M - A) * (B - F) - (D - B) * (A - E)) / J) >= 0 && L <= 1 ? [A + K * (M - A), B + K * (D - B)] : 0; spawnTunnel = ( tx, ty, tz, rw, cl, sp = 1, rad = .5, theta1 = 0, theta2 = 0, theta1ModFreq = 0, theta1ModMag = 0, theta2ModFreq = 0, theta2ModMag = 0, theta1Offset = 0, theta2Offset = 0, radModFreq = 0, radModMag = 0, radModOffset = 0, showLine = false) => { let X_ = X = tx; let Y_ = Y = ty; let Z_ = Z = tz; let ret = []; let p2a, p2, p2a1, ls; if (showLine) x('beginPath'); for (let i = cl + 1; i--;) { let p1 = theta1 + C(Math.PI * 2 / cl * i * theta1ModFreq + theta1Offset) * theta1ModMag; let p2 = theta2 + C(Math.PI * 2 / cl * i * theta2ModFreq + theta2Offset) * theta2ModMag; let p2a1 = theta2 + C(Math.PI * 2 / cl * (i + 1) * theta2ModFreq + theta2Offset) * theta2ModMag; let lsa = rad + C(Math.PI * 2 / cl * i * radModFreq + radModOffset) * rad / 2 * radModMag; let lsb = rad + C(Math.PI * 2 / cl * (i + 1) * radModFreq + radModOffset) * rad / 2 * radModMag; if (i == cl) { p2a = p2; ls = lsa; } else if (i == 0) { p2a = p2a1; ls = lsb; } else { p2a = (p2 + p2a1) / 2; ls = (lsa + lsb) / 2; } let a = []; for (let j = rw + 1; j--;) { p = Math.PI * 2 / rw * j + Math.PI / rw; X = S(p) * ls; Y = 0; Z = C(p) * ls; R(-p2a + Math.PI / 2, 0, 0); R(0, 0, -p1); a = [...a, [X + X_, Y + Y_, Z + Z_]]; } ret = [...ret, a]; if (showLine) { X = X_; Y = Y_; Z = Z_; motionPath = [...motionPath, [X, Y, Z]]; R(Rl, Pt, Yw, 1); x('lineTo', ...Q()); } vx = C(p1) * C(p2) * sp; vy = S(p2) * sp; vz = S(p1) * C(p2) * sp; X_ += vx; Y_ += vy; Z_ += vz; } //if(showLine) stroke('#f00', '', 2, false) a = []; ret.map((v, i) => { if (i) { let s1 = ret[i]; let s2 = ret[i - 1]; for (let j = rw; j--;) { b = []; let l1_ = (j + 0) % rw; let l2_ = (j + 1) % rw; X = s1[l1_][0]; Y = s1[l1_][1]; Z = s1[l1_][2]; b = [...b, [X, Y, Z]]; X = s1[l2_][0]; Y = s1[l2_][1]; Z = s1[l2_][2]; b = [...b, [X, Y, Z]]; X = s2[l2_][0]; Y = s2[l2_][1]; Z = s2[l2_][2]; b = [...b, [X, Y, Z]]; X = s2[l1_][0]; Y = s2[l1_][1]; Z = s2[l1_][2]; b = [...b, [X, Y, Z]]; a = [...a, b]; } } }); return a; }; Normal = (facet, autoFlipNormals = false, X1 = 0, Y1 = 0, Z1 = 0) => { let ax = 0,ay = 0,az = 0; facet.map(q_ => {ax += q_[0], ay += q_[1], az += q_[2];}); ax /= facet.length, ay /= facet.length, az /= facet.length; let b1 = facet[2][0] - facet[1][0],b2 = facet[2][1] - facet[1][1],b3 = facet[2][2] - facet[1][2]; let c1 = facet[1][0] - facet[0][0],c2 = facet[1][1] - facet[0][1],c3 = facet[1][2] - facet[0][2]; crs = [b2 * c3 - b3 * c2, b3 * c1 - b1 * c3, b1 * c2 - b2 * c1]; d = Math.hypot(...crs) + .001; let nls = 1; //normal line length crs = crs.map(q => q / d * nls); let X1_ = ax,Y1_ = ay,Z1_ = az; let flip = 1; if (autoFlipNormals) { let d1_ = Math.hypot(X1_ - X1, Y1_ - Y1, Z1_ - Z1); let d2_ = Math.hypot(X1 - (ax + crs[0] / 99), Y1 - (ay + crs[1] / 99), Z1 - (az + crs[2] / 99)); flip = d2_ > d1_ ? -1 : 1; } let X2_ = ax + (crs[0] *= flip),Y2_ = ay + (crs[1] *= flip),Z2_ = az + (crs[2] *= flip); return [X1_, Y1_, Z1_, X2_, Y2_, Z2_]; }; async function loadOBJ(url, scale, tx, ty, tz, rl, pt, yw, recenter = true) { let res; await fetch(url, res => res).then(data => data.text()).then(data => { a = []; data.split("\nv ").map(v => { a = [...a, v.split("\n")[0]]; }); a = a.filter((v, i) => i).map(v => [...v.split(' ').map(n => +n.replace("\n", ''))]); ax = ay = az = 0; a.map(v => { v[1] *= -1; if (recenter) { ax += v[0]; ay += v[1]; az += v[2]; } }); ax /= a.length; ay /= a.length; az /= a.length; a.map(v => { X = (v[0] - ax) * scale; Y = (v[1] - ay) * scale; Z = (v[2] - az) * scale; R2(rl, pt, yw, 0); v[0] = X; v[1] = Y * (url.indexOf('bug') != -1 ? 2 : 1); v[2] = Z; }); maxY = -6e6; a.map(v => { if (v[1] > maxY) maxY = v[1]; }); a.map(v => { v[1] -= maxY - oY; v[0] += tx; v[1] += ty; v[2] += tz; }); b = []; data.split("\nf ").map(v => { b = [...b, v.split("\n")[0]]; }); b.shift(); b = b.map(v => v.split(' ')); b = b.map(v => { v = v.map(q => { return +q.split('/')[0]; }); v = v.filter(q => q); return v; }); res = []; b.map(v => { e = []; v.map(q => { e = [...e, a[q - 1]]; }); e = e.filter(q => q); res = [...res, e]; }); }); return res; } reflect = (a, n) => { let d1 = Math.hypot(...a) + .0001; let d2 = Math.hypot(...n) + .0001; a[0] /= d1; a[1] /= d1; a[2] /= d1; n[0] /= d2; n[1] /= d2; n[2] /= d2; let dot = -a[0] * n[0] + -a[1] * n[1] + -a[2] * n[2]; let rx = -a[0] - 2 * n[0] * dot; let ry = -a[1] - 2 * n[1] * dot; let rz = -a[2] - 2 * n[2] * dot; return [-rx * d1, -ry * d1, -rz * d1]; }; geoSphere = (mx, my, mz, iBc, size) => { let collapse = 0,mind; let B = Array(iBc).fill().map(v => { X = Rn() - .5; Y = Rn() - .5; Z = Rn() - .5; return [X, Y, Z]; }); for (let m = 32; m--;) { B.map((v, i) => { X = v[0]; Y = v[1]; Z = v[2]; B.map((q, j) => { if (j != i) { X2 = q[0]; Y2 = q[1]; Z2 = q[2]; d = 1 + (Math.hypot(X - X2, Y - Y2, Z - Z2) * (3 + iBc / 40) * 3) ** 3; X += (X - X2) * 9 / d; Y += (Y - Y2) * 9 / d; Z += (Z - Z2) * 9 / d; } }); d = Math.hypot(X, Y, Z); v[0] = X / d; v[1] = Y / d; v[2] = Z / d; if (collapse) { d = 25 + Math.hypot(X, Y, Z); v[0] = (X - X / d) / 1.1; v[1] = (Y - Y / d) / 1.1; v[2] = (Z - Z / d) / 1.1; } }); } mind = 6e6; B.map((v, i) => { X1 = v[0]; Y1 = v[1]; Z1 = v[2]; B.map((q, j) => { X2 = q[0]; Y2 = q[1]; Z2 = q[2]; if (i != j) { d = Math.hypot(a = X1 - X2, b = Y1 - Y2, e = Z1 - Z2); if (d < mind) mind = d; } }); }); a = []; B.map((v, i) => { X1 = v[0]; Y1 = v[1]; Z1 = v[2]; B.map((q, j) => { X2 = q[0]; Y2 = q[1]; Z2 = q[2]; if (i != j) { d = Math.hypot(X1 - X2, Y1 - Y2, Z1 - Z2); if (d < mind * 2) { if (!a.filter(q => q[0] == X2 && q[1] == Y2 && q[2] == Z2 && q[3] == X1 && q[4] == Y1 && q[5] == Z1).length) a = [...a, [X1 * size, Y1 * size, Z1 * size, X2 * size, Y2 * size, Z2 * size]]; } } }); }); B.map(v => { v[0] *= size / 1.3333; v[1] *= size / 1.3333; v[2] *= size / 1.3333; v[0] += mx; v[1] += my; v[2] += mz; }); return [mx, my, mz, size, B, a]; }; /* burst = new Image() url = "https://srmcgann.github.io/temp/burst.png" await fetch(url).then(res=>res.blob()).then(data=> burst.src = URL.createObjectURL(data)) //burst1 = new Image() //burst1.src = "https://srmcgann.github.io/temp/burst1.png" burst2 = new Image() url = "https://srmcgann.github.io/temp/burst2.png" await fetch(url).then(res=>res.blob()).then(data=> burst2.src = URL.createObjectURL(data)) burst3 = new Image() url = "https://srmcgann.github.io/temp/burst3.png" await fetch(url).then(res=>res.blob()).then(data=> burst3.src = URL.createObjectURL(data)) burst4 = new Image() url = "https://srmcgann.github.io/temp/burst4.png" await fetch(url).then(res=>res.blob()).then(data=> burst4.src = URL.createObjectURL(data)) burstz = [ burst, burst2, burst3, burst4] sphere0 = new Image() url = 'https://srmcgann.github.io/ultratemp6/sphere_colorful.png' await fetch(url).then(res=>res.blob()).then(data=> sphere0.src = URL.createObjectURL(data)) sphere1 = new Image() url = 'https://srmcgann.github.io/temp13/sphere_colorful_1.png' await fetch(url).then(res=>res.blob()).then(data=> sphere1.src = URL.createObjectURL(data)) sphere2 = new Image() url = 'https://srmcgann.github.io/temp13/sphere_colorful_2.png' await fetch(url).then(res=>res.blob()).then(data=> sphere2.src = URL.createObjectURL(data)) sphere3 = new Image() url = 'https://srmcgann.github.io/temp13/sphere_colorful_3.png' await fetch(url).then(res=>res.blob()).then(data=> sphere3.src = URL.createObjectURL(data)) sphere4 = new Image() url = 'https://srmcgann.github.io/temp13/sphere_colorful_4.png' await fetch(url).then(res=>res.blob()).then(data=> sphere4.src = URL.createObjectURL(data)) spherez = [ sphere1, sphere2, sphere3, sphere4 ] */ star1 = new Image(); url = "https://srmcgann.github.io/stars/star1.png"; await fetch(url).then(res => res.blob()).then(data => star1.src = URL.createObjectURL(data)); star2 = new Image(); url = "https://srmcgann.github.io/stars/star2.png"; await fetch(url).then(res => res.blob()).then(data => star2.src = URL.createObjectURL(data)); star3 = new Image(); url = "https://srmcgann.github.io/stars/star3.png"; await fetch(url).then(res => res.blob()).then(data => star3.src = URL.createObjectURL(data)); star4 = new Image(); url = "https://srmcgann.github.io/stars/star4.png"; await fetch(url).then(res => res.blob()).then(data => star4.src = URL.createObjectURL(data)); star5 = new Image(); url = "https://srmcgann.github.io/stars/star5.png"; await fetch(url).then(res => res.blob()).then(data => star5.src = URL.createObjectURL(data)); star6 = new Image(); url = "https://srmcgann.github.io/stars/star6.png"; await fetch(url).then(res => res.blob()).then(data => star6.src = URL.createObjectURL(data)); star7 = new Image(); url = "https://srmcgann.github.io/stars/star7.png"; await fetch(url).then(res => res.blob()).then(data =&g.........完整代码请登录后点击上方下载按钮下载查看
网友评论0