๐ŸŒŸ p5.js ์ „์—ญ ๋ชจ๋“œ vs ์ธ์Šคํ„ด์Šค ๋ชจ๋“œ

BamgasiJMยท2025๋…„ 12์›” 14์ผ

p5.js Art

๋ชฉ๋ก ๋ณด๊ธฐ
6/70
post-thumbnail

โœ๏ธ Vanilla JavaScript + Vite ํ™˜๊ฒฝ์—์„œ p5.js๋ฅผ ์•ˆ์ „ํ•˜๊ณ  ํ™•์žฅ์„ฑ ์žˆ๊ฒŒ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•ต์‹ฌ ๊ฐœ๋…

p5.js๋Š” ์ฐฝ์˜์ ์ธ ์ฝ”๋”ฉ์„ ์œ„ํ•œ ๊ฐ•๋ ฅํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ง€๋งŒ, ์–ด๋–ป๊ฒŒ ๋ถˆ๋Ÿฌ์˜ค๋А๋ƒ์— ๋”ฐ๋ผ ์ฝ”๋“œ ๊ตฌ์กฐ์™€ ์œ ์ง€๋ณด์ˆ˜์„ฑ์ด ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
๊ฐ€์žฅ ํฐ ๋ถ„๊ธฐ์ ์€ ๋ฐ”๋กœ:
๐Ÿ”น ์ „์—ญ ๋ชจ๋“œ(Global Mode)
๐Ÿ”น ์ธ์Šคํ„ด์Šค ๋ชจ๋“œ(Instance Mode)

์ด ๊ธ€์—์„œ๋Š” ๋‘ ๋ฐฉ์‹์˜ ๋™์ž‘ ์›๋ฆฌ, ์žฅ๋‹จ์ , ์ ํ•ฉํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€, ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ ์ฝ”๋“œ ๋น„๊ต๋ฅผ ํ†ตํ•ด ๋ช…ํ™•ํžˆ ์งš์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

https://www.postype.com/@dizicode/post/15021097
https://www.postype.com/@dizicode/post/14862766
https://github.com/processing/p5.js/wiki/Global-and-instance-mode


๐Ÿ”น 1. ์ „์—ญ ๋ชจ๋“œ (Global Mode)

โœ… ์ž‘๋™ ๋ฐฉ์‹

  • p5.js ์Šคํฌ๋ฆฝํŠธ๋ฅผ <script> ํƒœ๊ทธ๋กœ HTML์— ์ง์ ‘ ๋กœ๋“œํ•˜๊ฑฐ๋‚˜,
    import 'p5';์ฒ˜๋Ÿผ ๋ชจ๋“ˆ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋ฉด,
    setup(), draw(), mousePressed() ๋“ฑ์˜ ํ•จ์ˆ˜ ์ด๋ฆ„์ด ์ „์—ญ ์Šค์ฝ”ํ”„์— ์ž๋™ ๋“ฑ๋ก๋ฉ๋‹ˆ๋‹ค.
    p5.js ์—”์ง„์ด ์ž๋™์œผ๋กœ setup()๊ณผ draw()๋ฅผ ์ฐพ์•„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“„ ์˜ˆ์‹œ: index.html + sketch.js (์ „ํ†ต์  ๋ฐฉ์‹)

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.4/p5.js"></script>
  <script src="sketch.js"></script>
</head>
<body></body>
</html>
// sketch.js
function setup() {
  createCanvas(400, 400);
  background(220);
}

function draw() {
  ellipse(mouseX, mouseY, 20, 20);
}

โœ… ์žฅ์ 

  • ์ดˆ๋ณด์ž ์นœํ™”์ : ์ฝ”๋“œ๊ฐ€ ์งง๊ณ  ์ง๊ด€์ 
  • ๋น ๋ฅธ ํ”„๋กœํ† ํƒ€์ดํ•‘์— ์ ํ•ฉ
  • p5.js ๊ณต์‹ ๋ ˆํผ๋Ÿฐ์Šค ๋Œ€๋ถ€๋ถ„์ด ์ด ๋ฐฉ์‹ ๊ธฐ์ค€

