미해결
애플 웹사이트 인터랙션 클론!
첫번째 문제 발생현상 : 새로고침 했을 경우 간혈적으로 이런 에러 문구가 출력이 됩니다. 섹션0부분에 이미지파일은 눈으로 봤을땐 정상적으로 출력된 상황입니다. 에러문구는 하단에 붙히겠습니다. main.js:258 Uncaught TypeError: Failed to execute 'drawImage' on 'CanvasRenderingContext2D': The provided value is not of type '(CSSImageValue or HTMLImageElement or SVGImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)' at playAnimation (main.js:258) at scrollLoop (main.js:364) at main.js:368 두번째 문제 발생현상 : 이것도 간혈적으로 출력되는 문제이며 main.js:352 Uncaught TypeError: Cannot read property 'scrollHeight' of undefined at scrollLoop (main.js:352) at main.js:368 이러 한 문구가 출력이 됩니다. 정말 죄송하지만 제 코드한번 봐주실수 있을까요?? ( () => { let yOffset = 0 ; //window.pageYOffset 대신 쓸 변수 let prevScrollHeight = 0 ; // 현재 스크롤 위치(yOffset)보다 이전에 위치한 스크롤 섹션들의 스크롤 높이값의 합 let currentScene = 0 ; // 현재 활성화된(눈 앞에 보고있는) 씬(scroll-section) let enterNewScene = false ; // 새로운 scene이 시작된 순간 true const sceneInfo = [ { // 0 type : ' sticky ' , heightNum : 5 , // 브라우저 높이의 5배로 scrollHeight 세팅 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 ' ) , canvas : document . querySelector ( ' #video-canvas-0 ' ) , context : document . querySelector ( ' #video-canvas-0 ' ) . getContext ( ' 2d ' ) , videoImages : [] }, values : { videoImageCount : 300 , imageSequence : [ 0 , 299 ] , messageA_opacity_in : [ 0 , 1 , { start : 0.1 , end : 0.2 } ] , messageB_opacity_in : [ 0 , 1 , { start : 0.3 , end : 0.4 } ] , messageC_opacity_in : [ 0 , 1 , { start : 0.5 , end : 0.6 } ] , messageD_opacity_in : [ 0 , 1 , { start : 0.7 , end : 0.8 } ] , messageA_translateY_in : [ 20 , 0 , { start : 0.1 , end : 0.2 } ] , messageB_translateY_in : [ 20 , 0 , { start : 0.3 , end : 0.4 } ] , messageC_translateY_in : [ 20 , 0 , { start : 0.5 , end : 0.6 } ] , messageD_translateY_in : [ 20 , 0 , { start : 0.7 , end : 0.8 } ] , messageA_opacity_out : [ 1 , 0 , { start : 0.25 , end : 0.3 } ] , messageB_opacity_out : [ 1 , 0 , { start : 0.45 , end : 0.5 } ] , messageC_opacity_out : [ 1 , 0 , { start : 0.65 , end : 0.7 } ] , messageD_opacity_out : [ 1 , 0 , { start : 0.85 , end : 0.9 } ] , messageA_translateY_out : [ 0 , - 20 , { start : 0.25 , end : 0.3 } ] , messageB_translateY_out : [ 0 , - 20 , { start : 0.45 , end : 0.5 } ] , messageC_translateY_out : [ 0 , - 20 , { start : 0.65 , end : 0.7 } ] , messageD_translateY_out : [ 0 , - 20 , { start : 0.85 , end : 0.9 } ] } }, { // 1 type : ' normal ' , // heightNum: 5, // type normal에서는 필요 없음 scrollHeight : 0 , objs : { container : document . querySelector ( ' #scroll-section-1 ' ) , content : document . querySelector ( ' #scroll-section-1 .description ' ) } }, { // 2 type : ' sticky ' , heightNum : 5 , scrollHeight : 0 , objs : { container : document . querySelector ( ' #scroll-section-2 ' ) , messageA : document . querySelector ( ' #scroll-section-2 .a ' ) , messageB : document . querySelector ( ' #scroll-section-2 .b ' ) , messageC : document . querySelector ( ' #scroll-section-2 .c ' ) , pinB : document . querySelector ( ' #scroll-section-2 .b .pin ' ) , pinC : document . querySelector ( ' #scroll-section-2 .c .pin ' ) }, values : { messageA_translateY_in : [ 20 , 0 , { start : 0.15 , end : 0.2 } ] , messageB_translateY_in : [ 30 , 0 , { start : 0.6 , end : 0.65 } ] , messageC_translateY_in : [ 30 , 0 , { start : 0.87 , end : 0.92 } ] , messageA_opacity_in : [ 0 , 1 , { start : 0.25 , end : 0.3 } ] , messageB_opacity_in : [ 0 , 1 , { start : 0.6 , end : 0.65 } ] , messageC_opacity_in : [ 0 , 1 , { start : 0.87 , end : 0.92 } ] , messageA_translateY_out : [ 0 , - 20 , { start : 0.4 , end : 0.45 } ] , messageB_translateY_out : [ 0 , - 20 , { start : 0.68 , end : 0.73 } ] , messageC_translateY_out : [ 0 , - 20 , { start : 0.95 , end : 1 } ] , messageA_opacity_out : [ 1 , 0 , { start : 0.4 , end : 0.45 } ] , messageB_opacity_out : [ 1 , 0 , { start : 0.68 , end : 0.73 } ] , messageC_opacity_out : [ 1 , 0 , { start : 0.95 , end : 1 } ] , pinB_scaleY : [ 0.5 , 1 , { start : 0.6 , end : 0.65 } ] , pinC_scaleY : [ 0.5 , 1 , { start : 0.87 , end : 0.92 } ] } }, { // 3 type : ' sticky ' , heightNum : 5 , scrollHeight : 0 , objs : { container : document . querySelector ( ' #scroll-section-3 ' ) , canvasCaption : document . querySelector ( ' .canvas-caption ' ) }, values : { } } ] ; function setCanvasImages () { for ( let i = 0 ; i < sceneInfo [ 0 ] . values . videoImageCount ; i ++ ) { imgElem = new Image () ; imgElem . src = ` ./video/001/IMG_ ${ 6726 + i } .JPG ` ; sceneInfo [ 0 ] . objs . videoImages . push ( imgElem ) ; } } setCanvasImages () function setLayout () { // 각 스크롤 섹션의 높이 세팅 for ( let i = 0 ; i < sceneInfo . length ; i ++ ) { if ( sceneInfo [ i ] . type === ' sticky ' ) { sceneInfo [ i ] . scrollHeight = sceneInfo [ i ] . heightNum * window . innerHeight ; } else if ( sceneInfo [ i ] . type === ' normal ' ) { sceneInfo [ i ] . scrollHeight = sceneInfo [ i ] . objs . content . offsetHeight + window . innerHeight * 0.5 ; } sceneInfo [ i ] . objs . container . style . height = `${ sceneInfo[i] . scrollHeight } px ` ; } yOffset = window . pageYOffset ; let totalScrollHeight = 0 ; for ( let i = 0 ; i < sceneInfo . length ; i ++ ) { totalScrollHeight += sceneInfo [ i ] . scrollHeight ; if ( totalScrollHeight >= yOffset ) { currentScene = i ; break ; } } document . body . setAttribute ( ' id ' , ` show-scene- ${ currentScene }` ) ; } function calcValues ( values , currentYOffset ) { let rv ; //현재 씬(스크롤섹션)에서 스크롤된 범위를 비율로 구하기 const scrollHeight = sceneInfo [ currentScene ] . scrollHeight ; const scrollRatio = currentYOffset / scrollHeight ; 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 = sceneInfo [ currentScene ] . objs ; const values = sceneInfo [ currentScene ] . values ; const currentYOffset = yOffset - prevScrollHeight ; const scrollHeight = sceneInfo [ currentScene ] . scrollHeight ; const scrollRatio = currentYOffset / scrollHeight ; switch ( currentScene ) { case 0 : let sequence = Math . round ( calcValues ( values . imageSequence , currentYOffset )) ; objs . context . drawImage ( objs . videoImages [ sequence ] , 0 , 0 ) ; if ( scrollRatio <= 0.22 ) { // in objs . messageA . style . opacity = calcValues ( values . messageA_opacity_in , currentYOffset ) ; objs . messageA . style . transform = ` translate3d(0, ${ calcValues (values . messageA_translateY_in , currentYOffset) } %, 0) ` ; } else { // out objs . messageA . style . opacity = calcValues ( values . messageA_opacity_out , currentYOffset ) ; objs . messageA . style . transform = ` translate3d(0, ${ calcValues (values . messageA_translateY_out , currentYOffset) } %, 0) ` ; } if ( scrollRatio <= 0.42 ) { // in objs . messageB . style . opacity = calcValues ( values . messageB_opacity_in , currentYOffset ) ; objs . messageB . style . transform = ` translate3d(0, ${ calcValues (values . messageB_translateY_in , currentYOffset) } %, 0) ` ; } else { // out objs . messageB . style . opacity = calcValues ( values . messageB_opacity_out , currentYOffset ) ; objs . messageB . style . transform = ` translate3d(0, ${ calcValues (values . messageB_translateY_out , currentYOffset) } %, 0) ` ; } if ( scrollRatio <= 0.62 ) { // in objs . messageC . style . opacity = calcValues ( values . messageC_opacity_in , currentYOffset ) ; objs . messageC . style . transform = ` translate3d(0, ${ calcValues (values . messageC_translateY_in , currentYOffset) } %, 0) ` ; } else { // out objs . messageC . style . opacity = calcValues ( values . messageC_opacity_out , currentYOffset ) ; objs . messageC . style . transform = ` translate3d(0, ${ calcValues (values . messageC_translateY_out , currentYOffset) } %, 0) ` ; } if ( scrollRatio <= 0.82 ) { // in objs . messageD . style . opacity = calcValues ( values . messageD_opacity_in , currentYOffset ) ; objs . messageD . style . transform = ` translate3d(0, ${ calcValues (values . messageD_translateY_in , currentYOffset) } %, 0) ` ; } else { // out objs . messageD . style . opacity = calcValues ( values . messageD_opacity_out , currentYOffset ) ; objs . messageD . style . transform = ` translate3d(0, ${ calcValues (values . messageD_translateY_out , currentYOffset) } %, 0) ` ; } break ; case 2 : // console.log('2 play'); if ( scrollRatio <= 0.32 ) { // in objs . messageA . style . opacity = calcValues ( values . messageA_opacity_in , currentYOffset ) ; objs . messageA . style . transform = ` translate3d(0, ${ calcValues (values . messageA_translateY_in , currentYOffset) } %, 0) ` ; } else { // out objs . messageA . style . opacity = calcValues ( values . messageA_opacity_out , currentYOffset ) ; objs . messageA . style . transform = ` translate3d(0, ${ calcValues (values . messageA_translateY_out , currentYOffset) } %, 0) ` ; } if ( scrollRatio <= 0.67 ) { // in objs . messageB . style . transform = ` translate3d(0, ${ calcValues (values . messageB_translateY_in , currentYOffset) } %, 0) ` ; objs . messageB . style . opacity = calcValues ( values . messageB_opacity_in , currentYOffset ) ; objs . pinB . style . transform = ` scaleY( ${ calcValues (values . pinB_scaleY , currentYOffset) } ) ` ; } else { // out objs . messageB . style . transform = ` translate3d(0, ${ calcValues (values . messageB_translateY_out , currentYOffset) } %, 0) ` ; objs . messageB . style . opacity = calcValues ( values . messageB_opacity_out , currentYOffset ) ; objs . pinB . style . transform = ` scaleY( ${ calcValues (values . pinB_scaleY , currentYOffset) } ) ` ; } if ( scrollRatio <= 0.93 ) { // in objs . messageC . style . transform = ` translate3d(0, ${ calcValues (values . messageC_translateY_in , currentYOffset) } %, 0) ` ; objs . messageC . style . opacity = calcValues ( values . messageC_opacity_in , currentYOffset ) ; objs . pinC . style . transform = ` scaleY( ${ calcValues (values . pinC_scaleY , currentYOffset) } ) ` ; } else { // out objs . messageC . style . transform = ` translate3d(0, ${ calcValues (values . messageC_translateY_out , currentYOffset) } %, 0) ` ; objs . messageC . style . opacity = calcValues ( values . messageC_opacity_out , currentYOffset ) ; objs . pinC . style . transform = ` scaleY( ${ calcValues (values . pinC_scaleY , currentYOffset) } ) ` ; } break ; case 3 : // console.log('3 play'); break ; } } function scrollLoop () { enterNewScene = false ; prevScrollHeight = 0 ; for ( let i = 0 ; i < currentScene ; i ++ ) { prevScrollHeight += sceneInfo [ i ] . scrollHeight ; } if ( yOffset > prevScrollHeight + sceneInfo [ currentScene ] . scrollHeight ) { enterNewScene = true ; currentScene ++; document . body . setAttribute ( ' id ' , ` show-scene- ${ currentScene }` ) ; } if ( yOffset < prevScrollHeight ) { if ( currentScene === 0 ) return // 브라우저 바운스 효과로 인해 마이너스가 되는 것을 방지(모바일) enterNewScene = true ; currentScene --; document . body . setAttribute ( ' id ' , ` show-scene- ${ currentScene }` ) ; } if ( enterNewScene ) return ; playAnimation () ; } window . addEventListener ( ' scroll ' , () => { yOffset = window . pageYOffset ; scrollLoop () ; } ) ; //window.addEventListener('DOMContentLoaded', setLayout); window . addEventListener ( ' load ' , setLayout ) ; window . addEventListener ( ' resize ' , setLayout ) ; } )() ;
svg 웹 디자인 javascript HTML/CSS 인터랙티브-웹 클론코딩
mario213
2021-01-01T09:09:19.071Z
댓글 2
좋아요 0
조회수 263