H5炫酷特效系列2——canvas特效-炫酷的心

来源:互联网 发布:webstorm运行js代码 编辑:程序博客网 时间:2024/05/16 15:52

之前已经有了一个满屏幕红心的案例,这次带来一个更加炫酷的心型炫酷动效,直接上图,有兴趣的就继续往下看,没兴趣直接过。
这里写图片描述
屏幕上眼花缭乱的心,不停的冲击着你的视线,让那些少女心砰砰直跳,绝对表白利器,同志们可以直接拿去给中意的姑娘看哦。
直接将下面的代码复制运行就可以看到效果:

<!DOCTYPE html><html><head>  <meta charset="utf-8">  <title>炫酷的心</title>  <style type="text/css">    html,    body {      height: 100%;      padding: 0;      margin: 0;      background: #000;    }    canvas {      position: absolute;      width: 100%;      height: 100%;    }  </style></head><body>  <canvas id="pinkboard"></canvas>  <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>  <script type="text/javascript">    var settings = {        particles: {          length: 500, //最大粒子数          duration: 2, //粒子持续时间          velocity: 100, //粒子速度,像素/秒          effect: -0.75,          size: 30, //粒子大小        }      };      (function() {        var b = 0;        var c = ["ms", "moz", "webkit", "o"];        for (var a = 0; a < c.length && !window.requestAnimationFrame; ++a) {          window.requestAnimationFrame = window[c[a] + "RequestAnimationFrame"];          window.cancelAnimationFrame = window[c[a] + "CancelAnimationFrame"] || window[c[a] + "CancelRequestAnimationFrame"]        }        if (!window.requestAnimationFrame) {          window.requestAnimationFrame = function(h, e) {            var d = new Date().getTime();            var f = Math.max(0, 16 - (d - b));            var g = window.setTimeout(function() {              h(d + f)            }, f);            b = d + f;            return g          }        }        if (!window.cancelAnimationFrame) {          window.cancelAnimationFrame = function(d) {            clearTimeout(d)          }        }      }());    var Point = (function() {      function Point(x, y) {        this.x = (typeof x !== 'undefined') ? x : 0;        this.y = (typeof y !== 'undefined') ? y : 0;      }      Point.prototype.clone = function() {        return new Point(this.x, this.y);      };      Point.prototype.length = function(length) {        if (typeof length == 'undefined')          return Math.sqrt(this.x * this.x + this.y * this.y);        this.normalize();        this.x *= length;        this.y *= length;        return this;      };      Point.prototype.normalize = function() {        var length = this.length();        this.x /= length;        this.y /= length;        return this;      };      return Point;    })();    var Particle = (function() {      function Particle() {        this.position = new Point();        this.velocity = new Point();        this.acceleration = new Point();        this.age = 0;      }      Particle.prototype.initialize = function(x, y, dx, dy) {        this.position.x = x;        this.position.y = y;        this.velocity.x = dx;        this.velocity.y = dy;        this.acceleration.x = dx * settings.particles.effect;        this.acceleration.y = dy * settings.particles.effect;        this.age = 0;      };      Particle.prototype.update = function(deltaTime) {        this.position.x += this.velocity.x * deltaTime;        this.position.y += this.velocity.y * deltaTime;        this.velocity.x += this.acceleration.x * deltaTime;        this.velocity.y += this.acceleration.y * deltaTime;        this.age += deltaTime;      };      Particle.prototype.draw = function(context, image) {        function ease(t) {          return (--t) * t * t + 1;        }        var size = image.width * ease(this.age / settings.particles.duration);        context.globalAlpha = 1 - this.age / settings.particles.duration;        context.drawImage(image, this.position.x - size / 2, this.position.y - size / 2, size, size);      };      return Particle;    })();    var ParticlePool = (function() {      var particles,        firstActive = 0,        firstFree = 0,        duration = settings.particles.duration;      function ParticlePool(length) {        // 创建和填充粒子库        particles = new Array(length);        for (var i = 0; i < particles.length; i++)          particles[i] = new Particle();      }      ParticlePool.prototype.add = function(x, y, dx, dy) {        particles[firstFree].initialize(x, y, dx, dy);        // 处理循环队列        firstFree++;        if (firstFree == particles.length) firstFree = 0;        if (firstActive == firstFree) firstActive++;        if (firstActive == particles.length) firstActive = 0;      };      ParticlePool.prototype.update = function(deltaTime) {        var i;        // 更新活动粒子        if (firstActive < firstFree) {          for (i = firstActive; i < firstFree; i++)            particles[i].update(deltaTime);        }        if (firstFree < firstActive) {          for (i = firstActive; i < particles.length; i++)            particles[i].update(deltaTime);          for (i = 0; i < firstFree; i++)            particles[i].update(deltaTime);        }        // 删除不活动的粒子        while (particles[firstActive].age >= duration && firstActive != firstFree) {          firstActive++;          if (firstActive == particles.length) firstActive = 0;        }      };      ParticlePool.prototype.draw = function(context, image) {        // 画活动粒子        if (firstActive < firstFree) {          for (i = firstActive; i < firstFree; i++)            particles[i].draw(context, image);        }        if (firstFree < firstActive) {          for (i = firstActive; i < particles.length; i++)            particles[i].draw(context, image);          for (i = 0; i < firstFree; i++)            particles[i].draw(context, image);        }      };      return ParticlePool;    })();    (function(canvas) {      var context = canvas.getContext('2d'),        particles = new ParticlePool(settings.particles.length),        particleRate = settings.particles.length / settings.particles.duration, // particles/sec        time;      // 获取heart点位 -PI <= t <= PI      function pointOnHeart(t) {        return new Point(          160 * Math.pow(Math.sin(t), 3),          130 * Math.cos(t) - 50 * Math.cos(2 * t) - 20 * Math.cos(3 * t) - 10 * Math.cos(4 * t) + 25        );      }      // 使用canvas创建粒子图像      var image = (function() {        var canvas = document.createElement('canvas'),          context = canvas.getContext('2d');        canvas.width = settings.particles.size;        canvas.height = settings.particles.size;        // 创建路径的辅助函数        function to(t) {          var point = pointOnHeart(t);          point.x = settings.particles.size / 2 + point.x * settings.particles.size / 350;          point.y = settings.particles.size / 2 - point.y * settings.particles.size / 350;          return point;        }        // 创建路径        context.beginPath();        var t = -Math.PI;        var point = to(t);        context.moveTo(point.x, point.y);        while (t < Math.PI) {          t += 0.01;          point = to(t);          context.lineTo(point.x, point.y);        }        context.closePath();        // 填充        context.fillStyle = '#ea80b0';        context.fill();        // 创建图片        var image = new Image();        image.src = canvas.toDataURL();        return image;      })();      // 渲染      function render() {        requestAnimationFrame(render);        // update time        var newTime = new Date().getTime() / 1000,          deltaTime = newTime - (time || newTime);        time = newTime;        // clear canvas        context.clearRect(0, 0, canvas.width, canvas.height);        // 创建新的粒子        var amount = particleRate * deltaTime;        for (var i = 0; i < amount; i++) {          var pos = pointOnHeart(Math.PI - 2 * Math.PI * Math.random());          var dir = pos.clone().length(settings.particles.velocity);          particles.add(canvas.width / 2 + pos.x, canvas.height / 2 - pos.y, dir.x, -dir.y);        }        // 更新并绘制        particles.update(deltaTime);        particles.draw(context, image);      }      // 处理canvas大小      function onResize() {        canvas.width = canvas.clientWidth;        canvas.height = canvas.clientHeight;      }      window.onresize = onResize;      // 延迟渲染      setTimeout(function() {        onResize();        render();      }, 10);    })(document.getElementById('pinkboard'));  </script></body></html>
原创粉丝点击