canvas实现太空宇宙运动粒子吞噬星星动画效果代码

代码语言:html

所属分类:粒子

代码描述:canvas实现太空宇宙运动粒子吞噬星星动画效果代码

代码标签: canvas 太空 宇宙 运动 粒子 吞噬 星星 动画

下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开

<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  

  
  
  
  
<style>
body, html{
  margin: 0;
  height: 100vh;
  background: linear-gradient(-45deg, #204, #000);
  overflow: hidden;
}
#c{
  border: 3px solid #0Ff3;
  position: absolute;
  background: #04f1;
  left: 50%;
  top: 50%;
  border-radius: 10px;
  transform: translate(-50%, -50%);
}
</style>


  
  
</head>

<body translate="no">
  <canvas id=c></canvas>
  
      <script  >
c = document.querySelector('#c');
c.width = 1920;
c.height = 1080;
x = c.getContext('2d');
C = Math.cos;
S = Math.sin;
t = 0;
T = Math.tan;

rsz = window.onresize = () => {
  let b = document.body;
  let margin = 10;
  let n;
  let d = .5625;
  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();

async function Draw() {
  if (!t) {
    oX = oY = oZ = 0;
    Rn = Math.random;
    R = (Rl, Pt, Yw, m) => {
      let p;
      M = Math;
      A = M.atan2;
      H = M.hypot;
      X = S(p = A(X, Z) + Yw) * (d = H(X, Z));
      Z = C(p) * d;
      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;
      if (m) {
        X += oX;
        Y += oY;
        Z += oZ;
      }
    };

    R2 = (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 * 900, c.height / 2 + Y / Z * 900];
    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;

    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;
      let B = Array(iBc).fill().map(v => {
        X = Rn() - .5;
        Y = Rn() - .5;
        Z = Rn() - .5;
        return [X, Y, Z];
      });
      for (let m = 99; 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) ** 4;
              X += (X - X2) * 99 / d;
              Y += (Y - Y2) * 99 / d;
              Z += (Z - Z2) * 99 / 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;
        v[1] *= size;
        v[2] *= size;
        v[0] += mx;
        v[1] += my;
        v[2] += mz;
      });
      return [mx, my, mz, size, B, a];
    };

    burst = new Image();
    burst.src = "https://srmcgann.github.io/temp/burst.png";

    starsLoaded = false, starImgs = [{ loaded: false }];
    starImgs = Array(9).fill().map((v, i) => {
      let a = { img: new Image(), loaded: false };
      a.img.onload = () => {
        a.loaded = true;
        setTimeout(() => {
          if (starImgs.filter(v => v.loaded).length == 9) starsLoaded = true;
        }, 0);
      };
      a.img.src = `https://srmcgann.github.io/stars/star${i + 1}.png`;
      return a;
    });

    lineFaceI = (X1, Y1, Z1, X2, Y2, Z2, facet, autoFlipNormals = false, showNormals = false) => {
      let X_, Y_, Z_, d, m, l_, K, J, L, p;
      let 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;
      let Q_ = () => [c.width / 2 + X_ / Z_ * 900, c.height / 2 + Y_ / Z_ * 900];
      let R_ = (Rl, Pt, Yw, m) => {
        let M = Math,A = M.atan2,H = M.hypot;
        X_ = S(p = A(X_, Y_) + Rl) * (d = H(X_, Y_)), Y_ = C(p) * d, X_ = S(p = A(X_, Z_) + Yw) * (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 rotSwitch = m => {
        switch (m) {
          case 0:R_(0, 0, Math.PI / 2);break;
          case 1:R_(0, Math.PI / 2, 0);break;
          case 2:R_(Math.PI / 2, 0, Math.PI / 2);break;}

      };
      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];
      let 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);
      if (showNormals) {
        x.beginPath();
        X_ = X1_, Y_ = Y1_, Z_ = Z1_;
        R_(Rl, Pt, Yw, 1);
        if (Z_ > 0) x.lineTo(...Q_());
        X_ = X2_, Y_ = Y2_, Z_ = Z2_;
        R_(Rl, Pt, Yw, 1);
        if (Z_ > 0) x.lineTo(...Q_());
        x.lineWidth = 5;
        x.strokeStyle = '#f004';
        x.stroke();
      }

      let p1_ = Math.atan2(X2_ - X1_, Z2_ - Z1_);
      let p2_ = -(Math.acos((Y2_ - Y1_) / (Math.hypot(X2_ - X1_, Y2_ - Y1_, Z2_ - Z1_) + .001)) + Math.PI / 2);
      let isc = false,iscs = [false, false, false];
      X_ = X1, Y_ = Y1, Z_ = Z1;
      R_(0, -p2_, -p1_);
      let rx_ = X_,ry_ = Y_,rz_ = Z_;
      for (let m = 3; m--;) {
        if (isc === false) {
          X_ = rx_, Y_ = ry_, Z_ = rz_;
          rotSwitch(m);
          X1_ = X_, Y1_ = Y_, Z1_ = Z_ = 5, X_ = X2, Y_ = Y2, Z_ = Z2;
          R_(0, -p2_, -p1_);
          rotSwitch(m);
          X2_ = X_, Y2_ = Y_, Z2_ = Z_;
          facet.map((q_, j_) => {
            if (isc === false) {
              let l = j_;
              X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2];
              R_(0, -p2_, -p1_);
              rotSwitch(m);
              let X3_ = X_,Y3_ = Y_,Z3_ = Z_;
              l = (j_ + 1) % facet.length;
              X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2];
              R_(0, -p2_, -p1_);
              rotSwitch(m);
              let X4_ = X_,Y4_ = Y_,Z4_ = Z_;
              if (l_ = I_(X1_, Y1_, X2_, Y2_, X3_, Y3_, X4_, Y4_)) iscs[m] = l_;
            }
          });
        }
      }
      if (iscs.filter(v => v !== false).length == 3) {
        let iscx = iscs[1][0],iscy = iscs[0][1],iscz = iscs[0][0];
        let pointInPoly = true;
        ax = 0, ay = 0, az = 0;
        facet.map((q_, j_) => {ax += q_[0], ay += q_[1], az += q_[2];});
        ax /= facet.length, ay /= facet.length, az /= facet.length;
        X_ = ax, Y_ = ay, Z_ = az;
        R_(0, -p2_, -p1_);
        X1_ = X_, Y1_ = Y_, Z1_ = Z_;
        X2_ = iscx, Y2_ = iscy, Z2_ = iscz;
        facet.map((q_, j_) => {
          if (pointInPoly) {
            let l = j_;
            X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2];
            R_(0, -p2_, -p1_);
            let X3_ = X_,Y3_ = Y_,Z3_ = Z_;
            l = (j_ + 1) % facet.length;
            X_ = facet[l][0], Y_ = facet[l][1], Z_ = facet[l][2];
            R_(0, -p2_, -p1_);
            let X4_ = X_,Y4_ = Y_,Z4_ = Z_;
            if (I_(X1_, Y1_, X2_, Y2_, X3_, Y3_, X4_, Y4_)) pointInPoly = false;
          }
        });
        if (pointInPoly) {
          X_ = iscx, Y_ = iscy, Z_ = iscz;
          R_(0, p2_, 0);
          R_(0, 0, p1_);
          isc = [[X_, Y_, Z_], [crs[0], crs[1], crs[2]]];
        }
      }
      return isc;
    };

    TruncatedOctahedron = ls => {
      let shp = [],a = [];
      mind = 6e6;
      for (let i = 6; i--;) {
        X = S(p = Math.PI * 2 / 6 * i + Math.PI / 6) * ls;
        Y = C(p) * ls;
        Z = 0;
        if (Y < mind) mind = Y;
        a = [...a, [X, Y, Z]];
      }
      let theta = .6154797086703867;
      a.map(v => {
        X = v[0];
        Y = v[1] - mind;
        Z = v[2];
        R(0, theta, 0);
        v[0] = X;
        v[1] = Y;
        v[2] = Z + 1.5;
      });
      b = JSON.parse(JSON.stringify(a)).map(v => {
        v[1] *= -1;
        return v;
      });
      shp = [...shp, a, b];
      e = JSON.parse(JSON.stringify(shp)).map(v => {
        v.map(q => {
          X = q[0];
          Y = q[1];
          Z = q[2];
          R(0, 0, Math.PI);
          q[0] = X;
          q[1] = Y;
          q[2] = Z;
        });
        return v;
      });
      shp = [...shp, ...e];
      e = JSON.parse(JSON.stringify(shp)).map(v => {
        v.map(q => {
          X = q[0];
          Y = q[1];
          Z = q[2];
          R(0, 0, Math.PI / 2);
          q[0] = X;
          q[1] = Y;
          q[2] = Z;
        });
        return v;
      });
      shp = [...shp, ...e];

      coords = [
      [[3, 1], [4, 3], [4, 4], [3, 2]],
      [[3, 4], [3, 3], [2, 4], [6, 2]],
      [[1, 4], [0, 3], [0, 4], [4, 2]],
      [[1, 1], [1, 2], [6, 4], [7, 3]],
      [[3, 5], [7, 5], [1, 5], [3, 0]],
      [[2, 5], [6, 5], [0, 5], [4, 5]]];

      a = [];
      coords.map(v => {
        b = [];
        v.map(q => {
          X = shp[q[0]][q[1]][0];
          Y = shp[q[0]][q[1]][1];
          Z = shp[q[0]][q[1]][2];
          b = [...b, [X, Y, Z]];
        });
        a = [...a, b];
      });
      shp = [...shp, ...a];
      return shp.map(v => {
        v.map(q => {
          q[0] /= 3;
          q[1] /= 3;
          q[2] /= 3;
          q[0] *= ls;
          q[1] *= ls;
          q[2] *= ls;
        });
        return v;
      });
    };

    Torus = (rw, cl, ls1, ls2, parts = 1, twists = 0, part_spacing = 1.5) => {
      t_ = C(t) * 8;
      let ret = [],tx = 0,ty = 0,tz = 0,prl1 = 0,p2a = 0,prl2 = 0,p2b = 0;
      tx1 = ty1 = tz1 = tx2 = ty2 = tz2 = 0;
      for (let m = parts; m--;) {
        avgs = Array(rw).fill().map(v => [0, 0, 0]);
        for (j = rw; j--;) for (let i = cl; i--;) {
          if (parts > 1) {
            ls3 = ls1 * part_spacing;
            X = S(p = Math.PI * 2 / parts * m) * ls3;
            Y = C(p) * ls3;
            Z = 0;
            R(prl1 = Math.PI * 2 / rw * (j - 1) * twists + t_, 0, 0);
            tx1 = X;
            ty1 = Y;
            tz1 = Z;
            R(0, 0, Math.PI * 2 / rw * (j - 1));
            ax1 = X;
            ay1 = Y;
            az1 = Z;
            X = S(p = Math.PI * 2 / parts * m) * ls3;
            Y = C(p) * ls3;
            Z = 0;
            R(prl2 = Math.PI * 2 / rw * j * twists + t_, 0, 0);
            tx2 = X;
            ty2 = Y;
            tz2 = Z;
            R(0, 0, Math.PI * 2 / rw * j);
            ax2 = X;
            ay2 = Y;
            az2 = Z;
            p1a = Math.atan2(ax2 - ax1, az2 - az1);
            p2a = Math.PI / 2 + Math.acos((ay2 - ay1) / (Math.hypot(ax2 - ax1, ay2 - ay1, az2 - az1) + .001));

            X = S(p = Math.PI * 2 / parts * m) * ls3;
            Y = C(p) * ls3;
            Z = 0;
            R(Math.PI * 2 / rw * j * twists + t_, 0, 0);
            tx1b = X;
            ty1b = Y;
            tz1b = Z;
            R(0, 0, Math.PI * 2 / rw * j);
            ax1b = X;
            ay1b = Y;
            az1b = Z;
            X = S(p = Math.PI * 2 / parts * m) * ls3;
            Y = C(p) * ls3;
            Z = 0;
            R(Math.PI * 2 / rw * (j + 1) * twists + t_, 0, 0);
            tx2b = X;
            ty2b = Y;
            tz2b = Z;
            R(0, 0, Math.PI * 2 / rw * (j + 1));
            ax2b = X;
            ay2b = Y;
            az2b = Z;
            p1b = Math.atan2(ax2b - ax1b, az2b - az1b);
            p2b = Math.PI / 2 + Math.acos((ay2b - ay1b) / (Math.hypot(ax2b - ax1b, ay2b - ay1b, az2b - az1b) + .001));
          }
          a = [];
          X = S(p = Math.PI * 2 / cl * i) * ls1;
          Y = C(p) * ls1;
          Z = 0;
          //R(0,0,-p1a)
          R(prl1, p2a, 0);
          X += ls2 + tx1, Y += ty1, Z += tz1;
          R(0, 0, Math.PI * 2 / rw * j);
          a = [...a, [X, Y, Z]];
          X = S(p = Math.PI * 2 / cl * (i + 1)) * ls1;
          Y = C(p) * ls1;
          Z = 0;
          //R(0,0,-p1a)
          R(prl1, p2a, 0);
          X += ls2 + tx1, Y += ty1, Z += tz1;
          R(0, 0, Math.PI * 2 / rw * j);
          a = [...a, [X, Y, Z]];
          X = S(p = Math.PI * 2 / cl * (i + 1)) * ls1;
          Y = C(p) * ls1;
          Z = 0;
          //R(0,0,-p1b)
          R(prl2, p2b, 0);
          X += ls2 + tx2, Y += ty2, Z += tz2;
          R(0, 0, Math.PI * 2 / rw * (j + 1));
          a = [...a, [X, Y, Z]];
          X = S(p = Math.PI * 2 / cl * i) * ls1;
          Y = C(p) * ls1;
          Z = 0;
          //R(0,0,-p1b)
          R(prl2, p2b, 0);
          X += ls2 + tx2, Y += ty2, Z += tz2;
          R(0, 0, Math.PI * 2 / rw * (j + 1));
          a = [...a, [X, Y, Z]];
          ret = [...ret, a];
        }
      }
      return ret;
    };

    Cylinder = (rw, cl, ls1, ls2, caps = false) => {
      let a = [];
      for (let i = rw; i--;) {
        let b = [];
        for (let j = cl; j--;) {
          X = S(p = Math.PI * 2 / cl * j) * ls1;
          Y = (1 / rw * i - .5) * ls2;
          Z = C(p) * ls1;
          b = [...b, [X, Y, Z]];
        }
        if (caps) a = [...a, b];
        for (let j = cl; j--;) {
          b = [];
          X = S(p = Math.PI * 2 / cl * j) * ls1;
          Y = (1 / rw * i - .5) * ls2;
          Z = C(p) * ls1;
          b = [...b, [X, Y, Z]];
          X = S(p = Math.PI * 2 / cl * (j + 1)) * ls1;
          Y = .........完整代码请登录后点击上方下载按钮下载查看

网友评论0