Friday, November 22, 2024

Hướng dẫn code trái tim

-

Gần đây mạng xã hội truyền tai nhau thông tin về code trái tim đập tỏ tình với crush rất đẹp mắt, nay theo yêu cầu của vợ mình nên mình sẽ làm 1 cái cho biết.

1. Mẫu 1.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
 <HEAD>
  <TITLE> Trai tim </TITLE>
  <META NAME="Generator" CONTENT="EditPlus">
  <META NAME="Author" CONTENT="">
  <META NAME="Keywords" CONTENT="">
  <META NAME="Description" CONTENT="">
  <link rel="stylesheet" href="style.css">
  <style>
  html, body {
  height: 100%;
  padding: 0;
  margin: 0;
  background: rgba(0, 0, 0, 0.851);
}
canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}
  </style>
 </HEAD>
 <BODY>
  <div class="box">
    <canvas id="pinkboard"></canvas>
  </div>
<script>
var settings = {
  particles: {
    length:   10000, // maximum amount of particles
    duration:   4, // particle duration in sec
    velocity: 80, // particle velocity in pixels/sec
    effect: -1.3, // play with this for a nice effect
    size:      8, // particle size in pixels
  },
};
/*
 */
(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)}}}());
/*
 * Point class
 */
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;
})();
/*
 * Particle class
 */
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;
})();
/*
 * ParticlePool class
 */
var ParticlePool = (function() {
  var particles,
      firstActive = 0,
      firstFree   = 0,
      duration    = settings.particles.duration;
 
  function ParticlePool(length) {
    // create and populate particle pool
    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);
   
    // handle circular queue
    firstFree++;
    if (firstFree   == particles.length) firstFree   = 0;
    if (firstActive == firstFree       ) firstActive++;
    if (firstActive == particles.length) firstActive = 0;
  };
  ParticlePool.prototype.update = function(deltaTime) {
    var i;
   
    // update active particles
    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);
    }
   
    // remove inactive particles
    while (particles[firstActive].age >= duration && firstActive != firstFree) {
      firstActive++;
      if (firstActive == particles.length) firstActive = 0;
    }
   
   
  };
  ParticlePool.prototype.draw = function(context, image) {
    // draw active particles
    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;
})();
/*
 * Putting it all together
 */
(function(canvas) {
  var context = canvas.getContext('2d'),
      particles = new ParticlePool(settings.particles.length),
      particleRate = settings.particles.length / settings.particles.duration, // particles/sec
      time;
 
  // get point on heart with -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
    );
  }
 
  // creating the particle image using a dummy canvas
  var image = (function() {
    var canvas  = document.createElement('canvas'),
        context = canvas.getContext('2d');
    canvas.width  = settings.particles.size;
    canvas.height = settings.particles.size;
    // helper function to create the path
    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;
    }
    // create the path
    context.beginPath();
    var t = -Math.PI;
    var point = to(t);
    context.moveTo(point.x, point.y);
    while (t < Math.PI) {
      t += 0.01; // baby steps!
      point = to(t);
      context.lineTo(point.x, point.y);
    }
    context.closePath();
    // create the fill
    context.fillStyle = '#f50b02';
    context.fill();
    // create the image
    var image = new Image();
    image.src = canvas.toDataURL();
    return image;
  })();
 
  // render that thing!
  function render() {
    // next animation frame
    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);
   
    // create new particles
    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);
    }
   
    // update and draw particles
    particles.update(deltaTime);
    particles.draw(context, image);
  }
 
  // handle (re-)sizing of the canvas
  function onResize() {
    canvas.width  = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
  }
  window.onresize = onResize;
 
  // delay rendering bootstrap
  setTimeout(function() {
    onResize();
    render();
  }, 10);
})(document.getElementById('pinkboard'));
  </script>
 </BODY>
</HTML>

2. Mẫu 2.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

 <HEAD>

  <TITLE> New Document </TITLE>

  <META NAME="Generator" CONTENT="EditPlus">

  <META NAME="Author" CONTENT="">

  <META NAME="Keywords" CONTENT="">

  <META NAME="Description" CONTENT="">

  <style>

  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>

  /*

 * Settings

 */

var settings = {

  particles: {

    length:   500, // maximum amount of particles

    duration:   2, // particle duration in sec

    velocity: 100, // particle velocity in pixels/sec

    effect: -0.75, // play with this for a nice effect

    size:      30, // particle size in pixels

  },

};


/*

 * RequestAnimationFrame polyfill by Erik Möller

 */

