๐ŸŽ‡ Image Circle Modulation (ver.2)

BamgasiJMยท2026๋…„ 3์›” 14์ผ

p5.js Art

๋ชฉ๋ก ๋ณด๊ธฐ
62/65
post-thumbnail

let img;
let gridCols = 80;
let gridRows = 80;
let cellW, cellH;
let levels = [];
let imgReady = false;
let offsetX, offsetY;

// ์ ๋“ค์˜ ์›๋ž˜ ์œ„์น˜์™€ ํ˜„์žฌ ์œ„์น˜/์†๋„ ์ €์žฅ
let points = [];

function setup() {
  createCanvas(1000, 1000);
  background(0);
  noStroke();

  loadImage("../../assets/sticker_lara_006.png", (loadedImg) => {
    img = loadedImg;

    // ๋น„์œจ ์œ ์ง€: ๊ธด ์ชฝ์„ 1000์œผ๋กœ ๋งž์ถ”๊ธฐ
    if (img.width > img.height) {
      img.resize(1000, 0);
    } else {
      img.resize(0, 1000);
    }

    offsetX = (width - img.width) / 2;
    offsetY = (height - img.height) / 2;

    cellW = img.width / gridCols;
    cellH = img.height / gridRows;

    img.loadPixels();

    for (let y = 0; y < gridRows; y++) {
      levels[y] = [];
      for (let x = 0; x < gridCols; x++) {
        let px = int(x * cellW);
        let py = int(y * cellH);
        let idx = (py * img.width + px) * 4;
        let r = img.pixels[idx];
        let g = img.pixels[idx + 1];
        let b = img.pixels[idx + 2];
        let brightness = (r + g + b) / 3;
        let level = map(brightness, 0, 255, 2, 5);
        levels[y][x] = level;

        // ์  ์ดˆ๊ธฐํ™”
        let cx = offsetX + x * cellW + cellW / 2;
        let cy = offsetY + y * cellH + cellH / 2;
        points.push({
          x: cx,
          y: cy,
          ox: cx, // ์›๋ž˜ ์œ„์น˜
          oy: cy,
          vx: 0,
          vy: 0,
          baseSize: level,
        });
      }
    }

    imgReady = true;
  });
}

function draw() {
  background(0);

  if (!imgReady) return;

  for (let p of points) {
    // ๋งˆ์šฐ์Šค์™€์˜ ๊ฑฐ๋ฆฌ
    let d = dist(mouseX, mouseY, p.x, p.y);

    // ๊ธฐ๋ณธ ํฌ๊ธฐ
    let size = p.baseSize;

    // ๋ฐ˜๊ฒฝ n px ๊ฐ€์šฐ์‹œ์•ˆ ํšจ๊ณผ
    if (d < 150) {
      let influence = exp(-pow(d, 2) / (2 * pow(50, 2))); // ฯƒ=100
      size = lerp(p.baseSize, 10, influence);

      // Repulsion ํž˜ ์ถ”๊ฐ€
      let angle = atan2(p.y - mouseY, p.x - mouseX);
      let force = (150 - d) * 0.01; // ๊ฐ€๊นŒ์šธ์ˆ˜๋ก ๊ฐ•ํ•˜๊ฒŒ ๋ฐ€๋ฆผ
      p.vx += cos(angle) * force;
      p.vy += sin(angle) * force;
    }

    // ์›๋ž˜ ์ž๋ฆฌ๋กœ ๋Œ์•„์˜ค๋„๋ก ๋ณต์›๋ ฅ
    let dx = p.ox - p.x;
    let dy = p.oy - p.y;
    p.vx += dx * 0.1; // ๋ณต์›๋ ฅ
    p.vy += dy * 0.1;

    // ๋Œํ•‘
    p.vx *= 0.9;
    p.vy *= 0.9;

    // ์œ„์น˜ ์—…๋ฐ์ดํŠธ
    p.x += p.vx;
    p.y += p.vy;

    // ์  ๊ทธ๋ฆฌ๊ธฐ
    fill(200, 190, 55);
    ellipse(p.x, p.y, size, size);
  }
}

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

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