โŒ ๋‹จ์ 

  • ์ „์—ญ ์Šค์ฝ”ํ”„ ์˜ค์—ผ: setup, draw, width, height, mouseX ๋“ฑ ๋ชจ๋“  p5 ๋ณ€์ˆ˜/ํ•จ์ˆ˜๊ฐ€ ์ „์—ญ์— ๋…ธ์ถœ
  • ์—ฌ๋Ÿฌ ์Šค์ผ€์น˜ ๋™์‹œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€: ํŽ˜์ด์ง€ ๋‚ด ๋‘ ๊ฐœ ์ด์ƒ์˜ p5 ์Šค์ผ€์น˜๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋ฉด ์ถฉ๋Œ ๋ฐœ์ƒ
  • ๋ชจ๋“ˆ ์‹œ์Šคํ…œ๊ณผ์˜ ํ˜ธํ™˜์„ฑ ๋ฌธ์ œ: Vite, Webpack ๋“ฑ ๋ฒˆ๋“ค๋Ÿฌ ํ™˜๊ฒฝ์—์„œ ์ „์—ญ ๋ณ€์ˆ˜ ์ถฉ๋Œ ์œ„ํ—˜ โ†‘
  • ๋ฆฌํŒฉํ† ๋งยทํ…Œ์ŠคํŠธ ์–ด๋ ค์›€: ํ•จ์ˆ˜ ๊ฐ„ ์˜์กด์„ฑ์ด ์•”๋ฌต์  โ†’ ์œ ์ง€๋ณด์ˆ˜ ๋น„์šฉ ์ฆ๊ฐ€

    ๐Ÿ’ก ์š”์•ฝ: "์‹œ์ž‘์€ ํŽธํ•˜์ง€๋งŒ, ์ ์  ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ๊ณ ํ†ต๋ฐ›๋Š” ๋ฐฉ์‹"


๐Ÿ”น 2. ์ธ์Šคํ„ด์Šค ๋ชจ๋“œ (Instance Mode)

โœ… ์ž‘๋™ ๋ฐฉ์‹

  • new p5()๋ฅผ ํ˜ธ์ถœํ•ด p5 ์ธ์Šคํ„ด์Šค๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ƒ์„ฑ
  • p5์˜ ๋ชจ๋“  ๊ธฐ๋Šฅ(createCanvas, ellipse, mouseX ๋“ฑ)์€ ์ธ์Šคํ„ด์Šค์˜ ๋ฉ”์„œ๋“œ/์†์„ฑ์œผ๋กœ ์ ‘๊ทผ
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜(setup, draw)๋Š” ์ต๋ช… ํ•จ์ˆ˜ ๋˜๋Š” ๋ณ„๋„ ํ•จ์ˆ˜๋กœ ์ „๋‹ฌ

๐Ÿ“„ ์˜ˆ์‹œ: Vite + ๋ชจ๋“ˆ ๋ฐฉ์‹ (main.js)

p. ์ ‘๋‘์‚ฌ๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ถ™์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// main.js
import p5 from 'p5';

new p5((p) => {
  // `p`๋Š” p5 ์ธ์Šคํ„ด์Šค โ€” ์ „์—ญ ๋ณ€์ˆ˜ ์—†์ด ๋ชจ๋“  ๊ธฐ๋Šฅ์— ์ ‘๊ทผ ๊ฐ€๋Šฅ
  p.setup = () => {
    p.createCanvas(400, 400);
    p.background(220);
  };

  p.draw = () => {
    p.ellipse(p.mouseX, p.mouseY, 20, 20);
  };
});

