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개의 댓글

Powered by GraphCDN, the GraphQL CDN