๐ŸŒŸ VanillaJS + p5.js + Vite ์„ค์ • (2.0.5 ๋ฒ„์ „)

BamgasiJMยท2025๋…„ 11์›” 1์ผ

p5.js Art

๋ชฉ๋ก ๋ณด๊ธฐ
2/67
post-thumbnail

Node.js์™€ npm์ด ์„ค์น˜๋œ ์ƒํƒœ์—์„œ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

node -v
npm -v

ํ„ฐ๋ฏธ๋„์—์„œ ์œ„ ๋ช…๋ น์œผ๋กœ ๋ฒ„์ „์„ ํ™•์ธํ•˜๊ณ  ํ•„์š”ํ•˜๋ฉด ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
๊ฐœ๋ฐœ ํด๋”๋ฅผ ์ •ํ•ฉ๋‹ˆ๋‹ค.


1๋‹จ๊ณ„: Vite Vanilla JS ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

React๋‚˜ Vue๊ฐ€ ์•„๋‹Œ, ์ˆœ์ˆ˜ Vanilla JavaScript ํ…œํ”Œ๋ฆฟ์„ ์‚ฌ์šฉํ•ด ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

1. ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

ํ„ฐ๋ฏธ๋„์—์„œ ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”.

npm create vite@latest my-p5-art -- --template vanilla
  • npm create: npm์„ ์‚ฌ์šฉํ•ด ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ช…๋ น
  • vite@latest: vite์˜ ์ตœ์‹  ๋ฒ„์ „์„ ์‚ฌ์šฉ
  • my-p5-art: ์ƒ์„ฑํ•  ํ”„๋กœ์ ํŠธ ํด๋” ์ด๋ฆ„ (ํ•„์š”์— ๋งž๊ฒŒ ๋ณ€๊ฒฝ)
  • --: ์ดํ›„์˜ ์˜ต์…˜๋“ค์€ vite ๋ช…๋ น์–ด์— ์ „๋‹ฌํ•œ๋‹ค๋Š” ์˜๋ฏธ. npm๊ณผ vite ๋ช…๋ น์–ด์˜ ์˜ต์…˜์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ตฌ๋ถ„์ž
  • --teamplate vanilla: vite์˜ ํ…œํ”Œ๋ฆฟ ์˜ต์…˜. react, react-ts, vue ๋“ฑ ์‚ฌ์šฉ

2. ํ”„๋กœ์ ํŠธ ํด๋”๋กœ ์ด๋™ ํ›„ ์˜์กด์„ฑ ์„ค์น˜

์ƒ์„ฑ๋œ ํด๋”๋กœ ์ด๋™ํ•œ ํ›„, ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

cd my-p5-art
npm install

2๋‹จ๊ณ„: p5.js ์„ค์น˜

p5.js๋ฅผ npm์œผ๋กœ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“ˆ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

npm install p5

1. ์ผ๊ด€์„ฑ ์žˆ๋Š” ๋ฒ„์ „ ๊ด€๋ฆฌ

package.json์— ๋ฒ„์ „์ด ๋ช…์‹œ๋˜๋ฏ€๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜ ๋ฐฐํฌํ•  ๋•Œ ํ•ญ์ƒ ๋™์ผํ•œ ๋ฒ„์ „์˜ p5.js๊ฐ€ ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค CDN ๋งํฌ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ์ธํ„ฐ๋„ท ์—ฐ๊ฒฐ ๋ฌธ์ œ๋‚˜ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

2. ๋ชจ๋“ˆ์‹ ๊ฐœ๋ฐœ ์ง€์› (ES Modules)

๋˜ํ•œ CDN ๋ฐฉ์‹์€ ๋ชจ๋“  ํ•จ์ˆ˜๋ฅผ ์ „์—ญ(global) ๋ฒ”์œ„๋กœ ์˜ค์—ผ์‹œํ‚ค๋Š” ๋ฐ˜๋ฉด์—, npm ํŒจํ‚ค์ง€๋กœ ์„ค์น˜ํ•˜๋ฉด import ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•„์š”ํ•œ ๋ชจ๋“ˆ๋งŒ ๊ฐ€์ ธ์™€ ๊น”๋”ํ•˜๊ฒŒ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ค์น˜ ํ›„, main.js๋‚˜ ๋ณ„๋„์˜ sketch ํŒŒ์ผ์—์„œ p5๋ฅผ importํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
(์ž„ํฌํŠธ ์˜ˆ์‹œ: import p5 from 'p5'; ๋˜๋Š” import 'p5';)

