天天看点

3d粒子特效---背景特效

3d粒子特效---背景特效

html代码:

<canvas id='canv'></canvas>
<!--

[ MouseMove / TouchSwipe ] 

Omega Centauri is a globular cluster in the constellation of Centaurus, the largest globular cluster in the Milky Way galaxy at a diameter of roughly  light-years.  It is estimated to contain approximately  million stars and a total mass equivalent to  million solar masses.

!-->
           

css代码:

html {
  height: %;
  background-image: radial-gradient(ellipse farthest-corner at center top, hsla(, %, %, ) %, hsla(, %, %, ) %);
  cursor: move;
}

body {
  width: %;
  margin: ;
  overflow: hidden;
}
           

js代码:

var c = document.getElementById('canv');
var w = c.width = window.innerWidth;
var h = c.height = window.innerHeight;
var $ = c.getContext("2d");
/*
Thanks Jack Rugile for this gradient cache fix for a perf boost - 
he's awesome - 
y'all should be following him if you're not already...( @jackrugile ;) 
*/
var _c = document.createElement('canvas');
var _w = _c.width = ;
var _h = _c.height = ;
var $$ = _c.getContext("2d");
var gc = $$.createRadialGradient(
  _w / ,
  _h / ,
  ,
  _w / ,
  _h / , (_w / ) * 
);
gc.addColorStop(, 'hsla(218, 95%, 85%, 1)');
gc.addColorStop(, 'hsla(218, 100%,85%,0.1)');
$$.fillStyle = gc;
$$.beginPath();
$$.arc(_w / , _h / , _w / , , Math.PI * );
$$.fill();

var num = ;
var _x = ;
var _y = ;
var _z = ;
var u = ;
var dtr = function(d) {
  return d * Math.PI / ;
};

var rnd = function() {
  return Math.sin(Math.floor(Math.random() * ) * Math.PI / );
};

var dst = function(p1, p2, p3) {
  return Math.sqrt(Math.pow(p2.x - p1.x, ) + Math.pow(p2.y - p1.y, ) + Math.pow(p2.z - p1.z, ));
};

var cam = {
  prime: {
    x: _x,
    y: _y,
    z: _z
  },
  sub: {
    x: ,
    y: ,
    z: 
  },
  dst: {
    x: ,
    y: ,
    z: 
  },
  ang: {
    phic: ,
    phis: ,
    thetac: ,
    thetas: 
  },
  zoom: ,
  disp: {
    x: w / ,
    y: h / ,
    z: 
  },
  upd: function() {
    cam.dst.x = cam.sub.x - cam.prime.x;
    cam.dst.y = cam.sub.y - cam.prime.y;
    cam.dst.z = cam.sub.z - cam.prime.z;
    cam.ang.phic = -cam.dst.z / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.z * cam.dst.z);
    cam.ang.phis = cam.dst.x / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.z * cam.dst.z);
    cam.ang.thetac = Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.z * cam.dst.z) / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.y * cam.dst.y + cam.dst.z * cam.dst.z);
    cam.ang.thetas = -cam.dst.y / Math.sqrt(cam.dst.x * cam.dst.x + cam.dst.y * cam.dst.y + cam.dst.z * cam.dst.z);
  }
};

var trans = {
  parts: {
    sz: function(p, sz) {
      return {
        x: p.x * sz.x,
        y: p.y * sz.y,
        z: p.z * sz.z
      };
    },
    rot: {
      x: function(p, rot) {
        return {
          x: p.x,
          y: p.y * Math.cos(dtr(rot.x)) - p.z * Math.sin(dtr(rot.x)),
          z: p.y * Math.sin(dtr(rot.x)) + p.z * Math.cos(dtr(rot.x))
        };
      },
      y: function(p, rot) {
        return {
          x: p.x * Math.cos(dtr(rot.y)) + p.z * Math.sin(dtr(rot.y)),
          y: p.y,
          z: -p.x * Math.sin(dtr(rot.y)) + p.z * Math.cos(dtr(rot.y))
        };
      },
      z: function(p, rot) {
        return {
          x: p.x * Math.cos(dtr(rot.z)) - p.y * Math.sin(dtr(rot.z)),
          y: p.x * Math.sin(dtr(rot.z)) + p.y * Math.cos(dtr(rot.z)),
          z: p.z
        };
      }
    },
    pos: function(p, pos) {
      return {
        x: p.x + pos.x,
        y: p.y + pos.y,
        z: p.z + pos.z
      };
    }
  },
  vp: {
    phi: function(p) {
      return {
        x: p.x * cam.ang.phic + p.z * cam.ang.phis,
        y: p.y,
        z: p.x * -cam.ang.phis + p.z * cam.ang.phic
      };
    },
    theta: function(p) {
      return {
        x: p.x,
        y: p.y * cam.ang.thetac - p.z * cam.ang.thetas,
        z: p.y * cam.ang.thetas + p.z * cam.ang.thetac
      };
    },
    resvp: function(p) {
      return {
        x: p.x - cam.prime.x,
        y: p.y - cam.prime.y,
        z: p.z - cam.prime.z
      };
    }
  },
  persp: function(p) {
    return {
      x: p.x * cam.dst.z / p.z * cam.zoom,
      y: p.y * cam.dst.z / p.z * cam.zoom,
      z: p.z * cam.zoom,
      p: cam.dst.z / p.z
    };
  },
  disp: function(p, disp) {
    return {
      x: p.x + disp.x,
      y: -p.y + disp.y,
      z: p.z + disp.z,
      p: p.p
    };
  },
  calc: function(obj, sz, rot, pos, disp) {
    var ret = trans.parts.sz(obj, sz);
    ret = trans.parts.rot.x(ret, rot);
    ret = trans.parts.rot.y(ret, rot);
    ret = trans.parts.rot.z(ret, rot);
    ret = trans.parts.pos(ret, pos);
    ret = trans.vp.phi(ret);
    ret = trans.vp.theta(ret);
    ret = trans.vp.resvp(ret);
    ret = trans.persp(ret);
    ret = trans.disp(ret, disp);
    return ret;
  }
};