(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)}}}());


/*

 * Point class

 */

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;

})();


/*

 * Particle class

 */

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;

})();


/*

 * ParticlePool class

 */

var ParticlePool = (function() {

  var particles,

      firstActive = 0,

      firstFree   = 0,

      duration    = settings.particles.duration;

 

  function ParticlePool(length) {

    // create and populate particle pool

    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);

   

    // handle circular queue

    firstFree++;

    if (firstFree   == particles.length) firstFree   = 0;

    if (firstActive == firstFree       ) firstActive++;

    if (firstActive == particles.length) firstActive = 0;

  };

  ParticlePool.prototype.update = function(deltaTime) {

    var i;

   

    // update active particles

    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);

    }

   

    // remove inactive particles

    while (particles[firstActive].age >= duration && firstActive != firstFree) {

      firstActive++;

      if (firstActive == particles.length) firstActive = 0;

    }

   

   

  };

  ParticlePool.prototype.draw = function(context, image) {

    // draw active particles

    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;

})();


/*

 * Putting it all together

 */

(function(canvas) {

  var context = canvas.getContext('2d'),

      particles = new ParticlePool(settings.particles.length),

      particleRate = settings.particles.length / settings.particles.duration, // particles/sec

      time;

 

  // get point on heart with -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

    );

  }

 

  // creating the particle image using a dummy canvas

  var image = (function() {

    var canvas  = document.createElement('canvas'),

        context = canvas.getContext('2d');

    canvas.width  = settings.particles.size;

    canvas.height = settings.particles.size;

    // helper function to create the path

    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;

    }

    // create the path

    context.beginPath();

    var t = -Math.PI;

    var point = to(t);

    context.moveTo(point.x, point.y);

    while (t < Math.PI) {

      t += 0.01; // baby steps!

      point = to(t);

      context.lineTo(point.x, point.y);

    }

    context.closePath();

    // create the fill

    context.fillStyle = '#ea80b0';

    context.fill();

    // create the image

    var image = new Image();

    image.src = canvas.toDataURL();

    return image;

  })();

 

  // render that thing!

  function render() {

    // next animation frame

    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);

   

    // create new particles

    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);

    }

   

    // update and draw particles

    particles.update(deltaTime);

    particles.draw(context, image);

  }

 

  // handle (re-)sizing of the canvas

  function onResize() {

    canvas.width  = canvas.clientWidth;

    canvas.height = canvas.clientHeight;

  }

  window.onresize = onResize;

 

  // delay rendering bootstrap

  setTimeout(function() {

    onResize();

    render();

  }, 10);

})(document.getElementById('pinkboard'));

  </script>

 </BODY>

</HTML>

3. Mẫu 3.

Tạo file index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@200;300;400;600&display=swap" rel="stylesheet">
    <link href="css/main.css" rel="stylesheet">
  </head>

  <body>
    <!-- <audio autoplay="autopaly">
      <source src="renxi.mp3" type="audio/mp3" />
    </audio> -->
    <!-- 星空html -->
    <!-- <div> -->
    <div class="container2">
      <div class="content">
        <canvas id="universe"></canvas>
      </div>
    </div>
    <!-- </div> -->
    <div class="title">
      <!-- EDIT HERE -->
      <h3 class="STARDUST1">12/12/2020</h3>
      <h1 class="STARDUST2">HOANG & NHUNG</h1>
      <h3 class="STARDUST3">L O V E <strong>❤</strong> Y O U</h3>
      <img class="img" src="hoanghd.jpeg" alt="JUNO_OKYO" />
      <canvas id="pinkboard"></canvas>
    </div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="js/main.js"></script>
    <script src="js/particle.js"></script>
    <script src="js/universe.js"></script>
  </body>
</html>

Tạo thư mục css và sau đó tạo file main.css nằm trong thư mục css.

.more-pens {
  position: fixed;
  left: 20px;
  bottom: 20px;
  z-index: 10;
  font-family: "Montserrat";
  font-size: 12px;
}

a.white-mode, a.white-mode:link, a.white-mode:visited, a.white-mode:active {
  font-family: "Montserrat";
  font-size: 12px;
  text-decoration: none;        /* background: #212121; */
  padding: 4px 8px;
  color: #f7f7f7;
}

a.white-mode:hover, a.white-mode:link:hover, a.white-mode:visited:hover, a.white-mode:active:hover {
  background: #edf3f8;
  color: #212121;
}

