mouseEffect

ness·2023년 6월 7일
0
post-thumbnail

원래 오늘 js중 processing 과 같은 라이브러리가 있어 그것을 하려고 했지만 시간이 없어서 이번에도 canvsJS로 한다 (다음: p5.js)

html 전체 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    body{
      padding: 0;
      margin: 0;
      height: 100vh;
      background-color: black;
    }
    #canvas{
      position: fixed;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
    }
  </style>
</head>
<body>
  <canvas id="canvas"></canvas>
</body>
</html>

canvasJS코드

let canvas, ctx, w, h, particles = [];
    let mouse = {
      x: undefined,
      y: undefined
    }

    const init = ()=> {
      canvas = document.querySelector("#canvas");
      ctx = canvas.getContext("2d");
      resizeReset();
      animationLoop();
    }

    const resizeReset = () => {
      w = canvas.width = window.innerWidth;
      h = canvas.height = window.innerHeight;
    }

    const mouseMove = (e) => {
      mouse.x = e.x;
      mouse.y = e.y;
    }

    const mouseOut = () => {
      mouse.x = undefined;
      mouse.y = undefined;
    }

    const animationLoop = () => {
      if (mouse.x != undefined && mouse.y != undefined) {
        particles.push(new Particle(mouse.x, mouse.y));
      }
      
      ctx.clearRect(0, 0, w, h);
      ctx.globalCompositeOperation = 'lighter';

      drawScene();
      arrayCleanup();
      requestAnimationFrame(animationLoop);
    }

    const arrayCleanup = () => {
      let dump = [];
      particles.map((particle) => {
        if (particle.radius > 0) {
          dump.push(particle);
        }
      });
      particles = dump;
    }

    const drawScene = () => {
      particles.map((particle) => {
        particle.update();
        particle.draw();
      })
    }

    class Particle {
      constructor(x, y) {
        this.x = x;
        this.y = y;
        this.radius = 5;
        this.size = 0;
        this.rotate = 0;
        this.alpha = 0.5;
      }
      
      setPoint() {
        let r, x, y;
        this.point = [];
        
        for (let a = 0; a < 360; a += 10) {
          r = (Math.PI / 180) * (a + this.rotate);
          x = this.x + this.size * Math.sin(r);
          y = this.y + this.size * Math.cos(r);
          
          this.point.push({ x: x, y: y, r: this.radius });
        }
      }
      
      draw() {
        if (this.radius <= 0) return;
        
        this.point.map((p) => {
          ctx.beginPath();
          ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
          ctx.fillStyle = `hsla(160, 100%, 50%, ${this.alpha})`;
          ctx.fill();
          ctx.closePath();
        });
      }

      update() {
        this.setPoint();
        this.radius -= 0.05;
        this.size += 0.5;
        this.rotate -= 1;
        this.alpha = (this.radius * 0.5 < 0.5) ? this.radius * 0.5 : 0.5;
      }
    }

    window.addEventListener("DOMContentLoaded", init);
    window.addEventListener("resize", resizeReset);
    window.addEventListener("mousemove", mouseMove);
    window.addEventListener("mouseout", mouseOut);

다음은 함수별 설명

init(): 이 함수는 캔버스를 초기화하고 2D 렌더링 컨텍스트 (ctx)를 가져온 다음, resizeReset() 함수를 호출하여 캔버스 크기를 창의 내부 크기와 일치하도록 설정하고, animationLoop()를 호출하여 애니메이션 루프를 시작함니다.

resizeReset(): 이 함수는 캔버스 크기를 창의 내부 크기와 일치하도록 설정하는 역할을 담당합니다. 캔버스의 너비 (w)와 높이 (h)를 창의 내부 너비와 높이로 설정합니다.

mouseMove(e): 이 함수는 마우스 이동 이벤트를 처리하여 마우스 위치를 따라 갑니다. e 매개변수는 이벤트 객체를 나타내고, 이벤트가 발생할 때마다 mouse.x와 mouse.y 속성을 현재 마우스 좌표로 업데이트합니다.

mouseOut(): 이 함수는 mouseMove()와 반대로 마우스가 켄버스 영역을 벗어나면 mouse.x와 mouse.y 를 undefined 마우스 위치를 재조정 시킨다.

animationLoop(): 애니메이션을 위한 루프 함수입니다. 마우스 좌표가 정의되어 있다면 새로운 파티클을 생성합니다. 그런 다음 캔버스를 지우고, drawScene 함수를 호출하여 모든 파티클을 업데이트하고 그려줍니다. 마지막으로 requestAnimationFrame을 사용하여 다음 프레임을 요청합니다.

arrayCleanup(): 파티클 배열을 정리하는 함수입니다. 반지름이 0보다 큰 파티클만을 유지하고, 나머지는 삭제합니다.

drawScene(): 파티클 배열을 순회하면서 각 파티클을 업데이트하고 그립니다.

Particle{} : 파티클을 나타내는 클래스입니다. 생성자에서는 파티클의 초기 위치와 속성을 정의합니다.
setPoint(): 함수에서는 파티클 주위의 점들을 계산하여 point 배열에 저장합니다.
draw(): 함수에서는 point 배열을 순회하면서 각 점을 캔버스에 그리고, update(): 함수에서는 파티클의 속성을 업데이트합니다.

점점 귀찮아 지기는 하지만 다음 부터는 vlog에서 보다 tistory 에서 올려 볼려고 한다 이름은 다음 시간에올려 보겠다.

profile
null

0개의 댓글