(function() {

  var Verts = function(par) {
    this.transIn = {};
    this.transOut = {};
    this.transIn.vtx = (par.vtx);
    this.transIn.sz = (par.sz);
    this.transIn.rot = (par.rot);
    this.transIn.pos = (par.pos);
  };

  Verts.prototype.updvtx = function() {
    this.transOut = trans.calc(
      this.transIn.vtx,
      this.transIn.sz,
      this.transIn.rot,
      this.transIn.pos,
      cam.disp
    );
  };

  var Obj = function() {

    this.vel = ;
    this.maxt = ;
    this.diff = ;
    this.pos = ;

    this.tx = _x;
    this.ty = _y;
    this.u = ;
    this.set();

  };

  Obj.prototype.set = function() {
    this.c = c;
    this.$ = $;
    this.v = [];
    this.dist = [];
    this.reps = [];

    for (var i = , len = num; i < len; i++) {
      this.v[i] = new Verts({
        vtx: {
          x: rnd(),
          y: rnd(),
          z: rnd()
        },
        sz: {
          x: ,
          y: ,
          z: 
        },
        rot: {
          x: ,
          y: -,
          z: 
        },
        pos: {
          x: this.diff * Math.sin( * Math.random() * Math.PI / ),
          y: this.diff * Math.sin( * Math.random() * Math.PI / ),
          z: this.diff * Math.sin( * Math.random() * Math.PI / )
        }
      });
      this.reps[i] = {
        x:  * Math.random(),
        y:  * Math.random(),
        z:  * Math.random()
      };
    }

    this.rots = {
      x: ,
      y: ,
      z: 
    };

    this.size = {
      x: w / ,
      y: h / ,
      z: w / 
    };
  };

  Obj.prototype.obj = function() {
    this.v.push(new Verts({
      vtx: {
        x: rnd(),
        y: rnd(),
        z: rnd()
      },
      sz: {
        x: ,
        y: ,
        z: 
      },
      rot: {
        x: ,
        y: -,
        z: 
      },
      pos: {
        x: this.diff * Math.sin( * Math.random() * Math.PI / ),
        y: this.diff * Math.sin( * Math.random() * Math.PI / ),
        z: this.diff * Math.sin( * Math.random() * Math.PI / )
      }
    }));
    this.reps.push({
      x:  * Math.random(),
      y:  * Math.random(),
      z:  * Math.random()
    });
  };

  Obj.prototype.upd = function() {
    cam.prime.x += (this.tx - cam.prime.x) * ;
    cam.prime.y += (this.ty - cam.prime.y) * ;
  };

  Obj.prototype.draw = function() {
    this.$.clearRect(, , this.c.width, this.c.height);
    cam.upd();
    this.rots.x += ;
    this.rots.y += ;
    this.rots.z += ;

    for (var i = ; i < this.v.length; i++) {

      for (var val in this.reps[i]) {
        if (this.reps[i].hasOwnProperty(val)) {
          this.reps[i][val] += this.vel;
          if (this.reps[i][val] > this.maxt) this.reps[i][val] = ;
        }
      }

      this.v[i].transIn.pos = {
        x: this.diff * Math.cos(this.reps[i].x * Math.PI / ),
        y: this.diff * Math.sin(this.reps[i].y * Math.PI / ),
        z: this.diff * Math.sin(this.reps[i].z * Math.PI / )
      };

      this.v[i].transIn.rot = this.rots;
      this.v[i].transIn.sz = this.size;
      this.v[i].updvtx();

      if (this.v[i].transOut.p < ) continue;
      this.$.drawImage(_c, this.v[i].transOut.x, this.v[i].transOut.y, this.v[i].transOut.p * , this.v[i].transOut.p * );

    }

  };

  Obj.prototype.loop = function() {
    window.requestAnimationFrame = (function() {
      return window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.oRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        function(callback, element) {
          window.setTimeout(callback,  / );
        };
    })();

    var loop = function() {
      this.upd();
      this.draw();
      window.requestAnimationFrame(loop);
    }.bind(this);
    loop();
  };

  Obj.prototype.run = function() {

    this.loop();

    window.addEventListener('mousemove', function(e) {
      this.tx = (e.clientX - this.c.width / ) * -;
      this.ty = (e.clientY - this.c.height / ) * ;
    }.bind(this));

    window.addEventListener('touchmove', function(e) {
      e.preventDefault();
      this.tx = (e.touches[].clientX - this.c.width / ) * -;
      this.ty = (e.touches[].clientY - this.c.height / ) * ;
    }.bind(this));

  };
  var o = new Obj();
  o.run();
})();
           

继续阅读