.title {
  z-index: 9999 !important;
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translateX(-50%) translateY(-50%);
  font-family: "Montserrat";
  text-align: center;
  width: 100%;
}

.title h1 {
  z-index: 99;
  position: relative;
  color: #fff;
  font-weight: 100;
  font-size: 70px;
  padding: 0;
  margin: 0;
  line-height: 1;
  text-shadow: 0 0 10px #ff006c, 0 0 20px #ff006c, 0 0 30px #ff006c, 0 0 40px #ff417d, 0 0 70px #ff417d, 0 0 80px #ff417d, 0 0 100px #ff417d, 0 0 150px #ff417d;
}

.title h1 span {
  z-index: 99;
  font-weight: 600;
  padding: 0;
  margin: 0;
  color: #ffffff;
}

.title h3 {
  z-index: 99;
  font-weight: 200;
  font-size: 26px;
  padding: 0;
  margin: 0;
  line-height: 1;
  color: #ffffff;
  letter-spacing: 2px;
}

/* 爱心css */
canvas {
  position: absolute;
  width: 100%;
  height: 100%;
}

.img {
  position: absolute;
  left: 50%;
  top: 60%;
  transform: translate(-50%, -50%);
  width: 420px;
  height: 420px;
}

#pinkboard {
  position: relative;
  top: 0%;
  left: 0%;
  height: 429px;
}

.STARDUST1 {
  position: relative !important;
  top: -60px;
}

.STARDUST2 {
  position: relative !important;
  top: -40px;
}

.STARDUST3 {
  position: relative !important;
  top: -20px;
}

/* 星空css */
html, body {
  padding: 0px;
  margin: 0px;
  width: 100%;
  height: 100%;
  position: fixed;
}

body {
  display: flex;
  justify-content: center;
  align-items: center;
  -webkit-filter: contrast(120%);
  filter: contrast(120%);
  background-image: radial-gradient(1600px at 70% 120%, rgba(33, 39, 80, 1) 10%, #020409 100%) !important;        /* background-color: black; */
}

.container2 {

  /* z-index: 8; */
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: radial-gradient(1600px at 70% 120%, rgba(33, 39, 80, 1) 10%, #020409 100%) !important;
}

.content {
  width: inherit;
  height: inherit;
  width: 100%;
  height: 100%;
  background-image: radial-gradient(1600px at 70% 120%, rgba(33, 39, 80, 1) 10%, #020409 100%) !important;
}

#universe {
  width: 100%;
  height: 100%;
}

#footerContent {
  font-family: sans-serif;
  font-size: 110%;
  color: rgba(200, 220, 255, 0.3);
  width: 100%;
  position: fixed;
  bottom: 0px;
  padding: 20px;
  text-align: center;
  z-index: 20;
}

/* #footer {
  position: absolute;
  bottom: 0px;
  height: 300px;
  width: 100%;
} */
#scene {
  height: 100%;
  position: absolute;
  left: 50%;
  margin-left: -800px;
}

a {
  text-decoration: none;
  color: rgba(200, 220, 255, 1);
  opacity: 0.4;
  transition: opacity 0.4s ease;
}

a:hover {
  opacity: 1;
}

