본문 바로가기
Frontend/JavaScript

ChatGPT 4.0 으로 나만의 라이브러리 만들기 도전(애니메이션 엔진)

by VictorMeredith 2023. 3. 16.

chatGPT 4.0 출시!

1. 개요

- chatGPT 4.0이 출시되었다! 더욱 신중하고 정확하며, 오류가 적고 거짓말을 줄였다고 한다.

- plust 결제 바로 때렸다

- 프로젝트에서 사용할 타임라인 애니메이션 엔진을 가볍게 만들어보고 싶었다. 

- 일도하고 사이드프로젝트도 하고 공부도하고 장가도 가야하니까 바빠서 chatGPT4.0 에게 시켜보았다.

 

2. 요구사항 작성

- 일단 사용방법을 정의해보았다.

const anim1 = 
vic
.anim('요소', 'css속성', 'css값', 애니메이션지속시간, 애니메이션실행이후콜백함수) //1번 애니메이션
.next('요소', 'css속성', 'css값', 애니메이션지속시간, 애니메이션실행이후콜백함수) //1번 종료 이후
.with('요소', 'css속성', 'css값', 애니메이션지속시간, 애니메이션실행이후콜백함수) // 이전과 함께
//.with()는 바로 이전 .next() 혹은 .with()와 함께 동시에 동작될 애니메이션
이런 형태로 동작하는 애니메이션 라이브러리를 만들건데 리액트에서 {vic} from './victoria.js' 의 형태로 작동하는 victoriaJS라는 이름의 리액트 애니메이션 엔진 라이브러리를 만들거야. 코드만 짜줘

 

- 이렇게 요청했을 경우 처음 코드를 짜준다.

// victoria.js
import { useEffect, useRef } from 'react';

class Victoria {
  constructor() {
    this.animations = [];
  }

  anim(element, cssProp, cssValue, duration, callback) {
    this.animations.push({
      element,
      cssProp,
      cssValue,
      duration,
      callback,
      type: 'anim',
    });
    return this;
    
    //.... 어쩌고 저쩌고

 

3. 복붙 후 테스트

- 당연히 처음에는 요구사항과 정확하게 맞지 않는다. 그래도 AI이므로 확장된 의미를 해석해서 작성해주지는 않는다.

- 그래서 다음처럼 계속 괴롭혀야한다.

const handleClick = () => { vic .anim('.box1', 'transform', 'translateY(200px)', 1000) .next('.box1', 'transform', 'scale(2)', 1000) .with('.box1', 'transform', 'rotate(200deg)', 1000); vic.executeAnimations(); }; 이렇게 실행했는데 첫번째 transform이 작동하지 않아

- 이렇게 자세하게 코드로 적더라도 실수도 한다.

- 그럴땐 검토하라고 계속 괴롭혀야한다.

안되잖아 다시 검토해줘
죄송합니다. 제가 이해한 것과 다르게 작동하는 것 같습니다. 이 문제를 해결하기 위해 다음과 같이 변경된 코드를 제안합니다.

- 그러면 지속적으로 이전 코드를 수정해서 요구사항에 맞도록 수정해준다.

- 이번에는 체이닝 기능을 추가해보자.

const handleClick = () => {
    vic
      .anim('.box1', 'transform', 'translateY(200px)', 1000)
      .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000)
      .with('.box1', 'height', '500px', 1000);
    vic.executeAnimations();
이렇게 적었을 때 anim 먼저 실행되고 next()와 .with()가 함께 실행될수 있도록 수정해줘

- 그러면 라이브러리의 전문을 써주고 대답도 해준다.

위의 코드를 사용하면 anim(), next(), 및 with() 메서드에 따라 애니메이션을 정의하고 실행할 수 있습니다. 다음의 순서로 애니메이션을 실행합니다:
anim()으로 정의된 애니메이션을 실행합니다.
next()로 정의된 애니메이션을 순차적으로 실행합니다.
with()로 정의된 애니메이션을 이전 next()와 동시에 실행합니다.

 

- 이렇게만 해도 기본 기능은 된거같은데, 테스트를 더 강하게 해야한다.

- 당연히 오류도 있었다.

 const handleClick = () => {
    vic
      .anim('.box1', 'transform', 'translateY(200px)', 1000)
      .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000)
      .with('.box1', 'height', '500px', 1000);
    vic.executeAnimations();
  };
이렇게 적었을 때 .anim()이 실행 완료 된 이후에 .next()가 실행되야 하는데 scale이 커지는 걸 보니 같이 실행 되는것 같아

- 라고 보내니 죄송합니다 하고 코드를 다시 수정해준다.

- 하지만 다양한 체이닝 테스트를 진행하면서 계속 수정해줘야 한다.

 const handleClick = () => {
    vic
      .anim('.box1', 'transform', 'translateY(200px)', 1000)
      .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000)
      .with('.box1', 'height', '300px', 1000)
      .with('.box1', 'width', '100px', 2000)
      .next('.box1', 'height', '100px', 1500)
      .with('.box1', 'background', 'blue', 5000)
    vic.executeAnimations();
  };
이런 애니메이션 체인이 있을 경우 .with() 뒤의 .next()는 이후 애니메이션을 동작해야하고 .with() 메서드는 이전에 .next() 혹은 .with() 체인이 있을 경우 그 애니메이션 덩어리와 함께 동작해야해.  

- 그러자 답변은 

아래의 수정된 victoria.js 코드를 사용하십시오. 이제 .with() 메서드가 이전 .next() 또는 .with() 체인과 함께 동작하고, 이후 .next()는 이전 애니메이션 체인이 완료된 후에 실행됩니다.
const handleClick = () => {
  vic
    .anim('.box1', 'transform', 'translateY(200px)', 1000)
    .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000)
    .with('.box1', 'height', '300px', 1000)
    .with('.box1', 'width', '100px', 2000)
    .next('.box1', 'height', '100px', 1500)
    .with('.box1', 'background', 'blue', 5000);
  vic.executeAnimations();
};
이 애니메이션 체인의 동작 순서는 다음과 같습니다:
1. .box1 요소의 transform 속성을 변경하여 Y축으로 200px 이동하고 1초 동안 애니메이션됩니다.
2. .box1 요소의 transform 속성을 변경하여 Y축으로 200px 이동한 상태에서 2배 크기로 확대되고 1초 동안 애니메이션됩니다. 동시에 .box1 요소의 height 속성을 300px로 변경하고 1초 동안 애니메이션되며, width 속성을 100px로 변경하고 2초 동안 애니메이션됩니다.
3. .box1 요소의 height 속성을 100px로 변경하고 1.5초 동안 애니메이션됩니다. 동시에 .box1 요소의 background 속성을 파란색으로 변경하고 5초 동안 애니메이션됩니다.
이러한 방식으로 .with() 메서드는 이전 .next() 또는 .with() 체인과 함께 동작하고, 이후 .next()는 이전 애니메이션 체인이 완료된 후에 실행됩니다. 이렇게 하면 원하는 애니메이션 동작을 순차적으로 처리할 수 있습니다.

- 꽤나 훌륭한 답변이다.

- 하지만 오류가 계속 발생한다. height의 요소 에러로 서로 다른 css 속성에 대한 transition 속성을 별도로 설정해야 하는 기능을 추가해야 한다고 한다.

- 코드에 대한 이해가 없어도 사용 가능하지만, 대충 보면 Victoria 라는 클래스에 anim, next, with 에 대한 생성 인스턴스를 통해 생성하고, 하나의 애니메이션 타임라인 프레임을 배열로 만들어서 그 안에 순서대로 하나씩 push한 이후 .executeAnimations라는 메서드를 정의하여 순서대로 type에 따라서 실행하는 방식이다.

 

4. 테스트 중 수정

const handleClick = () => {
  vic
    .anim('.box1', 'transform', 'translateY(200px)', 1000)
    .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000)
    .with('.box1', 'height', '300px', 1000)
    .with('.box1', 'width', '100px', 2000)
    .next('.box1', 'height', '100px', 1500)
    .with('.box1', 'background', 'blue', 5000);
  vic.executeAnimations();
};

- 다음과 같은 애니메이션 동작에서 마지막 with와 그 바로전 next의 애니메이션이 동시에 동작하지 않는 오류가 있어 재검토 요청했다.

height가 100이되는 부분은 1500ms이고 background가 blue가 되는 시간은 5초인데, height가 1.5초동안 100px이 되는 동시에 5초동안은 background가 blue가 되어야 해. 오류가 있어 수정해줘 꼼꼼히 검토해줘

- 그랬더니 답변이

죄송합니다. 문제를 확인했습니다. 애니메이션 체인에 대한 기능이 원하는 대로 동작하지 않는 것 같습니다. 다음은 수정된
victoria.js 코드입니다.

- 하면서 코드를 쭉 써줬다.

- transition속성을 매번 체이닝마다 추가/삭제를 지속하다보니 중간 중간 duration이 다를 경우 애니메이션이 작동하지 않는 경우가 생겼다.

- 처음 체이닝 때 transition : all을 추가하고 체이닝의 duration에 맞추어 second 속성을 추가하고 삭제하라고 명령했더니 그렇게 해주었다.

