<div class="title">
    <h1>JUST DO IT.</h1>
  </div>
  <div class="more-pens">
    <a target="_blank" href="https://codepen.io/plasm/" class="white-mode">VIEW OTHER PENS</a>
    <a target="_blank" href="https://codepen.io/collection/nZpPbz/" class="white-mode">VIEW OTHER PARTICLES</a>
  </div>
@import url('https://fonts.googleapis.com/css?family=Montserrat:200,300,400,600')
@import url('https://fonts.googleapis.com/css?family=Open+Sans+Condensed:700')

.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
  &:hover
    background: #edf3f8
    color: #212121

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


.title
  z-index: 10
  position: absolute
  left: 50%
  top: 50%
  transform: translateX(-50%) translateY(-50%)
  font-family: "Montserrat"
  text-align: center
  padding-top: 260px
  width: 100%

  h1
    font-family: 'Open Sans Condensed', sans-serif
    font-size: 46px
    text-transform: uppercase
    line-height: 1.1
    font-weight: 700
    padding: 0
    margin: -120px 0 0 0
    color: #FFFFFF
    letter-spacing: -.02em
View Compiled
function drawCircleGrey(ctx, radius, position){
  ctx.beginPath();
  ctx.arc(position.x, position.y, radius, 0, 2 * Math.PI, false);
  ctx.fillStyle   = hexToRGB("#FFFFFF", Math.random()*0.4);
  ctx.fill()
}

function colorLuminance(hex, lum) {
  // validate hex string
  hex = String(hex).replace(/[^0-9a-f]/gi, '');
  if (hex.length < 6) {
    hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
  }
  lum = lum || 0;

  // convert to decimal and change luminosity
  let rgb = "#", c, i;
  for (i = 0; i < 3; i++) {
    c = parseInt(hex.substr(i*2,2), 16);
    c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
    rgb += ("00"+c).substr(c.length);
  }
  return rgb;
}

function hexToRGB(hex, alpha) {
    let r = parseInt(hex.slice(1, 3), 16),
        g = parseInt(hex.slice(3, 5), 16),
        b = parseInt(hex.slice(5, 7), 16);

    if (alpha) {
        return "rgba(" + r + ", " + g + ", " + b + ", " + alpha + ")";
    } else {
        return "rgb(" + r + ", " + g + ", " + b + ")";
    }
}


function pointIsInPolygon(p, polygon) {
    let isInside = false;
    let minX = polygon[0].x, maxX = polygon[0].x;
    let minY = polygon[0].y, maxY = polygon[0].y;
    for (let n = 1; n < polygon.length; n++) {
        let q = polygon[n];
        minX = Math.min(q.x, minX);
        maxX = Math.max(q.x, maxX);
        minY = Math.min(q.y, minY);
        maxY = Math.max(q.y, maxY);
    }
    if (p.x < minX || p.x > maxX || p.y < minY || p.y > maxY) {
        return false;
    }
    let i = 0, j = polygon.length - 1;
    for (i, j; i < polygon.length; j = i++) {
        if ( (polygon[i].y > p.y) != (polygon[j].y > p.y) &&
                p.x < (polygon[j].x - polygon[i].x) * (p.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x ) {
            isInside = !isInside;
        }
    }
    return isInside;
}


function getBoundingBoxPolygon(points){
  let minX = null;
  let maxX = null;
  let minY = null;
  let maxY = null;
  for(let i = 0; i < points.length; i++) {
      let x = points[i].x;
      let y = points[i].y;
      if(minX == null){
        minX = x; maxX = x; minY = y; maxY = y;
      }
      minX = Math.min(minX, x);
      maxX = Math.max(maxX, x);
      minY = Math.min(minY, y);
      maxY = Math.max(maxY, y);
  }

  let width  = maxX - minX;
  let height = maxY - minY;

  return {
    x: minX,
    y: minY,
    width: width,
    height: height,
  }
}

function polygonScale(factor, polygon){
  return polygon.map(function(data) {
   data.x = data.x * factor
   data.y = data.y * factor
   return data;
  });
}

function addParticle(){
  // Externa points
  let vector = {
    x: Math.random()*logoBB.width,
    y: Math.random()*logoBB.height
  }

  if(pointIsInPolygon(vector, logo)){
    drawCircleGrey(canvas, Math.random()*2, {
      x: offsetX + vector.x,
      y: offsetY + vector.y - 80
    })
  }
}

//
let WIDTH  = $(window).width()
let HEIGHT = $(window).height()

let logo  = polygonScale(0.4, [{x: 120.7,y: 0}, {x: 67.3,y: 61.7}, {x: 32,y: 111.7}, {x: 12.7,y: 152.3}, {x: 4,y: 185.7}, {x: 0.7,y: 207}, {x: 4.7,y: 235}, {x: 10.7,y: 250.3}, {x: 25.3,y: 271}, {x: 46.7,y: 286.3}, {x: 72.7,y: 294.3}, {x: 98.7,y: 297.4}, {x: 130.7,y: 294.3}, {x: 176,y: 284.3}, {x: 248,y: 256.3}, {x: 834.3,y: 5.7}, {x: 218.7,y: 169}, {x: 182,y: 173.7}, {x: 150,y: 171.7}, {x: 122.7,y: 161.7}, {x: 104,y: 143.7}, {x: 94.7,y: 127.7}, {x: 90,y: 101.7}, {x: 92,y: 71.7}, {x: 102,y: 39}]);

let tela = document.createElement('canvas');
    tela.width = $(window).width();
    tela.height = $(window).height();
    $("body").append(tela);

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

let logoBB = getBoundingBoxPolygon(logo)

let offsetX = WIDTH/2 - (logoBB.width)/2
let offsetY = HEIGHT/2 - (logoBB.height)/2

setInterval(function(){
  for(let i=0;i<100;i++){
    addParticle()
  }
}, 5)
View Compiled
Run Pen

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

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