/* heart image: https://stackoverflow.com/a/51216413 */
img {

  /* width: 200px; */
  aspect-ratio: 1;
  object-fit: cover;
  --_m: radial-gradient(#000 69%, #0000 70%) 84.5% fill/100%;
  -webkit-mask-box-image: var(--_m);
  mask-border: var(--_m);
  clip-path: polygon(-41% 0, 50% 91%, 141% 0);
}

Tại thư mục gốc hãy tạo thư mục js và sau đó bạn hãy tạo 3 file main.js, particle.js, universe.js nằm trong thư mục js.

– Nội dung file main.js.

let particles = [];
let microparticles = [];

const c1 = createCanvas({
  width: $(window).width(),
  height: $(window).height(),
});

const tela = c1.canvas;
const canvas = c1.context;

// $("body").append(tela);
$("body").append(c1.canvas);

class Particle1 {
  constructor(canvas) {
    this.random = Math.random();
    this.random1 = Math.random();
    this.random2 = Math.random();
    this.progress = 0;
    this.canvas = canvas;
    this.life = 1000 + Math.random() * 3000;

    this.x =
      $(window).width() / 2 + (Math.random() * 20 - Math.random() * 20);
    this.y = $(window).height();
    this.s = 2 + Math.random();
    this.w = $(window).width();
    this.h = $(window).height();
    this.direction = this.random > 0.5 ? -1 : 1;
    this.radius = 1 + 3 * this.random;
    this.color = "#ff417d";

    this.ID = setInterval(
      function() {
        microparticles.push(
          new microParticle(c1.context, {
            x: this.x,
            y: this.y,
          })
        );
      }.bind(this),
      this.random * 20
    );

    setTimeout(
      function() {
        clearInterval(this.ID);
      }.bind(this),
      this.life
    );
  }

  render() {
    this.canvas.beginPath();
    this.canvas.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    // this.canvas.lineWidth = 2;
    this.canvas.shadowOffsetX = 0;
    this.canvas.shadowOffsetY = 0;
    // this.canvas.shadowBlur = 6;
    this.canvas.shadowColor = "#000000";
    this.canvas.fillStyle = this.color;
    this.canvas.fill();
    this.canvas.closePath();
  }

  move() {
    this.x -=
      this.direction *
      Math.sin(this.progress / (this.random1 * 430)) *
      this.s;
    this.y -= Math.cos(this.progress / this.h) * this.s;

    if (this.x < 0 || this.x > this.w - this.radius) {
      clearInterval(this.ID);
      return false;
    }

    if (this.y < 0) {
      clearInterval(this.ID);
      return false;
    }
    this.render();
    this.progress++;
    return true;
  }
}

class microParticle {
  constructor(canvas, options) {
    this.random = Math.random();
    this.random1 = Math.random();
    this.random2 = Math.random();
    this.progress = 0;
    this.canvas = canvas;

    this.x = options.x;
    this.y = options.y;
    this.s = 2 + Math.random() * 3;
    this.w = $(window).width();
    this.h = $(window).height();
    this.radius = 1 + this.random * 0.5;
    this.color = "#4EFCFE"; //this.random > .5 ? "#a9722c" : "#FFFED7"
  }

  render() {
    this.canvas.beginPath();
    this.canvas.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
    this.canvas.lineWidth = 2;
    this.canvas.fillStyle = this.color;
    this.canvas.fill();
    this.canvas.closePath();
  }

  move() {
    this.x -=
      Math.sin(this.progress / (100 / (this.random1 - this.random2 * 10))) *
      this.s;
    this.y += Math.cos(this.progress / this.h) * this.s;

    if (this.x < 0 || this.x > this.w - this.radius) {
      return false;
    }

    if (this.y > this.h) {
      return false;
    }
    this.render();
    this.progress++;
    return true;
  }
}

var random_life = 1000;

setInterval(
  function() {
    particles.push(new Particle1(canvas));
    random_life = 2000 * Math.random();
  }.bind(this),
  random_life
);

function clear() {
  let grd = canvas.createRadialGradient(
    tela.width / 2,
    tela.height / 2,
    0,
    tela.width / 2,
    tela.height / 2,
    tela.width
  );
  grd.addColorStop(0, "rgba(20,20,20,1)");
  grd.addColorStop(1, "rgba(0,0,0,0)");
  // Fill with gradient
  canvas.globalAlpha = 0.16;
  canvas.fillStyle = grd;
  canvas.fillRect(0, 0, tela.width, tela.height);
}

function blur(ctx, canvas, amt) {
  // ctx.filter = `blur(${amt}px)`
  // ctx.drawImage(canvas, 0, 0)
  // ctx.filter = 'none'
}

function update() {
  clear();
  particles = particles.filter(function(p) {
    return p.move();
  });
  microparticles = microparticles.filter(function(mp) {
    return mp.move();
  });
  requestAnimationFrame(update.bind(this));
}

function createCanvas(properties) {
  let canvas = document.createElement("canvas");
  canvas.width = properties.width;
  //   canvas.style.zIndex = 999;
  canvas.height = properties.height;
  let context = canvas.getContext("2d");
  return {
    canvas: canvas,
    context: context,
  };
}

update();

– Nội dung file particle.js.

/*
 * Settings
 */
var settings = {
  particles: {
    length: 500, // maximum amount of particles
    duration: 2, // particle duration in sec
    velocity: 100, // particle velocity in pixels/sec
    effect: -0.75, // play with this for a nice effect
    size: 30, // particle size in pixels
  },
};

/*
 * RequestAnimationFrame polyfill by Erik M?ller
 */
(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);
    };
  }
})();

/*
 * Point class
 */
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;
})();

/*
 * Particle class
 */
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;
})();

/*
 * ParticlePool class
 */
