My Boundary As Much As I Experienced

200번째 글은 디자인 주제로..! 요새 만들고 있는 인터랙티브 작업물 디자인 공유 본문

Interactive(HTML Canvas ・three.js ・game)/CSS・Canvas ・ p5.js ・ Pixi.js

200번째 글은 디자인 주제로..! 요새 만들고 있는 인터랙티브 작업물 디자인 공유

Bumang 2024. 6. 2. 22:53

 

 

크리에이티브 코딩 모임인 137.5에서 pendulum을 주제로 작업물을 만들어야하는데 "어쩌지.." 하다가

기술적으로 어려운 것을 구현하기보다 특이한 컨셉으로 승부하자! 라는 느낌으로 작업물을 만들었다.

Truth in Pendulum이라고 해야되나? 마법 진자 거울로 어떤 사람을 비추면 그 사람의 실제 마음 속을 비출 수 있다...

라는 요상한 컨셉의 작업을 만드려고 한다.

 

이제

1. 렌즈를 떨어뜨리고 가속도를 붙이는 과정도 보여주기

2. 실제 마법렌즈같이 꾸미기

3. 렌즈가 감속하여 정중앙에 멈췄을 때 렌즈에 클로즈업되면서 렌즈 속 세계로 들어가기?

4. 들어간 세계에서 또 다시 마법렌즈를 사용하여 다른 감정을 보기

 

등을 구현하려 한다.

... 설명이 잘 전달될지 모르겠다. 상상을 위해 아래 그렸던 컨셉 아트들도 넣겠다.

 

 

대강 이런 컷들이 쓰일 예정이다...

지금은 gif로 봤던 것과 같이 진자운동하는 렌즈 안에 화난 감정의 인물이 드러나 있는 것 까지 구현했다.

일단 '행복', '증오' 이렇게 두 레이어를 만들었다.

그런 후 pendulum의 진자 운동하는 원형 범위 내에 '증오' 레이어를 마스킹을 했다. 

 

하여튼 지금까지 구현한 코드는 아래와 같다.

 

preload.js

let layerOuter;
let layerOuterImage;
let layerInner;
let layerInnerImage;

function preload() {
  layerOuterImage = loadImage("../asset/happy.png");
  layerInnerImage = loadImage("../asset/anger.png");
}

 

 

pendulum.js

class Pendulum {
  constructor(gravity) {
    this.bob;
    this.len;
    this.gravity = gravity || 1;
    this.origin;
    this.angle = 0;
    this.angleV;
    this.angleA;
  }

  setPendulumSettings(origin, angle, bob, len) {
    this.origin = origin;
    this.angle = angle;
    this.bob = bob;
    this.len = len;
    this.angleV = 0; // 각속도 초기화
    this.angleA = 0.001; // 각가속도 초기화
  }

  swingPendulum() {
    // push와 pop으로 그리기 상태를 저장할 수 있다.
    push(); // 현재의 그리기 상태를 저장
    let force = this.gravity * sin(this.angle);

    this.angleA = (-1 * force) / this.len;
    this.angleV += this.angleA;
    this.angle += this.angleV;

    // 추의 x, y
    this.bob.x = this.len * sin(this.angle) + this.origin.x;
    this.bob.y = this.len * cos(this.angle) + this.origin.y;

    layerOuter.stroke(255);
    layerOuter.strokeWeight(4);
    // 시작점의 x,y, bob의 x,y를 라인으로 이음
    layerOuter.line(this.origin.x, this.origin.y, this.bob.x, this.bob.y);
    // bob의 x, y를 중점으로 반지름 64의 원을 생성

    layerOuter.stroke(75, 100, 255);
    layerOuter.strokeWeight(8);
    layerOuter.fill(255, 0, 0, 0);
    layerOuter.circle(this.bob.x, this.bob.y, 410);
    layerOuter.erase();
    layerOuter.circle(this.bob.x, this.bob.y, 400);
    layerOuter.noErase();
    pop(); // 이전의 그리기 상태로 복원
  }
}

function change() {
  let temp1 = layerOuterImage;
  let temp2 = layerInnerImage;

  layerOuterImage = temp2;
  layerInnerImage = temp1;
}

 

blur.js

function drawBlur(target, way) {
  push();
  clear(); // 캔버스를 지움 (투명한 배경으로 초기화)

  // 블러 강도를 점차 줄이기
  if (way === "DOWN" || undefined) {
    blurAmount -= 0.5;
    if (blurAmount < 0) blurAmount = 0;

    // 원본 이미지를 그리고 블러 필터 적용
    image(target, width / 2, height / 2);
    if (blurAmount > 0) {
      filter(BLUR, blurAmount);
    }
  }

  if (way === "UP") {
    blurAmount += 0.5;
    if (blurAmount > 20) blurAmount = 20;

    // 원본 이미지를 그리고 블러 필터 적용
    image(target, width / 2, height / 2);
    filter(BLUR, blurAmount);
  }

  pop();
}

 

 

layerInner.js

function setlayerInner() {
  layerInner = createGraphics(width, height);
  layerInner.colorMode(HSB, 360, 100, 100, 100);
  layerInner.rectMode(CENTER);
}

function drawlayerInner() {
  image(layerInner, width / 2, height / 2);
  layerInner.imageMode(CENTER);
  layerInner.image(layerInnerImage, width / 2, height / 2, width, height);
}

 

 

layerOuter.js

let blurAmount = 20; // 초기 블러 강도 (0에서 20까지)

function setlayerOuter() {
  layerOuter = createGraphics(width, height);
  layerOuter.colorMode(HSB, 360, 100, 100, 100);
  layerOuter.rectMode(CENTER);
}

function drawlayerOuter() {
  image(layerOuter, width / 2, height / 2);
  layerOuter.imageMode(CENTER);
  layerOuter.image(layerOuterImage, width / 2, height / 2, width, height);
}