3. ์ตœ์‹  ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๋ฒˆ๋“ค๋Ÿฌ์— ํ†ตํ•ฉ ์šฉ์ด

React, Vue, Svelte ๊ฐ™์€ modern frontend framework๋‚˜ Vite, Webpack ๊ฐ™์€ Bundler๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ p5๋ฅผ ์ผ๋ฐ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ชจ๋“ˆ์ฒ˜๋Ÿผ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ์••์ถ•ํ•˜๊ณ  ์ตœ์ ํ™”ํ•˜์—ฌ ์›น ๋กœ๋”ฉ ์†๋„๋ฅผ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.

4. npm ์ƒํƒœ๊ณ„์™€ ์—ฐ๋™

๋‹ค๋ฅธ ์™ธ๋ถ€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒจํ‚ค์ง€๋ฅผ ํ•จ๊ป˜ ์„ค์น˜ํ•˜๊ณ  ๊ฒฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3๋‹จ๊ณ„: package.json ํ™•์ธ

์—ฌ๊ธฐ๊นŒ์ง€ ์„ค์น˜๊ฐ€ ๋๋‚˜๋ฉด package.json ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜์˜ ํ•ญ๋ชฉ์€ ํ•„์ˆ˜์ด๋ฉฐ ์ด ํ•ญ๋ชฉ ์ด์™ธ์˜ ๊ฒƒ๋“ค์€ ์ง€์›Œ๋„ ๋ฌด๋ฐฉํ•ฉ๋‹ˆ๋‹ค. (keywords, author, license ๋“ฑ)

{
  "name": "p5js-vite-01",
  "version": "1.0.0",
  "type": "commonjs",
  "scripts": {
    "dev": "vite --host",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "p5": "^2.3.0"
  },
  "devDependencies": {
    "vite": "^8.1.0"
  }
}
  • "name", "version": package.json ์ž์ฒด์˜ ๊ธฐ๋ณธ ๊ทœ๊ฒฉ์ž…๋‹ˆ๋‹ค.
  • "type": "commonjs": Node.js ํ™˜๊ฒฝ์—์„œ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์„ ํ•ด์„ํ•˜๋Š” ๊ธฐ์ค€์ด ๋˜๋ฏ€๋กœ ๋‚จ๊ฒจ๋‘๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
  • "scripts": npm run dev ๋“ฑ์˜ ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•œ ํ•„์ˆ˜ ์„ค์ •์ž…๋‹ˆ๋‹ค.
  • "dependencies"์˜ p5: p5.js๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•ต์‹ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.
  • "devDependencies"์˜ vite: ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰ ๋ฐ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํ•„์ˆ˜ ๋ฒˆ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค.

3๋‹จ๊ณ„: ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ์ฝ”๋“œ

์ด์ œ ๊ผญ ํ•„์š”ํ•œ ํŒŒ์ผ๋“ค์„ ์ƒ์„ฑํ•˜๊ณ  ๊ฐ๊ฐ ์ฝ”๋“œ๋ฅผ ๋„ฃ์Šต๋‹ˆ๋‹ค.

1. index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>p5.js + Vite</title>
  </head>
  <body>
    <div id="p5-container"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

2. src/main.js

์ธ์Šคํ„ด์Šค ๋ชจ๋“œ๋กœ ์ž‘์„ฑ

import p5 from "p5";
import "./style.css";