var ParticlePool = (function() {
  var particles,
    firstActive = 0,
    firstFree = 0,
    duration = settings.particles.duration;

  function ParticlePool(length) {
    // create and populate particle pool
    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);

    // handle circular queue
    firstFree++;
    if (firstFree == particles.length) firstFree = 0;
    if (firstActive == firstFree) firstActive++;
    if (firstActive == particles.length) firstActive = 0;
  };
  ParticlePool.prototype.update = function(deltaTime) {
    var i;

    // update active particles
    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);
    }

    // remove inactive particles
    while (
      particles[firstActive].age >= duration &&
      firstActive != firstFree
    ) {
      firstActive++;
      if (firstActive == particles.length) firstActive = 0;
    }
  };
  ParticlePool.prototype.draw = function(context, image) {
    // draw active particles
    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;
})();

/*
 * Putting it all together
 */
(function(canvas) {
  var context = canvas.getContext("2d"),
    particles = new ParticlePool(settings.particles.length),
    particleRate = settings.particles.length / settings.particles.duration, // particles/sec
    time;

  // get point on heart with -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
    );
  }

  // creating the particle image using a dummy canvas
  var image = (function() {
    var canvas = document.createElement("canvas"),
      context = canvas.getContext("2d");
    canvas.width = settings.particles.size;
    canvas.height = settings.particles.size;
    // helper function to create the path
    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;
    }
    // create the path
    context.beginPath();
    var t = -Math.PI;
    var point = to(t);
    context.moveTo(point.x, point.y);
    while (t < Math.PI) {
      t += 0.01; // baby steps!
      point = to(t);
      context.lineTo(point.x, point.y);
    }
    context.closePath();
    // create the fill
    context.fillStyle = "#ea80b0";
    context.fill();
    // create the image
    var image = new Image();
    image.src = canvas.toDataURL();
    return image;
  })();

  // render that thing!
  function render() {
    // next animation frame
    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);

    // create new particles
    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
      );
    }

    // update and draw particles
    particles.update(deltaTime);
    particles.draw(context, image);
  }

  // handle (re-)sizing of the canvas
  function onResize() {
    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;
  }
  window.onresize = onResize;

  // delay rendering bootstrap
  setTimeout(function() {
    onResize();
    render();
  }, 10);
})(document.getElementById("pinkboard"));

– Nội dung file universe.js.

window.requestAnimationFrame =
  window.requestAnimationFrame ||
  window.mozRequestAnimationFrame ||
  window.webkitRequestAnimationFrame ||
  window.msRequestAnimationFrame;



this.draw = function() {
  universe.beginPath();

  if (this.giant) {
    universe.fillStyle = "rgba(" + giantColor + "," + this.opacity + ")";
    universe.arc(this.x, this.y, 2, 0, 2 * Math.PI, false);
  } else if (this.comet) {
    universe.fillStyle = "rgba(" + cometColor + "," + this.opacity + ")";
    universe.arc(this.x, this.y, 1.5, 0, 2 * Math.PI, false);

    //comet tail
    for (var i = 0; i < 30; i++) {
      universe.fillStyle =
        "rgba(" +
        cometColor +
        "," +
        (this.opacity - (this.opacity / 20) * i) +
        ")";
      universe.rect(
        this.x - (this.dx / 4) * i,
        this.y - (this.dy / 4) * i - 2,
        2,
        2
      );
      universe.fill();
    }
  } else {
    universe.fillStyle = "rgba(" + starColor + "," + this.opacity + ")";
    universe.rect(this.x, this.y, this.r, this.r);
  }

  universe.closePath();
  universe.fill();
};

this.move = function() {
  this.x += this.dx;
  this.y += this.dy;
  if (this.fadingOut === false) {
    this.reset();
  }
  if (this.x > width - width / 4 || this.y < 0) {
    this.fadingOut = true;
  }
};

(function() {
  setTimeout(function() {
    first = false;
  }, 50);
})();


function getProbability(percents) {
  return Math.floor(Math.random() * 1000) + 1 < percents * 10;
}

function getRandInterval(min, max) {
  return Math.random() * (max - min) + min;
}

function windowResizeHandler() {
  width = window.innerWidth;
  height = window.innerHeight;
  starCount = width * starDensity;
  circleRadius = width > height ? height / 2 : width / 2;
  circleCenter = {
    x: width / 2,
    y: height / 2,
  };

  canva.setAttribute("width", width);
  canva.setAttribute("height", height);
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories