2 277 Codepen

Кристаллический параллакс

Реализованный на канвасе параллакс эффект из градиентных полос. При клике случайным образом градиент меняется.

HTML

<div id="bg_glow"></div>
<div id="overlay"></div>
<canvas id="canvas"></canvas>

CSS

html, body{
  overflow: hidden;
  background: #000;
  padding: 0px;
  margin: 0px;
}

#canvas{
  cursor: crosshair;
  z-index: 2;
  position: absolute;
  top: 0; left: 0;
}

#overlay{
  background: radial-gradient(ellipse at center, rgba(0,0,0,.0) 10%, rgba(0,0,0,.8) 80%, rgba(0,0,0,1) 90%, rgba(0,0,0,1) 100%);
  z-index: 3;
  position: absolute;
  top:0;left:0;
  height: 100%;
  width: 100%;
}

#bg_glow{
  z-index: 1;
  position: absolute;
  top:0;left:0;
  height: 100%;
  width: 100%;
}

#info{
  z-index: 4;
  position: absolute;
  color: #fff;
  top: 0px;
  left: 0px;
  background: rgba(60,60,60,.6);
  padding: 5px;
}
#overlay:hover{
  cursor: pointer;
}

#fps{
  position: absolute;
  top: 0px;
  right: 0px;
  z-index: 5;
}

JS

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var bgg = document.getElementById("bg_glow");
w = ctx.canvas.width = window.innerWidth;
h = ctx.canvas.height = window.innerHeight;

window.onresize = function() {
  w = ctx.canvas.width = window.innerWidth;
  h = ctx.canvas.height = window.innerHeight;
  maxHeight = h*.9
  minHeight = h*.5;
  dots = [];
  pushDots();
  ctx.globalCompositeOperation = "lighter";
};

document.getElementById("overlay").onclick = function(){
  hue = Math.random()*360;
  bgg.style.background = "radial-gradient(ellipse at center, hsla("+hue+",50%,50%,.8) 0%,rgba(0,0,0,0) 100%)";
  dots = [];
  pushDots();
}

dots=[{}];
mx = 0; my = 0;
md = 100;
maxWidth = 15;
minWidth = 2;
maxHeight = h*.9
minHeight = h*.5;
maxSpeed = 35;
minSpeed = 6;
hue = 230;
hueDif = 50; // Hue +/-
glow = 10; // Turn this off for better performance
ctx.globalCompositeOperation = "lighter";

function pushDots(num){
  for(i=1; i<md; i++){
    dots.push({
      x:Math.random()*w,
      y:Math.random()*h/2,
      h:Math.random()*(maxHeight-minHeight)+minHeight,
      w:Math.random()*(maxWidth-minWidth)+minWidth,
      c:Math.random()*((hue+hueDif)-(hue-hueDif))+(hue-hueDif),
      m:Math.random()*(maxSpeed-minSpeed)+minSpeed
    });
  }
}pushDots();

function render(){
  ctx.clearRect(0,0,w,h);
  for(i=1; i<dots.length; i++){
    ctx.beginPath();
    grd = ctx.createLinearGradient(dots[i].x, dots[i].y, dots[i].x+dots[i].w, dots[i].y+dots[i].h);
    grd.addColorStop(.0, "hsla("+dots[i].c+",50%,50%,.0)");
    grd.addColorStop(.2, "hsla("+dots[i].c+20+",50%,50%,.5)");
    grd.addColorStop(.5, "hsla("+dots[i].c+50+",70%,60%,.8)");
    grd.addColorStop(.8, "hsla("+dots[i].c+80+",50%,50%,.5)");
    grd.addColorStop(1., "hsla("+(dots[i].c+100)+",50%,50%,.0)");
    ctx.shadowBlur = glow;
    ctx.shadowColor = "hsla("+(dots[i].c)+",50%,50%,1)";
    ctx.fillStyle=grd;
    ctx.rect(dots[i].x,dots[i].y,dots[i].w,dots[i].h);
    ctx.fill();
    ctx.closePath();
    dots[i].x += dots[i].m/100;
    if(dots[i].x > w+maxWidth){
      dots.splice(i,1);
      dots.push({
        x:0,
        y:Math.random()*h,
        h:Math.random()*(maxHeight-minHeight)+minHeight,
        w:Math.random()*(maxWidth-minWidth)+minWidth,
        c:Math.random()*((hue+hueDif)-(hue-hueDif))+(hue-hueDif),
        m:Math.random()*(maxSpeed-minSpeed)+minSpeed
      });
    }
  }window.requestAnimationFrame(render);
}

bgg.style.background = "radial-gradient(ellipse at center, hsla("+hue+",50%,50%,.8) 0%,rgba(0,0,0,0) 100%)";
render();

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи