역방향 선형보간 계산법과 시작값 결정 원리-2

calm·2025년 6월 29일
0

GSAP애니메이션

목록 보기
4/8

375를 직접 구해서 다시 375를 차감하는 것이 논리적으로 이상해 보이죠. 이 순환 논리의 함정을 수학적 원리부터 실제 구현까지 완전히 해결해드리겠습니다.


🤔 문제 인식: 순환 논리의 함정

겉보기 모순

// 1단계: 375를 계산함
감소량 = 400 - 25 = 375

// 2단계: 그 375를 다시 사용함  
borderRadius = 400 - progress * 375

// 🤯 "375를 구하기 위해 25를 알아야 하는데, 
//     25를 얻기 위해 375를 써야 한다?"

실제 논리 흐름

// 실제로는 이런 순서입니다:
1. 디자인 목표 설정: "400px에서 25px로 변화시키고 싶다"
2. 수학적 공식 도출: "선형 보간을 사용하자"
3. 공식 매개변수 계산: "변화량 = 400 - 25 = 375"
4. 공식 완성: "value = 400 - progress * 375"

🎯 올바른 이해: 디자인 우선 접근법

실제 개발자의 사고 과정

1단계: 비즈니스/디자인 요구사항

// PM/디자이너가 요청:
"처음엔 완전한 (400px)이었다가 
 스크롤하면서 둥근 사각형(25px)이 되게 해주세요"

const START_RADIUS = 400;  // 요구사항에서 주어짐
const END_RADIUS = 25;     // 요구사항에서 주어짐

2단계: 수학적 공식 선택

// 개발자가 판단:
"스크롤에 따라 선형적으로 변화시키자"
// 선형 보간 공식: current = start + progress * (end - start)
// 또는 역방향: current = start - progress * (start - end)

3단계: 공식 매개변수 계산

// 공식에 필요한 값들 계산
const CHANGE_AMOUNT = START_RADIUS - END_RADIUS;
const CHANGE_AMOUNT = 400 - 25; // 375

// 이제 375는 "계산된 매개변수"일 뿐

4단계: 런타임 공식 실행

// 스크롤할 때마다 실행되는 공식
function updateBorderRadius(progress) {
  return START_RADIUS - progress * CHANGE_AMOUNT;
  //     400         - progress * 375
}

🔄 일상생활 비유: 길찾기 내비게이션

목적지까지의 거리 계산

// 1단계: 목적지 설정 (디자인 요구사항)
출발지 = "서울역" (위치: 400km 지점)
목적지 = "부산역" (위치: 25km 지점)

// 2단계: 총 이동거리 계산 (매개변수 계산)
총_이동거리 = 400 - 25 = 375km

// 3단계: 현재 위치 계산 공식 (런타임 실행)
현재_위치 = 400 - 진행률 * 375

// 진행률 50%일 때:
현재_위치 = 400 - 0.5 * 375 = 212.5km 지점

핵심 포인트

  • 375km는 미리 계산된 고정값
  • 런타임에서는 단순히 그 값을 사용
  • 순환 논리가 아니라 단계별 계산

💻 실제 코드 구현: 단계별 분리

방법 1: 설정 분리형

// config.js - 설정값 정의
const ANIMATION_CONFIG = {
  borderRadius: {
    start: 400,    // 디자인 명세서에서 가져옴
    end: 25,       // 디자인 명세서에서 가져옴
    get change() { 
      return this.start - this.end; // 375 (계산됨)
    }
  }
};

// animation.js - 런타임 실행
function updateBorderRadius(progress) {
  const config = ANIMATION_CONFIG.borderRadius;
  return config.start - progress * config.change;
  //     400         - progress * 375
}

방법 2: 클래스 기반

class BorderRadiusAnimation {
  constructor(startValue, endValue) {
    this.start = startValue;     // 400
    this.end = endValue;         // 25  
    this.change = startValue - endValue; // 375 (한번만 계산)
  }
  
  getValue(progress) {
    return this.start - progress * this.change;
  }
}

// 사용
const radiusAnim = new BorderRadiusAnimation(400, 25);
const currentRadius = radiusAnim.getValue(0.5); // 212.5

방법 3: 함수 팩토리

function createReverseAnimation(start, end) {
  const changeAmount = start - end; // 375 (클로저에 저장)
  
  return function(progress) {
    return start - progress * changeAmount;
  };
}

// 사용
const getBorderRadius = createReverseAnimation(400, 25);
const currentRadius = getBorderRadius(0.5); // 212.5

