Chars Grid

Chars Grid
       
(CSS)

body {
  margin: 0;
  background-color: #1d1e22;
}

canvas {
  max-width: 100%;
  display: block;
}

(JAVA)

/** Moving the letters with the mouse angle.
The angle of the mouse is obtained by subtracting the mouse vector and the letters, then using the arcontangent of the x / y coordinates of the result of the subtraction, the Sin and Cos multiplied by the radius are obtained to obtain the new position of the letters. **/

const ctx = c.getContext("2d");
const rAF = requestAnimationFrame;
const m = {
  x: 0,
  y: 0,
  a: 0,
  e: false };

class Letters {
  constructor(x, y, char, font, color, radius) {
    this.x = x;
    this.y = y;
    this.char = char;
    this.font = font;
    this.color = color;
    this.radius = 0;
    this.oriRad = radius;
    this.i = 20;
    this.maxSize = 30;
    this.minSize = 20;
    this.v = 5;
    this.dist = 0;
    this.friction = 0.9;
    this.K = 0.2; // Spring constant: The Spring Constant is the amount of force required to move the spring a fixed amount of distance.
    this.vel = {
      x: 0,
      y: 0 };

    this.o = {
      x: 0,
      y: 0,
      a: 0 };
  }

  angleChars() {
    if (this.radius < this.oriRad) this.radius += this.v;

    const dx = m.x - this.x;
    const dy = m.y - this.y;

    this.dist = Math.hypot(dx, dy);
    m.a = Math.atan2(dy, dx);

    const ax = Math.cos(m.a) * this.radius;
    const ay = Math.sin(m.a) * this.radius;

    this.o.x = lerp(ax, this.o.x, 0.1);
    this.o.y = lerp(ay, this.o.y, 0.1);

    this.dist < this.radius + 10 ?
    this.i < this.maxSize ? (
    this.dist = this.radius,
    this.i += this.v - 4,
    this.font = `600 ${this.i}px Arial`) :
    null :
    this.i > this.minSize ? (
    this.i -= this.v - 4, this.font = `600 ${this.i}px Arial`) :
    null;
  }

  onMouseLeave() {

    const forceX = this.K * (0 - this.o.x);
    const forceY = this.K * (0 - this.o.y);

    this.o.x += this.vel.x = (this.vel.x + forceX) * this.friction;
    this.o.y += this.vel.y = (this.vel.y + forceY) * this.friction;

    if (this.i > this.minSize) {
      this.i -= this.v - 4;
      this.font = `600 ${this.i}px Arial`;
    }
  }

  update(ctx) {
    m.e ? this.angleChars() : this.onMouseLeave();

    this.draw(ctx);
  }

  draw(ctx) {
    ctx.setTransform(1, 0, 0, 1, this.o.x, this.o.y);
    ctx.fillStyle = this.color;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.font = this.font;
    ctx.fillText(this.char, this.x, this.y);
  }}

let letters;

const init = () => {
  c.width = window.innerWidth;
  c.height = window.innerHeight;

  letters = [];
  const chars = ["A", "L", "A", "I", "N"];
  const colors = ["#02d2d6", "#b125d1", "#fea064", "#00a8e8", "#fb89ef"];
  const colorLength = colors.length;
  const charLength = chars.length;
  const gridLength = 6;
  const radius = Math.min(c.width, c.height) / (gridLength + 1) / 2;
  const font = "600 20px Arial";
  for (let i = 0; i < gridLength; i++) {
    for (let j = 0; j < gridLength; j++) {
      const x = c.width / (gridLength + 1) * (j + 1);
      const y = c.height / (gridLength + 1) * (i + 1);
      const color = randomValue(colors, colorLength);
      const char = randomValue(chars, charLength);
      letters.push(new Letters(x, y, char, font, color, radius));
    }
  }
};

const lerp = (end, start, p) => p * (end - start) + start;

const randomValue = (array, length) =>
array[Math.floor(Math.random() * length)];

const animate = () => {
  ctx.clearRect(0, 0, c.width, c.height);
  for (let letter of letters) {
    letter.update(ctx);
  }
  rAF(animate);
};

init();
animate();
window.addEventListener("resize", init);
c.addEventListener("mousemove", e => {
  const bounding = c.getBoundingClientRect();

  m.x = e.x - bounding.left;
  m.y = e.y - bounding.top;
});
c.addEventListener("mouseenter", () => {
  m.e = true;
});
c.addEventListener("mouseleave", () => {
  m.e = false;
});
       

Comments