HTML5 canvas: trippy geometry animation

In this example below you will see how to do a HTML5 canvas: trippy geometry animation with some HTML / CSS and Javascript

Thumbnail
This awesome code was written by dead_seagull, you can see more from this user in the personal repository.
You can find the original code on Codepen.io
Copyright dead_seagull ©
  • HTML
  • CSS
  • JavaScript
<!DOCTYPE html>
<html lang="en" >

<head>
  <meta charset="UTF-8">
  <title>HTML5 canvas: trippy geometry animation</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">

  
      <link rel="stylesheet" href="css/style.css">

  
</head>

<body>

  
<canvas id="canvas"></canvas>
<canvas id="trails"></canvas>
  
  

    <script  src="js/index.js"></script>




</body>

</html>

/*Downloaded from https://www.codeseek.co/dead_seagull/html5-canvas-trippy-geometry-animation-yVOqGe */
body,
html {
  padding: 0;
  margin: 0;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
}
canvas {
  position: absolute;
  width: 100vw;
  height: 100vh;
}
#canvas {
  background: transparent;
  z-index: 2;
}
#trails {
  background: #000;
  z-index: 1;
}


/*Downloaded from https://www.codeseek.co/dead_seagull/html5-canvas-trippy-geometry-animation-yVOqGe */
// Глобальные переменные
var canvas = document.querySelector('#canvas'),
    // Получаем объект canvas
trails = document.querySelector('#trails'),
    // Получаем объект canvas
ctx = canvas.getContext('2d'),
    // Получаем контекст отрисовки
Tctx = trails.getContext('2d'),
    // Получаем контекст отрисовки
PI = Math.PI; // Запись значения пи в константу

var COUNT = Math.floor(rand(2, 12)),
    R1 = rand(60, (window.innerHeight - 100) / 2),
    // Радиус большого круга
R2 = R1 / (PI * rand(1, 4)) * COUNT,
    // Радиус маленького круга
COLOR = '#fff',
    // Цвет контура
SPEED = rand(0.05, 2 / (COUNT * rand(0.5, 2))),
    // Скорость вращения большого круга
ANGLE = 0,
    // Начальный угол
ANGLEDIFF = 360 / COUNT * (PI / 180),
    // Отклонение угла
CENTER = {
  x: window.innerWidth / 2, // Центр окна по оси X
  y: window.innerHeight / 2 // Центр окна по оси Y
};

var lw = rand(0.5, 3);

// Функция запуска анимации
function init() {
  ctx.canvas.width = CENTER.x * 2;
  ctx.canvas.height = CENTER.y * 2;
  Tctx.canvas.width = CENTER.x * 2;
  Tctx.canvas.height = CENTER.y * 2;

  window.requestAnimationFrame(draw); // Перерисовываем анимацию
}

var opacityRand = rand(0.05, 0.3);
var overlayColor = 'rgba(' + Math.floor(rand(10, 100)) + ',' + Math.floor(rand(10, 100)) + ',' + Math.floor(rand(10, 100)) + ',' + opacityRand + ')';

// Перерисовка изображения на канвасе
function draw() {
  Tctx.fillStyle = overlayColor;
  Tctx.fillRect(0, 0, Tctx.canvas.width, Tctx.canvas.height);

  ctx.clearRect(0, 0, CENTER.x * 2, CENTER.y * 2);

  ANGLE -= PI / 360 * SPEED; // Угол в радианах

  // Drawing elements
  drawCenter(ctx);

  var COORDS = getCoordinates();

  drawFirstLevelPoints(COORDS.mainPoints);
  drawSecondLevelPoints(COORDS.secondaryPoints);
  drawConnectors(COORDS.mainPoints, COORDS.secondaryPoints);

  window.requestAnimationFrame(draw);
}

// Правка координат при ресайзе окна
window.addEventListener('resize', function () {
  CENTER = {
    x: window.innerWidth / 2,
    y: window.innerHeight / 2
  };

  ctx.canvas.width = CENTER.x * 2;
  ctx.canvas.height = CENTER.y * 2;
  Tctx.canvas.width = CENTER.x * 2;
  Tctx.canvas.height = CENTER.y * 2;
});

// Старт анимации
init();

// Вычисления ===========================================