🧮 수학적 증명: 왜 이 방법이 올바른가

선형 보간의 일반 공식

// 수학적 정의
y = start + t * (end - start)

// 여기서:
// y = 현재값
// start = 시작값
// end = 끝값  
// t = 진행률 (0~1)

역방향 변형

// 일반형: y = start + t * (end - start)
// 역방향: y = start - t * (start - end)

// 수학적으로 동일함을 증명:
y = start + t * (end - start)
y = start + t * end - t * start  
y = start - t * start + t * end
y = start - t * (start - end)    // 역방향 공식!

구체적 적용

// start=400, end=25일 때
y = 400 + progress * (25 - 400)
y = 400 + progress * (-375)
y = 400 - progress * 375        // 최종 공식

// 375는 수학적 유도의 결과물

🎨 더 직관적인 사고법

백분율 관점

// "진행률에 따라 얼마나 줄어들까?"
진행률_0%400px (100% 크기)
진행률_50%212.5px (53.125% 크기)  
진행률_100%25px (6.25% 크기)

// 375는 "줄어들 수 있는 최대량"
최대_감소량 = 400 - 25 = 375px
현재_감소량 = 진행률 * 최대_감소량
현재_크기 = 원래_크기 - 현재_감소량

물탱크 비유

// 물탱크에서 물 빼기
탱크_용량 = 400리터 (가득참)
목표_용량 = 25리터 (거의 비움)
배출_가능량 = 400 - 25 = 375리터

// 배출 진행률에 따른 현재 수위
현재_수위 = 400 - 진행률 * 375

// 50% 배출했을 때:
현재_수위 = 400 - 0.5 * 375 = 212.5리터

실전 팁: 코드 가독성 높이기

의미 있는 변수명 사용

// 나쁜 예
borderRadius = 400 - progress * 375;

// 좋은 예  
const CIRCLE_RADIUS = 400;
const ROUNDED_SQUARE_RADIUS = 25;
const TOTAL_RADIUS_DECREASE = CIRCLE_RADIUS - ROUNDED_SQUARE_RADIUS;

borderRadius = CIRCLE_RADIUS - progress * TOTAL_RADIUS_DECREASE;

주석으로 의도 명확화

// Border radius 애니메이션: 원형 → 둥근 사각형
const borderRadiusAnimation = {
  start: 400,    // 완전한 원을 위한 radius
  end: 25,       // 살짝 둥근 사각형을 위한 radius
  range: 375,    // 총 변화량 (400 - 25)
  
  getValue(progress) {
    // 진행률에 따라 원형에서 사각형으로 변화
    return this.start - progress * this.range;
  }
};

🔧 자동화 도구 만들기

범용 애니메이션 생성기

function createLinearAnimation(from, to, direction = 'forward') {
  const range = Math.abs(to - from);
  
  if (direction === 'forward') {
    // 값이 증가하는 애니메이션
    return (progress) => from + progress * range;
  } else {
    // 값이 감소하는 애니메이션  
    return (progress) => from - progress * range;
  }
}

// 사용 예시
const radiusAnim = createLinearAnimation(400, 25, 'reverse');
const scaleAnim = createLinearAnimation(0.5, 1.0, 'forward');

🎯 핵심 깨달음

375는 "마법의 숫자"가 아니다

// ❌ 잘못된 인식
"375라는 숫자를 어디서 구해와야 하지?"

// ✅ 올바른 인식  
"400에서 25로 변화시키려면 375만큼 줄여야 하네"

공식의 본질

// 공식은 "변화의 규칙"을 정의
현재값 = 시작값 - (진행률 × 변화량)

// 여기서 각 요소의 출처:
시작값(400) ← 디자인 요구사항
끝값(25) ← 디자인 요구사항  
변화량(375) ← 수학적 계산 (400-25)
진행률 ← 스크롤 위치 (동적)

🎭 완전한 이해를 위한 단계별 정리

1️⃣ 요구사항: "400px 원형에서 25px 둥근 사각형으로"
2️⃣ 수학 선택: "선형 보간 사용"
3️⃣ 매개변수: "변화량 = 400 - 25 = 375"
4️⃣ 공식 완성: "current = 400 - progress × 375"
5️⃣ 런타임: "스크롤할 때마다 progress만 바뀜"

💡 핵심: 375는 한 번 계산되고, 이후엔 고정된 상수로 사용됩니다!

이제 순환 논리의 함정에서 벗어나셨나요? 😊

profile
공부한 내용을 기록합니다

0개의 댓글