注册 登录 充值会员 退出
毕业设计 PHP源码
充值

HTML5 Canvas炫酷3D线条延伸动画特效

作者/代码整理:  (转载请附加本文地址,带有“懒人原生”字样的谢绝转载) 发布日期:2018-01-18
HTML5 Canvas炫酷3D线条延伸动画特效
这是一款基于HTML5 Canvas绘制的炫酷3D线条延伸动画特效,多彩颜色变幻,非常漂亮!


js代码

<script>
;(function() {
  'use strict';
  var c = document.getElementById('c');
  var ctx = c.getContext('2d');
  var w = c.width = window.innerWidth;
  var h = c.height = window.innerHeight;
  var cx = w / 2;
  var cy = h / 2;
  var fl = 1000;
  
  function prj(obj) {
    var cz = obj.z + fl;
    if(cz === 0) return;
    var scl = fl / cz;
    obj.p.x = cx + obj.x * scl;
    obj.p.y = cy + obj.y * scl;
    obj.s = scl;
  }
  
  var P = function(x, y, z) {
    this.x = x;
    this.y = y;
    this.z = z;
    this.s = 1;
    this.cl = 0;
    this.p = {
      x: 0,
      y: 0
    };
  };
  P.prototype = {
    constructor: P,
    update: function() {
      this.z -= 30;
    },
    render: function(ctx) {
      if(this.z <= -fl) return;
      ctx.save();
      ctx.translate(this.p.x, this.p.y);
      ctx.scale(this.s, this.s);
      ctx.fillStyle = 'hsla(' + this.cl + ', 100%, 50%, 0.5)';
      ctx.beginPath();
      ctx.arc(0, 0, 2, 0, Math.PI * 2);
      ctx.fill();
      ctx.restore();
    }
  };
  var M = function(x, y, z) {
    this.list = [];
    this.max = 100;
    this.x = x;
    this.y = y;
    this.z = z;
    this.s = 1;
    this.p = {
      x: 0,
      y: 0
    };
    this.ax = Math.random() * (Math.PI * 2);
    this.ay = Math.random() * (Math.PI * 2);
    this.rx = Math.random() * 100;
    this.ry = Math.random() * 100;
    this.cl = Math.random() * 360;
    this.cls = Math.random();
  };
  M.prototype = {
    constructor: M,
    update: function() {
      this.cl += this.cls;
      this.ax += Math.random() * 0.1 - 0.02;
      this.ay += Math.random() * 0.1 - 0.02;
      this.x = Math.cos(this.ax) * 100;
      this.y = Math.sin(this.ay) * 100;
      this.z += 10;
      if(this.z > fl) this.z = fl;
      
      if(this.list.length < this.max) {
        if(Math.random() * 100 < 50) {
          var pp = new P(this.x, this.y, this.z);
          pp.cl = this.cl;
          this.list.push(pp);        
        }
      } else {
        var pp = this.list.shift();
        pp.x = this.x;
        pp.y = this.y;
        pp.z = this.z;
        pp.cl = this.cl;
        this.list.push(pp);
      }
    },
    render: function(ctx) {
      if(this.z <= -fl) return;
      ctx.save();
      ctx.translate(this.p.x, this.p.y);
      ctx.fillStyle = 'green';
      ctx.beginPath();
      ctx.arc(0, 0, 2, 0, Math.PI * 2);
      ctx.fill();
      ctx.restore();
    }
  };
  
  function update(mv, list) {
    for(var i = 0; i < list.length; i++) {
      var p = list[i];
      p.update();
      prj(p);
      p.render(ctx);
    }
    
    for(var i = list.length-1; i >= 0; i--) {
      var p = list[i];
      if(p.z <= -fl) continue;
       if(i === list.length - 1) {
         ctx.lineWidth = Math.random();
         ctx.strokeStyle = 'hsl(' + mv.cl + ', 100%, 50%)';
         ctx.beginPath();
         ctx.moveTo(p.p.x, p.p.y);
       } else {
         ctx.lineTo(p.p.x, p.p.y);
       }
    }
    ctx.stroke();
  }
  
  var ms = [];

  for(var i = 0; i < 10; i++) {
    ms.push(new M(
      Math.random() * 400 - 200, 
      Math.random() * 400 - 200, 
      Math.random() * 400 - 200));
  }

  requestAnimationFrame(function loop() {
    requestAnimationFrame(loop);
    ctx.clearRect(0, 0, w, h);
    
    for(var i = 0; i < ms.length; i++) {
      var m = ms[i];
      m.update();
      prj(m);
      update(m, m.list);
    }
   
  });
})();
</script>