โœ… ์žฅ์ 

  • ์Šค์ฝ”ํ”„ ๊ฒฉ๋ฆฌ: ์ „์—ญ ์˜ค์—ผ ์ œ๋กœ โ†’ ์—ฌ๋Ÿฌ ์Šค์ผ€์น˜ ๋…๋ฆฝ ์‹คํ–‰ ๊ฐ€๋Šฅ
  • ๋ชจ๋“ˆ ์‹œ์Šคํ…œ๊ณผ ์™„๋ฒฝ ํ˜ธํ™˜: Vite, Rollup, Webpack ๋“ฑ ์ตœ์‹  ๋„๊ตฌ ์ฒด์ธ์—์„œ ๊ถŒ์žฅ ๋ฐฉ์‹
  • ์œ ์ง€๋ณด์ˆ˜์„ฑ ํ–ฅ์ƒ: ์ธ์Šคํ„ด์Šค๋ฅผ ๋ณ€์ˆ˜๋กœ ๊ด€๋ฆฌ โ†’ ๋ฆฌํŒฉํ† ๋ง(์˜ˆ: ํด๋ž˜์Šค ๋ถ„๋ฆฌ) ์šฉ์ด

โŒ ๋‹จ์ 

  • ์•ฝ๊ฐ„ ๋” ๊ธด ๋ฌธ๋ฒ•(p. ๋ฐ˜๋ณต)
  • ๊ณต์‹ ๋ ˆํผ๋Ÿฐ์Šค ์˜ˆ์ œ์™€ ๋ฌธ๋ฒ• ์ฐจ์ด

๐Ÿ’ก ์š”์•ฝ: "์ดˆ๊ธฐ ์ง„์ž… ์žฅ๋ฒฝ์€ ์žˆ์ง€๋งŒ, ์žฅ๊ธฐ์ ์œผ๋ก  ํ›จ์”ฌ ๊ฑด๊ฐ•ํ•œ ์„ ํƒ"


๐Ÿ” ์ธ์Šคํ„ด์Šค ๋ชจ๋“œ๋ฅผ ํด๋ž˜์Šค๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ

p5 ์ธ์Šคํ„ด์Šค ๋ชจ๋“œ๋Š” ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ ๊ตฌ์กฐ์™€ ๊ถํ•ฉ์ด ๋งค์šฐ ์ข‹์Šต๋‹ˆ๋‹ค.
ํŠนํžˆ ์—ฌ๋Ÿฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์กฐ์ •ํ•˜๊ฑฐ๋‚˜, ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค ๋•Œ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

main.js ์•ˆ์—์„œ sketch.js๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์˜ˆ์‹œ์ž…๋‹ˆ๋‹ค.

main.js

// main.js
import p5 from 'p5';
import CircleSketch from './sketch.js';

const sketch = new p5((p) => {
  const circleSketch = new CircleSketch(p, document.body);
  circleSketch.init();
});

sketch.js

// sketch.js
export default class CircleSketch {
  constructor(p, canvasParent) {
    this.p = p;
    this.parent = canvasParent;
    this.radius = 20;
    this.color = 255;
  }

  init() {
    this.p.setup = () => {
      const canvas = this.p.createCanvas(400, 400);
      canvas.parent(this.parent); // ํŠน์ • DOM ์š”์†Œ์— ์บ”๋ฒ„์Šค ์‚ฝ์ž…
      this.p.background(30);
    };

    this.p.draw = () => {
      this.p.background(30, 20); // ํ๋ฆฟํ•œ ํŠธ๋ ˆ์ผ ํšจ๊ณผ
      this.p.fill(this.color);
      this.p.noStroke();
      this.p.ellipse(this.p.mouseX, this.p.mouseY, this.radius);
    };

    // ์™ธ๋ถ€์—์„œ ์กฐ์ • ๊ฐ€๋Šฅํ•œ API
    this.p.keyPressed = () => {
      if (this.p.key === ' ') this.radius += 5;
    };
  }
}

โœ… ์ด๋Ÿฐ ๊ตฌ์กฐ๋Š”

  • ํŒŒ๋ผ๋ฏธํ„ฐ ํŠœ๋‹ UI (e.g., dat.GUI) ์ ์šฉ ์šฉ์ด
  • ์—ฌ๋Ÿฌ ์Šค์ผ€์น˜๋ฅผ ๊ฐ™์€ ํŽ˜์ด์ง€์— ๋ฐฐ์น˜ ๊ฐ€๋Šฅ
  • ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ๋„ ์‰ฌ์›Œ์ง‘๋‹ˆ๋‹ค.
profile
Coding Art with Blender / Three.js / p5.js / GLSL Shader / Processing / nannou

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