const sketch = (p) => {
  let t = 0; // ์‹œ๊ฐ„ ๋ณ€์ˆ˜

  p.setup = () => {
    p.createCanvas(400, 400).parent("p5-container");
    p.noStroke();
  };

  p.draw = () => {
    p.background(0);
    p.fill(255);

    // ์‚ฌ์ธํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•ด ๋ฐ˜์ง€๋ฆ„ ๊ณ„์‚ฐ
    const baseRadius = 80; // ๊ธฐ๋ณธ ํฌ๊ธฐ
    const amplitude = 40;  // ํฌ๊ธฐ ๋ณ€ํ™” ํญ
    const speed = 0.05;    // ์†๋„ (๊ฐ’์ด ํด์ˆ˜๋ก ๋น ๋ฆ„)

    const radius = baseRadius + amplitude * p.sin(t);

    // ํ™”๋ฉด ์ค‘์•™์— ์› ๊ทธ๋ฆฌ๊ธฐ
    p.circle(p.width / 2, p.height / 2, radius * 2);

    // ์‹œ๊ฐ„ ์ฆ๊ฐ€
    t += speed;
  };
};

new p5(sketch);

๋˜ ๋‹ค๋ฅธ ์ธ์Šคํ„ด์Šค ๋ชจ๋“œ์˜ ์˜ˆ์‹œ ์ฝ”๋“œ

import p5 from 'p5';
import "./style.css";

const sketch = (p) => {
  let angle = 0;

  p.setup = () => {
    p.createCanvas(800, 600);        // ์บ”๋ฒ„์Šค ํฌ๊ธฐ
    p.background(0);                 // ์ดˆ๊ธฐ ๋ฐฐ๊ฒฝ
    p.smooth();                      // ๋ถ€๋“œ๋Ÿฌ์šด ๋ Œ๋”๋ง
  };

  p.draw = () => {
    // ๋ฐ˜ํˆฌ๋ช… ๋ฐฐ๊ฒฝ์œผ๋กœ ํŠธ๋ ˆ์ผ ํšจ๊ณผ
    p.fill(0, 20);
    p.rect(0, 0, p.width, p.height);

    // ์ค‘์‹ฌ ์ด๋™
    p.translate(p.width/2, p.height/2);
    
    // ํšŒ์ „ํ•˜๋Š” ์—ฌ๋Ÿฌ ๋„ํ˜• ์˜ˆ์‹œ
    for (let i = 0; i < 8; i++) {
      p.push();
      p.rotate(angle + i * p.PI / 4);
      
      // ์ƒ‰์ƒ ๋ณ€ํ™”
      let hue = (p.frameCount + i * 30) % 360;
      p.fill(hue, 80, 100);
      p.noStroke();
      
      // ์‚ฌ๊ฐํ˜• + ์› ์กฐํ•ฉ
      p.rect(-40, -40, 80, 80);
      p.circle(60, 0, 30);
      
      p.pop();
    }
    
    angle += 0.02;  // ํšŒ์ „ ์†๋„
  };

  // ๋งˆ์šฐ์Šค ํด๋ฆญ ์‹œ ์ƒ‰์ƒ/ํŒจํ„ด ๋ฆฌ์…‹ ์˜ˆ์‹œ
  p.mousePressed = () => {
    p.background(0);
  };
};

new p5(sketch);

3. style.css

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: #000000;
}

#p5-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

canvas {
  display: block;
}

4๋‹จ๊ณ„: ๊ฐœ๋ฐœ ์„œ๋ฒ„ ์‹คํ–‰

์ง€๊ธˆ๊นŒ์ง€ ์ง„ํ–‰ํ•œ ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ํ˜•ํƒœ์˜ ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

my-vanilla-p5-app/
โ”œโ”€โ”€ index.html	 	 <-- ํ”„๋กœ์ ํŠธ ๋Œ€๋ฌธ ์—ญํ• 
โ”œโ”€โ”€ package.json	 <-- ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ์„ธํŒ…
โ”œโ”€โ”€ package-lock.json
โ”œโ”€โ”€ node_modules/	 <-- npm install๋กœ ์„ค์น˜ํ•œ ๋ชจ๋“ˆ		
โ””โ”€โ”€ src/
    โ”œโ”€โ”€ main.js      <-- p5.js ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด๊ฐ„ ๋ฉ”์ธ javascriptํŒŒ์ผ
    โ””โ”€โ”€ style.css    <-- css ํŒŒ์ผ

