인프런 커뮤니티 질문&답변

DDU님의 프로필 이미지
DDU

작성한 질문수

애플 웹사이트 인터랙션 클론!

특정 타이밍 스크롤 애니메이션 기능 추가

translateY대신 애플에서 사용한 것 처럼 matrix로 scale의 크기를 주려고 하는데

작성

·

329

0

안녕하세요!! 강의를 전부 듣고 코드를 뜯어보며 복습중에 있습니다. section-0에서 사용한 것을 이용해 스크롤 될 때 matrix로 Text에 scale(80)정도로 주려고 코드를 입력해보니 적용은 되었으나 스크롤을 빠르게 올릴시에 정상적으로 사이즈가 줄어들지 않고 줄어들다 말거나 그러더라구요...ㅠㅠ 폰트 픽셀도 많이 깨지는 현상이 발생하구요. 혹시 해결하려면 어떤식으로 접근해야 할까요? 해당 코드 첨부드립니다.

 

 const sectionInfo = [
    {
      // section-0
      type: "sticky",
      heightNum: 5,
      scrollHeight: 0,
      objs: {
        container: document.querySelector("#scroll-section-0"),
        messageA: document.querySelector("#scroll-section-0 .main-message.a"),
        messageB: document.querySelector("#scroll-section-0 .main-message.b"),
        messageC: document.querySelector("#scroll-section-0 .main-message.c"),
        messageD: document.querySelector("#scroll-section-0 .main-message.d"),
      },
      values: {
        messageA_opacity_in: [0.4, 1, { start: 0, end: 0.05 }],
        messageA_opacity_out: [1, 0, { start: 0.15, end: 0.2 }],
        messageA_scale_in: [1, 80, { start: 0.05, end: 0.25 }],
        messageA_scale_out: [80, 1, { start: 0.25, end: 0.05 }],
        messageB_opacity_in: [0, 1, { start: 0.2, end: 0.25 }],
        messageB_opacity_out: [1, 0, { start: 0.35, end: 0.4 }],
        messageB_translateY_in: [50, 0, { start: 0.2, end: 0.25 }],
        messageB_translateY_out: [0, -50, { start: 0.35, end: 0.4 }],
        messageC_opacity_in: [0, 1, { start: 0.4, end: 0.45 }],
        messageC_opacity_out: [1, 0, { start: 0.55, end: 0.6 }],
        messageC_translateY_in: [50, 0, { start: 0.4, end: 0.45 }],
        messageC_translateY_out: [0, -50, { start: 0.55, end: 0.6 }],
        messageD_opacity_in: [0, 1, { start: 0.6, end: 0.65 }],
        messageD_opacity_out: [1, 0, { start: 0.75, end: 0.8 }],
        messageD_translateY_in: [50, 0, { start: 0.6, end: 0.65 }],
        messageD_translateY_out: [0, -50, { start: 0.75, end: 0.8 }],
      },
    },
  ];

  function calcValues(values, currentScrollY) {
    let returnValue;

    const currentSectionHeight = sectionInfo[currentSection].scrollHeight;
    // 현재 스크롤 섹션에서 스크롤 된 범위를 비율로 구하는 식
    const scrollRatio = currentScrollY / currentSectionHeight;

    if (values.length === 3) {
      const scrollAniStart = values[2].start * currentSectionHeight;
      const scrollAniEnd = values[2].end * currentSectionHeight;
      const scrollAniHeight = scrollAniEnd - scrollAniStart;

      if (currentScrollY >= scrollAniStart && currentScrollY <= scrollAniEnd) {
        returnValue =
          ((currentScrollY - scrollAniStart) / scrollAniHeight) *
            (values[1] - values[0]) +
          values[0];
      } else if (currentScrollY < scrollAniStart) {
        returnValue = values[0];
      } else if (currentScrollY > scrollAniEnd) {
        returnValue = values[1];
      }
    } else {
      returnValue = scrollRatio * (values[1] - values[0]) + values[0];
    }

    return returnValue;
  }

  function playAnimation() {
    const objs = sectionInfo[currentSection].objs;
    const values = sectionInfo[currentSection].values;
    const currentScrollY = scrollY - prevScrollHeight;
    const currentSectionHeight = sectionInfo[currentSection].scrollHeight;
    const scrollRatio = currentScrollY / currentSectionHeight;

    switch (currentSection) {
      case 0:
        // message
        if (scrollRatio <= 0.05) {
          objs.messageA.style.opacity = calcValues(
            values.messageA_opacity_in,
            currentScrollY
          );
        } else {
          objs.messageA.style.opacity = calcValues(
            values.messageA_opacity_out,
            currentScrollY
          );
          objs.messageA.style.transform = `matrix(${calcValues(
            values.messageA_scale_in,
            currentScrollY
          )}, 0, 0, ${calcValues(
            values.messageA_scale_in,
            currentScrollY
          )}, 0, 0)`;
        }

답변 1

0

안녕하세요, 인프런 AI 인턴이에요.

translateY 대신 matrix로 scale의 크기를 주려하시는 것 같아요. 그리고 스크롤을 빠르게 올리면 사이즈가 제대로 줄어들지 않아 폰트 픽셀이 깨지는 문제가 발생한다고 하셨네요.

scale 속성을 matrix로 변환하여 직접 사용하면 다양한 형태의 애니메이션을 만들 수 있어 좋은 방법이에요. 그렇지만, matrix를 사용하면 애니메이션의 복잡성이 증가할 수 있어 원하는 결과를 얻기까지 실패할 가능성도 있어요.

이 경우, requestAnimationFrame을 사용하여 중간 프레임에서 좀 더 자연스럽게 애니메이션 전환을 할 수 있도록 구현하실 수 있어요. 또는, CSS 애니메이션 기능을 이용하여 해당 요소에 transition 속성을 추가하여 애니메이션을 부드럽게 구현할 수 있습니다.

해당 코드를 수정하는 방법으로는 요소의 scale 값이 80 이상이 되면 transition 속성을 추가하던가, 요소의 width, height 값을 조정하여 폰트 픽셀 깨짐 문제를 해결하는 방법도 있을 것 같습니다.

좀 더 자세한 것은 코드를 직접 보지 않으면 정확한 조언을 드리기 어렵습니다. 하지만 어떤 방법이 옳은 방법인지 참고할 수 있도록 답변해드렸습니다.

더 궁금하신 점이 있으면 언제든지 물어봐주세요!

DDU님의 프로필 이미지
DDU

작성한 질문수

질문하기