// Получаем глобальный набор координат точек
function getCoordinates() {
  var coords = {
    mainPoints: [],
    secondaryPoints: []
  };

  var angles = [ANGLE];

  for (var i = 1; i < COUNT; i++) {
    angles.push(ANGLE + ANGLEDIFF * i);
  }

  angles.forEach(function (angle) {
    coords.mainPoints.push(getPointCoordinates(CENTER, angle, R1));
  });

  coords.mainPoints.forEach(function (point, index) {
    var localAngle = angles[index] + angles[index] * COUNT * 2;
    var newPointCoordinate = getPointCoordinates(point, localAngle, R2);

    coords.secondaryPoints.push(newPointCoordinate);
  });

  return coords;
}

// Получаем координаты точки из центра окружности, угла и радиуса
function getPointCoordinates(center, angle, radius) {
  var x = void 0,
      y = void 0;

  x = center.x + radius * Math.cos(angle);
  y = center.y + radius * Math.sin(angle);

  return { x: x, y: y };
}

// Отрисовка ===========================================

var randCircleCenterSize = rand(2, 20);
var randCircleInnerSize = rand(2, 10);
var randCircleOutterSize = rand(2, 8);
// Рисуем центр
function drawCenter(ctx) {
  drawCirclePoint(CENTER.x, CENTER.y, randCircleCenterSize);
  drawCircle(CENTER.x, CENTER.y, R1 - 4, true);
}
// Рисуем точки большого круга
function drawFirstLevelPoints(points) {
  points.map(function (point) {
    drawCirclePoint(point.x, point.y, randCircleInnerSize);
    drawCircle(point.x, point.y, R2 - 4);
  });
}
// Рисуем точки внешних кругов
function drawSecondLevelPoints(points) {
  points.map(function (point) {
    drawCirclePoint(point.x, point.y, randCircleOutterSize);
    drawPoint(point.x, point.y);
  });
}
// Рисуем линии между точками
function drawConnectors(innerPoints, outterPoints) {
  innerPoints.forEach(function (point, index) {
    drawLine(point, CENTER);
    drawLine(point, outterPoints[index]);
    var n = outterPoints.length;
    for (var i = 1; i < n; i++) {
      drawLine(outterPoints[0], outterPoints[n - 1]);
      drawLine(outterPoints[i], outterPoints[i - 1]);
    }
  });
}

// Отрисовка круга с обводкой
function drawCirclePoint(x, y, rad) {
  ctx.beginPath();
  ctx.strokeStyle = COLOR;
  ctx.lineWidth = rad;
  ctx.arc(x, y, rad / 2, 0, PI * 2, false);
  ctx.stroke();

  ctx.beginPath();
  ctx.strokeStyle = COLOR;
  ctx.lineWidth = lw;
  ctx.arc(x, y, rad + 4, 0, PI * 2, false);
  ctx.stroke();
}
// Отрисовка полупрозрачной окружности
function drawCircle(x, y, rad, isDashed) {
  isDashed ? ctx.setLineDash([2, 4]) : '';

  ctx.globalAlpha = 0.2;
  ctx.beginPath();
  ctx.strokeStyle = COLOR;
  ctx.lineWidth = 2;
  ctx.arc(x, y, rad + 4, 0, PI * 2, false);
  ctx.stroke();
  ctx.globalAlpha = 1;
  ctx.setLineDash([0]);
}

// Отрисовка линии
function drawLine(from, to) {
  ctx.globalAlpha = 0.5;
  ctx.beginPath();
  ctx.strokeStyle = COLOR;
  ctx.lineWidth = lw;
  ctx.moveTo(from.x, from.y);
  ctx.lineTo(to.x, to.y);
  ctx.stroke();
  ctx.globalAlpha = 1;
}
// Отрисовка точки
function drawPoint(x, y) {
  var radius = 1;

  Tctx.globalAlpha = 1;
  Tctx.beginPath();
  Tctx.strokeStyle = COLOR;
  Tctx.lineWidth = lw;
  Tctx.arc(x, y, radius / 2, 0, PI * 2, false);
  Tctx.stroke();
  Tctx.globalAlpha = 1;
  Tctx.setLineDash([0]);
}

function rand(min, max) {
  return Math.random() * (max - min) + min;
}

Comments