ํ„ฐ๋ฏธ๋„์—์„œ ์•„๋ž˜์˜ ๋ช…๋ น์œผ๋กœ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

npm run dev

ํ„ฐ๋ฏธ๋„์— Local: http://localhost:5173/ ๊ณผ ๊ฐ™์€ ์ฃผ์†Œ๊ฐ€ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค. ์ด๊ฑธ Cmd+ํด๋ฆญ ํ•ด์„œ ์›น ๋ธŒ๋ผ์šฐ์ €๋กœ ์—ฝ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์— ๋ณด์ด๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๋ฉด์„œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋‚˜๊ฐ€๋ฉด ๋ฉ๋‹ˆ๋‹ค.


p5.js 2.0 ๊ฐœ๋ฐœ ๋ฐฉ์‹ ๋ณ€๊ฒฝ

https://github.com/processing/p5.js/wiki/Global-and-instance-mode

1. ES Modules์˜ ๋“ฑ์žฅ

// v1.x: UMD ๋ฐฉ์‹ (์ „์—ญ์— ์ž๋™ ๋“ฑ๋ก)
<script src="p5.js"></script>
// setup(), draw() ํ•จ์ˆ˜๊ฐ€ ์ž๋™์œผ๋กœ ์ „์—ญ์—์„œ ์ธ์‹๋จ

// v2.x: ES Modules ๋ฐฉ์‹
import p5 from 'p5';
// setup(), draw()์ด ์ „์—ญ์— ์ž๋™ ๋“ฑ๋ก๋˜์ง€ ์•Š์Œ

2. ๋ฒˆ๋“ค๋Ÿฌ์˜ ๋ชจ๋“ˆ ๊ฒฉ๋ฆฌ

Vite/Webpack ๋“ฑ์˜ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์—์„œ๋Š” ๊ฐ ํŒŒ์ผ์ด ๋…๋ฆฝ๋œ ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง โ†’ ์ „์—ญ ํ•จ์ˆ˜๊ฐ€ ์ž๋™์œผ๋กœ ๋“ฑ๋ก๋˜์ง€ ์•Š์Œ

3. p5.js์˜ ๋””์ž์ธ ์ฒ ํ•™ ๋ณ€ํ™”

  • v1.x: ์‰ฌ์šด ์‹œ์ž‘์„ ์œ„ํ•œ ๊ธ€๋กœ๋ฒŒ ํด๋ฆฌ์‹œ
  • v2.x: ๋ชจ๋˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋ชจ๋“ˆ ์‹œ์Šคํ…œ ์ค€์ˆ˜

์™œ p. ์ ‘๋‘์‚ฌ๊ฐ€ ํ•„์š”ํ•œ๊ฐ€?

// ๋ชจ๋“ˆ ํ™˜๊ฒฝ์—์„œ๋Š” ์ด๊ฒŒ ์•ˆ๋˜๋Š” ์ด์œ :
function setup() {   	  // โ›” ์ด ํ•จ์ˆ˜๋Š” p5 ์ธ์Šคํ„ด์Šค์™€ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Œ
  createCanvas(400, 400); // โ›” createCanvas๊ฐ€ ์–ด๋–ค p5 ์ธ์Šคํ„ด์Šค์ธ์ง€ ๋ชจ๋ฆ„
}

// ๋Œ€์‹  ์ด๋ ‡๊ฒŒ ํ•ด์•ผํ•จ:
new p5((p) => {      		  // โœ… p5 ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
  p.setup = () => {  		  // โœ… ์ด setup์€ p ์ธ์Šคํ„ด์Šค์™€ ์—ฐ๊ฒฐ๋จ
    p.createCanvas(400, 400); // โœ… p ์ธ์Šคํ„ด์Šค์˜ createCanvas ์‚ฌ์šฉ
  };
});

profile
Coding Art with Blender / oF / Processing / p5.js / nannou

0๊ฐœ์˜ ๋Œ“๊ธ€