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 지점
// 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
}
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
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라는 숫자를 어디서 구해와야 하지?"
// ✅ 올바른 인식
"400에서 25로 변화시키려면 375만큼 줄여야 하네"
// 공식은 "변화의 규칙"을 정의
현재값 = 시작값 - (진행률 × 변화량)
// 여기서 각 요소의 출처:
시작값(400) ← 디자인 요구사항
끝값(25) ← 디자인 요구사항
변화량(375) ← 수학적 계산 (400-25)
진행률 ← 스크롤 위치 (동적)
1️⃣ 요구사항: "400px 원형에서 25px 둥근 사각형으로"
2️⃣ 수학 선택: "선형 보간 사용"
3️⃣ 매개변수: "변화량 = 400 - 25 = 375"
4️⃣ 공식 완성: "current = 400 - progress × 375"
5️⃣ 런타임: "스크롤할 때마다 progress만 바뀜"
💡 핵심: 375는 한 번 계산되고, 이후엔 고정된 상수로 사용됩니다!
이제 순환 논리의 함정에서 벗어나셨나요? 😊