2 551 Codepen

Деление клетки на канвасе, эффект для фона

Фоновый эффект для интро страницы сайта на канвасе. Митозис, деление клеток.

HTML

<canvas id="mitosys"></canvas>

SCSS

html,
body {
  margin: 0;
  background: #000;
  height: 100vh;
  overflow: hidden;
}

body:before,
body:after {
  content: '';
  position: absolute;
  z-index: 1;
  top: 50%;
  left: 50%;
  width: 100vw;
  height: 100vh;
  transform: translate(-50%, -50%);
  transform-origin: 0 0;
  mix-blend-mode: hard-light;
  background: linear-gradient(45deg, #e10000, #40ab00);
}


body:after {
  z-index: 2;
  content: 'MITOSYS';
  font-family: 'Montserrat', sans-serif;
  mix-blend-mode: soft-light;
  background: none;
  color: #fff;
  font-size: 20px;
  text-align: center;
  letter-spacing: 10vw;
  top: 50%;
  left: calc(50% + 5vw);
  transform: translateX(-50%);
  height: auto;
  
  @media (max-width: 575px) {
    font-size: 12px;
  }
}

JS

/*--------------------
Settings
--------------------*/
let canvas = document.getElementById('mitosys'),
    ctx = canvas.getContext('2d'),
    winW = canvas.width = window.innerWidth,
    winH = canvas.height = window.innerHeight,
    ticker = 0,
    Balls = [],
    maxBalls = 10,
    easing = 1/10;


/*--------------------
Balls
--------------------*/
class Ball {
  constructor(options){

    Object.assign(this, options);

    this.r = 100 + Math.random() * 100;
    this.pos = {
      x: Math.random() * winW,
      y: Math.random() * winH
    };
    this.direction = {
      x: -1 + Math.random() * 2,
      y: -1 + Math.random() * 2
    };
    this.activePos = {
      x: this.pos.x,
      y: this.pos.y
    };
  }

  draw() {
    this.color = gradientBg(this.activePos.x, this.activePos.y, this.r);
    ctx.fillStyle = this.color;
    ctx.beginPath();
    ctx.arc(this.activePos.x, this.activePos.y, this.r, 0, 2 * Math.PI);
    ctx.fill();
  }
  
  update() {
    let dx = mouse.x - this.activePos.x,
        dy = mouse.y - this.activePos.y;
    
    this.activePos.x += this.direction.x;
    this.activePos.y += this.direction.y;
    
    if (this.activePos.x < 0 || this.activePos.x > winW) {
      this.direction.x *= -1;
    }
    if (this.activePos.y < 0 || this.activePos.y > winH) {
      this.direction.y *= -1;
    }
  }
}


/*--------------------
Gradient BG
--------------------*/
const gradientBg = (x, y, r) => {
  bg = ctx.createRadialGradient(x-r/3, y-r/7, 0, x, y, r);
  bg.addColorStop(0, '#fff');
  bg.addColorStop(.95, '#000');
  return bg;
}


/*--------------------
Distance
--------------------*/
const dist = (p1, p2) => {
  const dx = p2.x - p1.x;
  const dy = p2.y - p1.y;
  return Math.sqrt(dx * dx + dy * dy);
}


/*--------------------
Get Mouse
--------------------*/
let mouse = { x: window.innerWidth / 2, y: window.innerHeight / 2, dir: '' };
const getMouse = (e) => {
  mouse = {
    x: e.clientX || e.pageX || e.touches[0].pageX || 0,
    y: e.clientY || e.pageX || e.touches[0].pageY || 0,
    dir: (getMouse.x > e.clientX) ? 'left' : 'right'
  }
};
['mousemove', 'touchstart', 'touchmove'].forEach(e => {
  window.addEventListener(e, getMouse);
});


/*--------------------
Init
--------------------*/
const init = () => {
  console.clear();
  winW = canvas.width = window.innerWidth;
  winH = canvas.height = window.innerHeight;
  ctx.globalCompositeOperation = "lighten";
  
  Balls = [];
  for (let i = 0; i < maxBalls; i++) {
    Balls.push(new Ball());
  }
}
init();


/*--------------------
Animate
--------------------*/
const animate = () => {
  ticker += .1;
  ctx.clearRect(0, 0, winW, winH);
  window.requestAnimationFrame(animate);
  Balls.forEach(ball => {
    ball.update();
    ball.draw();
  });
}
animate();


/*--------------------
Resize
--------------------*/
window.addEventListener('resize', () => {
  init();
});

Комментарии

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

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