<!--

Follow me on
Instagram: https://www.instagram.com/kevgutierrez_/
ORCID: https://orcid.org/0009-0005-6780-1106
Pinterest: https://www.pinterest.es/KevinGutierrez__/
Codepen: https://codepen.io/Kevin_Gutier09
Figshare: https://figshare.com/authors/Kevin_Guti_rrez/19729930
Github Gist: https://gist.github.com/Kahernandezg

© Credits to: Kevin Gutierrez.
Design Original: Marco Dell'Anna
-->
<div class="content">
    <div class="title">
      <h1>MICELIO</h1>
      <h3><b>Plataforma para<span> la investigación </span></h>
    </div>
  </div>
  <div class="more-pens">
    <a target="_blank" href="https://micelio.uca.edu.sv/home" class="white-mode">INGRESAR A MICELIO</a>
  </div>
  <!-- END Codepen -->
=transform($prop)
  -webkit-transform: $prop
  -moz-transform: $prop
  -ms-transform: $prop
  -o-transform: $prop
  transform: $prop


@import url('https://fonts.googleapis.com/css?family=Catamaran:300,400,500,600,700')
.more-pens
  position: fixed
  right: 20px
  bottom: 20px
  z-index: 10
  font-family: 'Catamaran', sans-serif
  font-size: 12px

a.white-mode, a.white-mode:link, a.white-mode:visited, a.white-mode:active
  font-family: 'Catamaran', sans-serif
  font-size: 12px
  text-decoration: none
  background: #212121
  padding: 8px 18px
  color: #f7f7f7
  border-radius: 20px
  margin: 0 4px

  &:hover
    background: #DDDDDD
    color: #FDBF18

body
  margin: 0
  padding: 0
  overflow: hidden
  width: 100%
  height: 100%
  background: #FFF

.content
  z-index: 10
  position: absolute
  left: 0
  top: 0
  padding: 0
  text-align: center
  width: 100vw
  height: 100vh


.title
  z-index: 10
  position: absolute
  left: 50%
  top: 50%
  transform: translateX(-50%) translateY(-50%)
  font-family: "Montserrat"
  text-align: center
  width: 100%
  h1
    position: relative
    color: #EEEEEE
    font-weight: 800
    font-size: 90px
    padding: 0
    margin: 0
    line-height: 1
    text-shadow: 0 0 30px #000155
  

  h3
    font-weight: 200
    font-size: 30px
    padding: 0
    margin: 0
    line-height: 1
    color: #EEEEEE
    letter-spacing: 2px
    text-shadow: 0 0 30px #000155
    span
      font-weight: 700
View Compiled
class Particles{
  static initClass() {
    this.prototype.defaults = {
      speed: 1.8,
      radius: 25,
      innerColor: "#234980",
      outerColor: "#111111",
      aroundColor: "#FFF",
      innerColorHero: "#e58314",
      outerColorHero: "#FDBF18",
      aroundColorHero: "#FFF",
      aroundme: false,
      speedAroudme: 3,
      offsetAroudme: 0,
      hero: false,
      onCreate: function(){},
      onDead: function(){}
    };
  }

  constructor(canvas, options){
    Particles.initClass();
    //
    this.options  = $.extend({}, this.defaults, options );


    let timeout,
        random,
        startAngle,
        progress,
        direction,
        currentRadius,
        oldx,
        oldy,
        x,
        y,
        w,
        h;

    // Set default value
    this.canvas     = canvas;
    this.timeout    = false;
    this.random     = Math.random();
    this.startAngle = this.random * 360;
    this.w          = 0;
    this.h          = 0;
    this.progress   = 0;
    this.direction  = 0;
    this.currentRadius = 0;

    if( this.options.hero )
      this.options.offsetAroudme = 20

    // Init dimensions
    this.getWindowDimensions();

    // Initial position
    this.x = Math.floor(Math.random() * this.w);
    this.y = Math.floor(Math.random() * this.h);

    // init Behaviours
    this.behaviours();
    this.options.onCreate(this.options);
  }

  behaviours(){
    // window.resize event listener
    window.addEventListener('resize', function() {
      this.getWindowDimensions()
    }.bind(this));
  }

  render(){
    // this.getWindowDimensions();
    this.drawFirstParticle();
    this.drawSecondParticleAroundMe();
    this.nextPosition();
    this.progress++;
  }

