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