- 다음은 몇번 수정 된 결과인데, transition 속성을 체이닝 된 duration 속성에 맞추어 변경하면서 작성되었다.

- 아래는 요청한 애니메이션 체이닝이고,

  const vic = useVictoria();

  const handleClick = () => {
    vic
      .anim('.box1', 'transform', 'translateY(200px)', 1000)

      .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000)
      .with('.box1', 'height', '300px', 1000)
      .with('.box1', 'width', '100px', 2000)

      .next('.box1', 'height', '100px', 1500)
      .with('.box1', 'background', 'blue', 1500);
    vic.executeAnimations();
  };

- 아래는 그 결과이다.

뭔가 음..

- 마지막 background가 동시에 작동하지 않았다.

- 한계가 명확했다. 요구사항을 지속적으로 추가하다보면, chatGPT가 그 이전 이전 이전 요구사항들을 전부 기억하지 못하고, 이전 몇개(1~3개)정도까지 기억했다가 잊어버리기 때문에, 전혀 예상하지 못했던 결과가 지속적으로 발생했다.

- 그래서 해결하고자 한번에 모든 요구사항을 명확하게 작성해보는 것이었다.

 

5. 해결을 위해 명확하게 조건을 제시

react에서 import 로 사용할 수 있는 타임라인 애니메이션 엔진 라이브러리를 만들거야. 요구사항과 조건은 다음과 같아.

1. 이름은 victoria.js이고, 동시 애니메이션과 타임라인에 따른 애니메이션을 구현할 예정이야.

2. 사용법은 다음과 같아.

vic
.anim('요소', 'css속성', 'css값', 애니메이션지속시간, 애니메이션실행이후콜백함수) //1번 애니메이션
.next('요소', 'css속성', 'css값', 애니메이션지속시간, 애니메이션실행이후콜백함수) //1번 종료 이후 실행
.with('요소', 'css속성', 'css값', 애니메이션지속시간, 애니메이션실행이후콜백함수) // 이전블럭과 함께 실행
//.with()는 바로 이전 .next() 혹은 .with()와 함께 동시에 동작될 애니메이션

3. .with() 애니메이션블럭은 이전 단계에 .with() 혹은 .next() 애니메이션 블럭이 있을 경우 그 애니메이션과 함께 실행되도록 해.

4. transition 속성을 이용한 css 애니메이션이 아닌 requestAnimationFrame 을 기반으로 css값을 계산하여 60FPS 의 최적화된 애니메이션을 제공해.

5. 오류는 없어야하고, 애니메이션 지속시간인 duration에 따라 각각의 애니메이션이 지속시간을 다르게 가져야해

6. 다음과 같은 테스트에 통과해야해

  const handleClick = () => {
    vic
      .anim('.box1', 'transform', 'translateY(200px)', 1000) //첫번째 타임라인

      .next('.box1', 'transform', 'translateY(200px) scale(2)', 1000) //두번째 타임라인
      .with('.box1', 'height', '300px', 1000)
      .with('.box1', 'width', '100px', 2000)

      .next('.box1', 'height', '100px', 1500) //세번째 타임라인
      .with('.box1', 'background', 'blue', 1500);
    vic.executeAnimations();
  };

handleClick이 실행 되었을 때, box1의 아이디를 가진 요소는 translateY(200px)의 애니메이션을 1초간 실행하고, 실행이 종료된 이후 scale(2)가 1초동안, height가300px로 1초동안, width가100px로 2초동안 변하는 애니메이션이 동시에 실행되야해, 실행이 종료된 이후 height가100으로 1.5초동안, background가 blue로 1.5초동안 변하는 애니메이션이 동시에 실행된 후 모든 애니메이션이 종료되는거야.

 

- 이후 몇번이고 안된다고 해결하라고 징징거려봤는데..

 

6. 결과

 

 

 

 

 

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

오늘의 결론 : 라이브러리는 만드는게 아니고 갖다 쓰는거다.

미국 성님들이 알아서 잘 만들어주신다.

 

 

- 진짜 할 서비스 없고 라이브러리를 만드는데 너무 큰 꿈이 있다면, 코드 작성 도중에 일부 메소드에 대한 개념이나 리팩토링 같은 제안들은 충분히 chatGPT와 상의할 수 있을 것 같다.

- 어제 사이드프로젝트의 좋아요버튼 기능을 chatGPT랑 함께 만들었는데, 내가 만든 코드가 있고 로직이 잘 짜여져 있으면 리팩토링이나 간단한 패턴 수정, 에러 찾기 등은 매우 잘하는 것 같다. 

- 아직 먹고 살 수 있다 ㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎㅎ

 

...

...

 

댓글