  drawFirstParticle(){
    // Set current dimension radius
    this.currentRadius = Math.min(this.progress/2, this.options.radius);
    // GRADIENT
    let grd = this.canvas.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.currentRadius);
    if(this.options.hero == true){
      grd.addColorStop(0, this.options.innerColorHero);
      grd.addColorStop(1, this.options.outerColorHero);
    }else{
      grd.addColorStop(0, this.options.innerColor);
      grd.addColorStop(1, this.options.outerColor);
    }

    // Draw first circle
    this.canvas.beginPath();
    this.canvas.arc(this.x, this.y, this.currentRadius, 0, 2 * Math.PI);
    this.canvas.lineWidth = 1;
    this.canvas.fillStyle = grd;
    this.canvas.fill();
    this.canvas.closePath();
    return;
  }
  drawSecondParticleAroundMe(){
    if( !this.options.aroundme ) return;

    let color = this.options.hero == true ? this.options.aroundColorHero : this.options.aroundColor;;
    let angle = (this.progress*this.options.speedAroudme + this.startAngle) * Math.PI / 180;
    let x = this.x + Math.cos(angle)*(this.currentRadius-1 + this.options.offsetAroudme);
    let y = this.y + Math.sin(angle)*(this.currentRadius-1 + this.options.offsetAroudme);
    // this.canvas.beginPath();
    // this.canvas.arc(x, y, 1, 0, 2 * Math.PI);
    // this.canvas.lineWidth = 1;
    // this.canvas.fillStyle = color;
    // this.canvas.fill();
    // this.canvas.closePath();

    if(this.oldx){
      this.canvas.beginPath();
      this.canvas.moveTo(this.oldx, this.oldy);
      this.canvas.lineTo(x, y);
      this.canvas.strokeStyle = color;
      this.canvas.lineWidth = 1;
      this.canvas.stroke();
    }

    this.oldx = x;
    this.oldy = y;

    return;
  }

  nextPosition(){
    this.x += Math.cos(this.direction ) * this.options.speed;
    this.y += Math.sin(this.direction ) * this.options.speed;
    this.direction  += Math.random() * 0.7 - 0.32;
    return;
  }

  move(){
    this.render()
    return this.isInBound();
  }

  isInBound(){
    // console.log(this.w)
    if(
        this.x < -this.options.radius ||
        this.x > this.w + this.options.radius ||
        this.y < -this.options.radius ||
        this.y > this.h + this.options.radius
      ){
      this.options.onDead(this.options);
      return false
    }
    return true
  }

  getWindowDimensions(){
    this.w = window.innerWidth;
    this.h = window.innerHeight;
  }
}

var tela = document.createElement('canvas');
    $("body").append(tela);

    let canvas = tela.getContext('2d');

// ---------------------------

let config = {
    maxParticles: 100,
    maxHeros: 50,
    speedAroudme: 1.8,
    offsetAroudme: 1
  }

let dimensions = {
  width: 0,
  height: 0
}

let heros = 0;
let data_particles =[];

function setWindowSize(){
  dimensions.width  = $(window).width();
  dimensions.height = $(window).height();
  tela.width = dimensions.width;
  tela.height = dimensions.height;
}

function popolate(num){
  for (var i = 0; i < num; i++) {
    let isHero = false;
    if(heros < config.maxHeros){
      isHero = true;
    }
    data_particles.push(new Particles(canvas, {
      speed: .8,
      radius: Math.round(18 + (Math.random() * 40)),
      aroundme: true,
      hero: isHero,
      speedAroudme: config.speedAroudme,
      offsetAroudme: config.offsetAroudme,
      onCreate: function(data){
        if( data.hero == true )
          heros++;
      },
      onDead: function(data){
        if( data.hero == true )
          heros--;
      }
    }))
  }
  return data_particles.length
}

  function clear(){
    canvas.globalAlpha = 0.018;
    canvas.fillStyle = '#181719';
    canvas.fillRect(0, 0, dimensions.width, dimensions.height);
    canvas.globalAlpha = 1;
  }

  function update(){
    clear();
    data_particles = data_particles.filter(function(p) {
      return p.move()
    })
    if(data_particles.length < config.maxParticles){
      popolate(1)
    }
    requestAnimationFrame(update)
  }


setWindowSize()
popolate(config.maxParticles)
update()

$(window).resize(setWindowSize)
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://code.jquery.com/jquery-2.2.4.min.js