문제 사항이 있어서 질문드립니다.
0.1 에서 0.2 부분까지는 잘되지만 0.25에서 0.3 가는 부분에서 텍스트가 덜컹거립니다.
어느 부분이 문제인지 궁굼하니다.
(()=>{
let yOffset = 0; // window.pageYOffset 대신 쓸 변수
let prevScrollHeight = 0; // 현재 스크롤 위치보다 이전에 위치한 스크롤 섹션들의 스크롤 높이의 합
let currentScene = 0; // 현재 활성화된( 눈 앞에 보고 있는 ) 씬 ( scroll-section)
let enterNewScene = false; // 새로운 scene 이 시작되는 순간 true;
const sceneInfo = [
{
// scrollSection : 0
type : 'sticky',
heightNum : 5, // 브라우저 높이의 5배로 scollHeight 세팅
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, 1, { start: 0.1, end: 0.2 }],
messageA_translateY_in: [20, 0, { start: 0.1, end: 0.2 }],
messageA_opacity_out: [1, 0, { start: 0.25, end: 0.3 }],
messageA_translateY_out:[0, -20,{start:0.25, end: 0.3}],
}
},
{
// scrollSection 번호 : 1
type : 'normal',
heightNum : 5, // 브라우저 높이의 5배로 scollHeight 세팅
scrollHeight: 0,
objs: {
container: document.querySelector("#scroll-section-1")
}
},
{
// scrollSection 번호 : 2
type : 'sticky',
heightNum : 5, // 브라우저 높이의 5배로 scollHeight 세팅
scrollHeight: 0,
objs: {
container: document.querySelector("#scroll-section-2")
}
},
{
// scrollSection 번호 : 3
type : 'sticky',
heightNum : 5, // 브라우저 높이의 5배로 scollHeight 세팅
scrollHeight: 0,
objs: {
container: document.querySelector("#scroll-section-3")
}
}
];
function setLayout() {
// 각 스크롤 섹션의 높이 세팅
for(let i = 0; i < sceneInfo.length; i++){
sceneInfo[i].scrollHeight = sceneInfo[i].heightNum * window.innerHeight;
sceneInfo[i].objs.container.style.height = `${sceneInfo[i].scrollHeight}px`;
}
let yOffset = window.pageYOffset;
let totalScrollHeigt = 0;
for(let i =0; i < sceneInfo.length; i++){
totalScrollHeigt += sceneInfo[i].scrollHeight;
if(totalScrollHeigt >= 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 <= partScrollStart){
rv = (currentYOffset - partScrollStart) / partScrollHeight * (values[1] - values[0]) + values[0];
} else if ( currentYOffset < partScrollStart){
rv = value[0];
} else if (currentYoffset > partScrollEnd){
rv= value[1]
; }
} else {
rv = scrollRatio * (values[1] - values[0]) + values[0];
}
return rv;
};
function playAnimation(){
const values = sceneInfo[currentScene].values;
const objs = sceneInfo[currentScene].objs;
const currentYOffset = yOffset - prevScrollHeight;
const scrollHeight = sceneInfo[currentScene].scrollHeight;
const scrollRatio = currentYOffset / scrollHeight;
switch(currentScene) {
case 0 :
const messageA_opacity_in = calcValues(values.messageA_opacity_in, currentYOffset);
const messageA_opacity_out = calcValues(values.messageA_opacity_out, currentYOffset);
const messageA_translateY_in = calcValues(values.messageA_translateY_in, currentYOffset);
const messageA_translateY_out = calcValues(values.messageA_translateY_out, currentYOffset);
if(scrollRatio <= 0.22){
// in
objs.messageA.style.opacity = messageA_opacity_in;
objs.messageA.style.transform = `translateY(${messageA_translateY_in}%)`;
} else {
// out
objs.messageA.style.opacity = messageA_opacity_out;
objs.messageA.style.transform = `translateY(${messageA_translateY_out}%)`;
}
case 1 :
break;
case 2 :
break;
case 3 :
break;
}
};
function scrollLoop(){
prevScrollHeight = 0;
enterNewScene = false;
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){
enterNewScene = true;
if(currentScene===0) return; // 브라우저 바운스 모바일
currentScene--;
document.body.setAttribute('id', `show-scene-${currentScene}`);
}
if(enterNewScene) return;
playAnimation();
}
window.addEventListener('scroll', ()=>{
yOffset = window.pageYOffset;
scrollLoop();
});
window.addEventListener('resize',setLayout);
window.addEventListener('load', setLayout);
setLayout();
})
();