LOADING...

Preview

Pen ID
Unlock Campus Themeforest adv

 

Code

30,000 Particles

A study creating performant particles with Canvas 2D

Use your mouse

CSS
@charset "UTF-8";
@import url(https://fonts.googleapis.com/css?family=Quantico);
html, body {
  background: #111;
}

#container {
  background: #111;
  position: absolute;
  left: 50%;
  top: 50%;
}

#stats {
  position: absolute;
  right: 10px;
  top: 10px;
}

/* Info */
@keyframes show-info {
  0% {
    transform: rotateY(120deg);
  }
  100% {
    transform: rotateY(0deg);
  }
}
.info {
  transition: all 180ms ease-out;
  transform-style: preserve-3d;
  transform: perspective(800px);
  font-family: "Quantico", sans-serif;
  position: absolute;
  font-size: 12px;
  opacity: 0.8;
  color: #fff;
  width: 220px;
  left: 0px;
  top: 20px;
}
.info:hover {
  box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.05);
  opacity: 1;
}
.info h1, .info h2, .info h3 {
  line-height: 1;
  margin: 5px 0;
}
.info a {
  transition: all 200ms ease-out;
  border-bottom: 1px dotted rgba(255, 255, 255, 0.4);
  text-decoration: none;
  opacity: 0.6;
  color: #fff;
}
.info a:hover {
  opacity: 0.99;
}
.info .about,
.info .more {
  transform-origin: 0% 50%;
  transform: rotateY(120deg);
  margin-bottom: 1px;
  background: rgba(0, 0, 0, 0.8);
  padding: 12px 15px 12px 20px;
}
.info .about {
  animation: show-info 500ms cubic-bezier(0.23, 1, 0.32, 1) 600ms 1 normal forwards;
  padding-bottom: 15px;
}
.info .about a {
  opacity: 0.9;
}
.info .about h1 {
  letter-spacing: -1px;
  font-weight: 300;
  font-size: 19px;
  opacity: 0.95;
}
.info .about h2 {
  font-weight: 300;
  font-size: 13px;
  opacity: 0.8;
}
.info .about h3 {
  text-transform: uppercase;
  margin-top: 10px;
  font-size: 11px;
}
.info .about h3:before {
  margin-right: 2px;
  font-size: 14px;
  content: "›";
}
.info .more {
  animation: show-info 500ms cubic-bezier(0.23, 1, 0.32, 1) 500ms 1 normal forwards;
  padding: 5px 15px 10px 20px;
}
.info .more a {
  text-transform: uppercase;
  margin-right: 10px;
  font-size: 10px;
}
JS
var NUM_PARTICLES = ( ( ROWS = 100 ) * ( COLS = 300 ) ),
    THICKNESS = Math.pow( 80, 2 ),
    SPACING = 3,
    MARGIN = 100,
    COLOR = 220,
    DRAG = 0.95,
    EASE = 0.25,
    
    /*
    
    used for sine approximation, but Math.sin in Chrome is still fast enough :)http://jsperf.com/math-sin-vs-sine-approximation

    B = 4 / Math.PI,
    C = -4 / Math.pow( Math.PI, 2 ),
    P = 0.225,

    */

    container,
    particle,
    canvas,
    mouse,
    stats,
    list,
    ctx,
    tog,
    man,
    dx, dy,
    mx, my,
    d, t, f,
    a, b,
    i, n,
    w, h,
    p, s,
    r, c
    ;

particle = {
  vx: 0,
  vy: 0,
  x: 0,
  y: 0
};

function init() {

  container = document.getElementById( 'container' );
  canvas = document.createElement( 'canvas' );
  
  ctx = canvas.getContext( '2d' );
  man = false;
  tog = true;
  
  list = [];
  
  w = canvas.width = COLS * SPACING + MARGIN * 2;
  h = canvas.height = ROWS * SPACING + MARGIN * 2;
  
  container.style.marginLeft = Math.round( w * -0.5 ) + 'px';
  container.style.marginTop = Math.round( h * -0.5 ) + 'px';
  
  for ( i = 0; i < NUM_PARTICLES; i++ ) {
    
    p = Object.create( particle );
    p.x = p.ox = MARGIN + SPACING * ( i % COLS );
    p.y = p.oy = MARGIN + SPACING * Math.floor( i / COLS );
    
    list[i] = p;
  }

  container.addEventListener( 'mousemove', function(e) {

    bounds = container.getBoundingClientRect();
    mx = e.clientX - bounds.left;
    my = e.clientY - bounds.top;
    man = true;
    
  });
  
  if ( typeof Stats === 'function' ) {
    document.body.appendChild( ( stats = new Stats() ).domElement );
  }
  
  container.appendChild( canvas );
}

function step() {

  if ( stats ) stats.begin();

  if ( tog = !tog ) {

    if ( !man ) {

      t = +new Date() * 0.001;
      mx = w * 0.5 + ( Math.cos( t * 2.1 ) * Math.cos( t * 0.9 ) * w * 0.45 );
      my = h * 0.5 + ( Math.sin( t * 3.2 ) * Math.tan( Math.sin( t * 0.8 ) ) * h * 0.45 );
    }
      
    for ( i = 0; i < NUM_PARTICLES; i++ ) {
      
      p = list[i];
      
      d = ( dx = mx - p.x ) * dx + ( dy = my - p.y ) * dy;
      f = -THICKNESS / d;

      if ( d < THICKNESS ) {
        t = Math.atan2( dy, dx );
        p.vx += f * Math.cos(t);
        p.vy += f * Math.sin(t);
      }

      p.x += ( p.vx *= DRAG ) + (p.ox - p.x) * EASE;
      p.y += ( p.vy *= DRAG ) + (p.oy - p.y) * EASE;

    }

  } else {

    b = ( a = ctx.createImageData( w, h ) ).data;

    for ( i = 0; i < NUM_PARTICLES; i++ ) {

      p = list[i];
      b[n = ( ~~p.x + ( ~~p.y * w ) ) * 4] = b[n+1] = b[n+2] = COLOR, b[n+3] = 255;
    }

    ctx.putImageData( a, 0, 0 );
  }

  if ( stats ) stats.end();

  requestAnimationFrame( step );
}

init();
step();
Host Instantly Drag and Drop Website Builder

 

Description

A study creating performant particles with Canvas 2D
Term
Mon, 11/27/2017 - 22:12

Related Codes

Pen ID
Pen ID
Pen ID