• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    미해결

검은색 영역 애니메이션이 움직이지 않습니다.

21.05.31 20:16 작성 조회수 150

0

안녕하세요 강의 잘 듣고 있습니다. 제가 강의를 보면서 따라하던 도중 이상하게 검은색 박스는 생기지만 옆으로 움직이면서 서서히 사라지는 부분이 안 됌니다. 그런데 아무리 찾아보아도 문제의 원인을 모르겠습니다.(제가 변수의 이름을 제가 알기 쉽게 바꾼게 몇개 존재합니다.)

(() => {
  let yoffset = 0;
  let prevScrollHeight = 0;//이전 스크롤 섹션의 높이를 담음
  let currentScene = 0 //현재 활성화된 씬
  let enterScene = false;
  const sectionInfo = [
    //0
    {
      type : 'sticky',
      heightNum : 5,
      height : 0,
      objs : {
        section : document.querySelector('#scroll-section-1'),
        MessageA : document.querySelector('#scroll-section-1 .main-message.a'),
        MessageB : document.querySelector('#scroll-section-1 .main-message.b'),
        MessageC : document.querySelector('#scroll-section-1 .main-message.c'),
        MessageD : document.querySelector('#scroll-section-1 .main-message.d'),
        canvas : document.querySelector('#scroll-section-1 #first_canvas'),
        ctx : document.querySelector('#scroll-section-1 #first_canvas').getContext('2d'),
      },
      values : {
        //비디오 정보
        img_values : 300,
        img_obj : [],
        imgeSequence : [0,300],
        canvas_opacity : [1,0,{start : 0.9, end : 1}],
        //투명도 조절
        messageA_fade_in : [0,1,{start : 0.1, end : 0.2}],
        messageB_fade_in : [0,1,{start : 0.3, end : 0.4}],
        messageC_fade_in : [0,1,{start : 0.5, end : 0.6}],
        messageA_fade_out : [1,0,{start : 0.25, end : 0.3}],
        messageB_fade_out : [1,0,{start : 0.45, end : 0.5}],
        messageC_fade_out : [1,0,{start : 0.65, end : 0.7}],
        //transform 조절
        messageA_transform_in : [20,0,{start: 0.1, end : 0.2}],
        messageB_transform_in : [20,0,{start: 0.3, end : 0.4}],
        messageC_transform_in : [20,0,{start: 0.5, end : 0.6}],
        messageA_transform_out : [0,-20,{start: 0.25, end : 0.3}],
        messageB_transform_out : [0,-20,{start: 0.45, end : 0.5}],
        messageC_transform_out : [0,-20,{start: 0.65, end : 0.7}],
      }
    },
    //1
    {
      type : 'normal',
      heightNum : 5,
      height : 0,
      objs : {
        section : document.querySelector('#scroll-section-2'),
      },
      values : {

      }
    },
    //2
    {
      type : 'sticky',
      heightNum : 5,
      height : 0,
      objs : {
        section : document.querySelector('#scroll-section-3'),
        desc_messageA: document.querySelector('#scroll-section-3 .desc-message.a'),
        desc_messageB : document.querySelector('#scroll-section-3 .desc-message.b'),
        desc_messageC : document.querySelector('#scroll-section-3 .desc-message.c'),
        canvas : document.querySelector('#scroll-section-3 #second_canvas'),
        ctx : document.querySelector('#scroll-section-3 #second_canvas').getContext('2d'),
      },
      values : {
        img_values : 960,
        img_obj : [],
        imgeSequence : [0,960],
        canvas_fade_in : [0,1, {start : 0.05, end : 0.1}],
        canvas_fade_out : [1,0, {start : 0.9, end : 1}],
        //투명도
        desc_messageA_fade_in : [0 , 1, {start : 0.1, end : 0.2}],
        desc_messageB_fade_in : [0 , 1, {start : 0.3, end : 0.4}],
        desc_messageC_fade_in : [0 , 1, {start : 0.5, end : 0.6}],
        desc_messageA_fade_out : [1 , 0, {start : 0.25, end : 0.3}],
        desc_messageB_fade_out : [1 , 0, {start : 0.45, end : 0.5}],
        desc_messageC_fade_out : [1 , 0, {start : 0.65, end : 0.7}],
        //transform 조절
        desc_messageA_transform_in : [20,0,{start : 0.1, end : 0.2}],
        desc_messageB_transform_in : [20,0,{start : 0.3, end : 0.4}],
        desc_messageC_transform_in : [20,0,{start : 0.5, end : 0.6}],
        desc_messageA_transform_out : [0,-20,{start : 0.25, end : 0.3}],
        desc_messageB_transform_out : [0,-20,{start : 0.45, end : 0.5}],
        desc_messageC_transform_out : [0,-20,{start : 0.65, end : 0.7}],
      }
    },
    //3
    {
      type : 'sticky',
      heightNum : 5,
      height : 0,
      objs : {
        section : document.querySelector('#scroll-section-4'),
        mainMessageA : document.querySelector('mid-message.a'),
        canvas : document.querySelector('#third_canvas'),
        ctx : document.querySelector('#third_canvas').getContext('2d'),
      },
      values : {
        imgsrc : [
          './images/blend-image-1.jpg',
          './images/blend-image-2.jpg'
        ],
        discrimination : 0,
        img_obj : [],
        recet1X : [0,0, {start: 0, end: 0}],
        recet2X : [0,0, {start: 0, end: 0}],
        rectscrollY : 0,
      }
    }
  ]
  function setHeight() {
    yoffset = window.pageYOffset;
    let totalHeight = 0; //각 섹션별 높이를 전부 담는 변수
    const canvasRatio = window.innerHeight / 1080; //마지막 캔버스를 제외한 나머지 캔버스의 비율
    for(let i = 0; i < sectionInfo.length; i++){
      let sectionNum = sectionInfo[i];
      let calcHeight = 0;
      if( sectionNum.type === 'sticky' ){
        calcHeight = window.innerHeight *  sectionNum.heightNum;
        sectionNum.height = calcHeight;
        sectionNum.objs.section.style.height = `${calcHeight}px`
      }else{
        calcHeight = sectionInfo[i].objs.section.offsetHeight;
        sectionNum.height = calcHeight;
      }
      sectionNum.objs.section.style.height = `${calcHeight}px`
    }

    for(let i = 0; i < sectionInfo.length; i++){
      totalHeight += sectionInfo[i].height;
      if( totalHeight >=  window.pageYOffset){
        currentScene = i;
        break;
      }
    }
    

    sectionInfo[0].objs.canvas.style.transform = `translate3d(-50%,-50%,0) scale(${canvasRatio})`;
    sectionInfo[2].objs.canvas.style.transform = `translate3d(-50%,-50%,0) scale(${canvasRatio})`;
    document.body.id = `show-scene-${currentScene}`;
  }

  function setCanvasImage() {
    let imgElem;
    let imgElem2;
    let imgElem3;
    for (let i = 0; i < sectionInfo[0].values.img_values; i++){
      imgElem = new Image();
      imgElem.src = `./video/001/IMG_${6726 + i}.jpg`;
      sectionInfo[0].values.img_obj.push(imgElem);
    }

    for (let i = 0; i < sectionInfo[2].values.img_values; i++){
      imgElem2 = new Image();
      imgElem2.src = `./video/002/IMG_${7027 + i}.jpg`;
      sectionInfo[2].values.img_obj.push(imgElem2);
    }

    for (let i = 0; i < sectionInfo[3].values.imgsrc.length; i++){
      imgElem3 = new Image();
      imgElem3.src = sectionInfo[3].values.imgsrc[i];
      sectionInfo[3].values.img_obj.push(imgElem3);
    }
  } 
  setCanvasImage();


  function scrollLoop() {
    enterScene = false;
    prevScrollHeight = 0;
    for(let i = 0; i < currentScene; i++){
      prevScrollHeight += sectionInfo[i].height;
    }

    if(yoffset > prevScrollHeight + sectionInfo[currentScene].height){
      enterScene = true;
      currentScene++;
      document.body.id = `show-scene-${currentScene}`;
    }
    if ( yoffset < prevScrollHeight ){
      if(yoffset < 0) return;
      enterScene = true;
      currentScene--;
      document.body.id = `show-scene-${currentScene}`;
    }
    if ( enterScene ) return;
    playAnimation();
  }


  //애니메이션 처리 값과 현재 씬에서의 스크롤 비율을 넘겨받음
  function calcValues(values,currentYoffset){
    let rv;//값을 계산해 리턴해줄 변수
    const scrollHeight = sectionInfo[currentScene].height;
    const scrollRatio = currentYoffset / sectionInfo[currentScene].height;//현재씬의 스크롤 비율
    
    if ( values.length === 3 ){
      //start ~ end 사이의 애니메이션 실행
      const partScrollStart = values[2].start * scrollHeight;
      const partScrollEnd = values[2].end * scrollHeight;
      const partScrollHeight = partScrollEnd - partScrollStart;
      if( currentYoffset >= partScrollStart && currentYoffset <= partScrollEnd ){
        rv = (currentYoffset - partScrollStart) / partScrollHeight * (values[1] - values[0] ) + values[0];
      }else if(currentYoffset < partScrollStart){
        rv = values[0]
      }
      else if ( currentYoffset > partScrollEnd ){
        rv = values[1];
      }
    }else{
      rv = scrollRatio * (values[1] - values[0] ) + values[0];
    }



    return rv;
  }

  function playAnimation() {
    const objs = sectionInfo[currentScene].objs;
    const values = sectionInfo[currentScene].values;
    const currentYoffset = yoffset - prevScrollHeight;
    const scrollHeight = sectionInfo[currentScene].height;
    const scrollRatio = currentYoffset / scrollHeight;

    switch(currentScene){
      case 0:
       if ( scrollRatio <= 0.22 ){
        objs.MessageA.style.opacity = calcValues(values.messageA_fade_in,currentYoffset);
        objs.MessageA.style.transform = `translateY(${calcValues(values.messageA_transform_in,currentYoffset)}%)`;
       }
       else{
         objs.MessageA.style.opacity = calcValues(values.messageA_fade_out,currentYoffset);
         objs.MessageA.style.transform = `translateY(${calcValues(values.messageA_transform_out,currentYoffset)}%)`;
       }
       if(scrollRatio < 0.43){
          objs.MessageB.style.opacity = calcValues(values.messageB_fade_in,currentYoffset);
          objs.MessageB.style.transform = `translateY(${calcValues(values.messageB_transform_in,currentYoffset)}%)`;
       }else{
          objs.MessageB.style.opacity = calcValues(values.messageB_fade_out,currentYoffset);
          objs.MessageB.style.transform = `translateY(${calcValues(values.messageB_transform_out,currentYoffset)}%)`;
       }
       if( scrollRatio < 0.63 ){
          objs.MessageC.style.opacity = calcValues(values.messageC_fade_in,currentYoffset);
          objs.MessageC.style.transform = `translateY(${calcValues(values.messageC_transform_in,currentYoffset)}%)`;
       }else{
          objs.MessageC.style.opacity = calcValues(values.messageC_fade_out,currentYoffset);
          objs.MessageC.style.transform = `translateY(${calcValues(values.messageC_transform_out,currentYoffset)}%)`;
       }
       let imgeSequence = Math.floor(calcValues(sectionInfo[0].values.imgeSequence,currentYoffset));
       objs.ctx.drawImage(values.img_obj[imgeSequence],0,0);
       objs.canvas.style.opacity = calcValues(values.canvas_opacity,currentYoffset);
        break;
      case 1:
        break;
      case 2:
        if( scrollRatio <=  0.22 ){
         objs.desc_messageA.style.opacity = calcValues(values.desc_messageA_fade_in,currentYoffset);
         objs.desc_messageA.style.transform = `translate3d(-50%, ${calcValues(values.desc_messageA_transform_in,currentYoffset)}%, 0)`;
        }
        else{
          objs.desc_messageA.style.opacity = calcValues(values.desc_messageA_fade_out,currentYoffset);
          objs.desc_messageA.style.transform = `translate3d(-50%, ${calcValues(values.desc_messageA_transform_out,currentYoffset)}%, 0)`;
        }
        if ( scrollRatio < 0.42 ){
          objs.desc_messageB.style.opacity = calcValues(values.desc_messageB_fade_in,currentYoffset);
          objs.desc_messageB.style.transform = `translate3d(-50%, ${calcValues(values.desc_messageB_transform_in,currentYoffset)}%, 0)`;
        }else{
          objs.desc_messageB.style.opacity = calcValues(values.desc_messageB_fade_out,currentYoffset);
          objs.desc_messageB.style.transform = `translate3d(-50%, ${calcValues(values.desc_messageB_transform_out,currentYoffset)}%, 0)`;
        }
        if ( scrollRatio < 0.62 ){
          objs.desc_messageC.style.opacity = calcValues(values.desc_messageC_fade_in,currentYoffset);
          objs.desc_messageC.style.transform = `translate3d(-50%, ${calcValues(values.desc_messageC_transform_in,currentYoffset)}%, 0)`;
        }else{
          objs.desc_messageC.style.opacity = calcValues(values.desc_messageC_fade_out,currentYoffset);
          objs.desc_messageC.style.transform = `translate3d(-50%, ${calcValues(values.desc_messageC_transform_out,currentYoffset)}%, 0)`;
        }
        if(scrollRatio < 0.5){
          objs.canvas.style.opacity = calcValues(values.canvas_fade_in,currentYoffset);
        }else{
          objs.canvas.style.opacity = calcValues(values.canvas_fade_out,currentYoffset);
        }
        let imageSequence2 = Math.floor(calcValues(values.imgeSequence,currentYoffset));
        objs.ctx.drawImage(values.img_obj[imageSequence2],0,0);
        break;
      case 3:
        const widthRatio = window.innerWidth / objs.canvas.width;
        const heightRatio = window.innerHeight / objs.canvas.height;
        if ( widthRatio <= heightRatio ){
          objs.canvas.style.transform = `scale(${heightRatio})`;
        }else{
          objs.canvas.style.transform = `scale(${widthRatio})`;
        }
        const newWidth = document.body.offsetWidth / widthRatio//안쪽의 content영역의 width값을 구하기 위한 계산
        const newheight = window.innerHeight / heightRatio//안쪽의 content영역의 높이를 구하기 위한 계산
        const blockArea = newWidth * 0.15;
        values.recet1X[0] = (objs.canvas.width - newWidth) / 2; // 애니메이션 시작 지점을 계산
        values.recet1X[1] = values.recet1X[0] - blockArea;//애니메이션 끝 지점을 계산
        values.recet2X[0] = (values.recet1X[0] + newWidth) - blockArea; // 오른쪽 블록의 애니메이션 시작지점을 계산
        values.recet2X[1] = values.recet2X[1] + blockArea//오른쪽 애니메이션의 끝 지점을 지정
        if(!values.rectscrollY){
          values.rectscrollY = objs.canvas.getBoundingClientRect().top;
          values.recet1X[2].end = values.rectscrollY / scrollHeight;
          values.recet2X[2].end = values.rectscrollY / scrollHeight;
        }
        objs.ctx.fillRect(
					parseInt(calcValues(values.recet1X, currentYoffset)),
					0,
					parseInt(blockArea),
					objs.canvas.height
				);
				objs.ctx.fillRect(
					parseInt(calcValues(values.recet2X, currentYoffset)),
					0,
					parseInt(blockArea),
					objs.canvas.height
				);
        break;
    }
  }

  window.addEventListener('resize',setHeight);
  window.addEventListener('scroll',() => {
    yoffset = window.pageYOffset;
    scrollLoop()
  });
  window.addEventListener('load',() => {
    setHeight();
    sectionInfo[0].objs.ctx.drawImage(sectionInfo[0].values.img_obj[0],0,0);
    sectionInfo[3].objs.ctx.drawImage(sectionInfo[3].values.img_obj[0],0,0);
  });
})();

답변 0

답변을 작성해보세요.

답변을 기다리고 있는 질문이에요.
첫번째 답변을 남겨보세요!