새로고침 시에 페이지의 상단으로 자동이동되어 페이지의 이벤트를 다시 구현하도록 한다.
이전 포트폴리오에서 사용했던 방법보다 더 간단하고 용이한 방법을 찾아 수정하였다!
window.onload = function(){
setTimeout(function(){
scrollTo(0,0)
},100);
}
history.scrollRestoration = "manual"
더욱 짧고 작동 상에도 더 부드러워진 코드!
동일한 이벤트가 적용되는 요소를, 구역별로 하나하나 지정해서 이벤트를 넣는 것보다, each
반복문을 사용하여 하나로 묶어 돌리는게 더욱 깔끔하고 효과적이다!
//sc-clients의 라인
gsap.set('.sc-clients .line, .sc-service .line', { width: 0 });
gsap.to('.sc-clients .line',3,{
scrollTrigger:{
trigger:'.sc-clients .text-group',
start:"0% 80%",
end:"100% 0%",
// markers:true,
},
width:'100%',
ease: "power4.out",
})
//sc-service의 라인
gsap.to('.sc-service .line',3,{
scrollTrigger:{
trigger:'.sc-service .text-group',
start:"0% 80%",
end:"100% 0%",
// markers:true,
},
width:'100%',
ease: "power4.out",
})
각각의 라인을 따로따로 불러서 이벤트를 지정했지만,
1️⃣
gsap.set('.sc-clients .line, .sc-service .line', { width: 0 });
$('.line').2️⃣each(function(3️⃣ i, el){
gsap.to(3️⃣ el,3,{
scrollTrigger:{
trigger:el,
start:"0% 80%",
end:"100% 0%",
},
width:'100%',
ease: "power4.out",
})
})
gsap.set으로 두 라인 클래스를 같이 묶어준 후 width값 셋팅
.line을 each문으로 각각 반복문을 돌려준다.
매개변수 정의
i: 인덱스(index) 매개변수로서, 현재 요소가 반복문 내에서 몇 번째 요소인지를 나타냅니다. 인덱스는 0부터 시작하며, 첫 번째 요소의 인덱스는 0이 됩니다.
el: 요소(element) 매개변수로서, 현재 반복되는 요소 자체를 나타내며 $(this)
와 같은 의미기도 하다. 이 경우에는 클래스가 "line"인 요소 중 하나가 됩니다.
<!--html-->
<ul class="list">
<li class="item">
<a href="" ✅data-up="">
<figure class="img-wrap" >
<img src="https://www.datocms-assets.com/84325/1682701161-hearthstone_barrens_01.jpg?auto=format&dpr=1.5&fit=crop&fm=jpg&h=953&q=70&w=1395" alt="">
</figure>
<p class="title">Hearthstone Cinematic: Forged in the Barrens</p>
<span class="subtitle">Blizzard Entertainment</span>
</a>
</li>
<li class="item">
<a href="" ✅data-up="">
<figure class="img-wrap" >
<img src="https://www.datocms-assets.com/84325/1675720505-hearthstone_sc_shot04_a_final.jpg?auto=format&dpr=2&fit=crop&fm=jpg&h=953&q=70&w=1395" alt="">
</figure>
<p class="title">Hearthstone Cinematic: Voyage to the Sunken City</p>
<span class="subtitle">Blizzard Entertainment</span>
</a>
</li>
/~~중략~~/
위치값을 받아서 아래에서 위로 올라오는 슬라이드 효과가 들어가야 하는 태그들에게 동일한 데이터 값인 data-up
을 넣어준다. 따로 ""에 값은 넣어주지 않아도 되며,
필요시에 따로 넣어주면 된다!
<!--js-->
gsap.set('1️⃣[data-up]',{
opacity:0,
yPercent:100,
})
$('[data-up]').3️⃣each(function(i,el){
gsap.to($(this),{
scrollTrigger:{
trigger:el,
start:"0% 100%",
end:"100% 0%",
// markers:true,
},
2️⃣opacity:1,
yPercent:0,
})
})
gsap.set으로 속성값인 data-up
요소들을 불러준다.
( 여기서 속성값은 [ ]
를 사용해서 불러줄 수 있다!)
gsap.to()의 변해줄 값을 설정해준다.
셋팅해 준 data-up을 each 반목문을 통하여 data-up을 돌려준다.
<!--html-->
<li class="item">
<a href="" ✅data-up="-50% 100%">
<figure class="img-wrap" >
<img src="https://www.datocms-assets.com/84325/1682701161-hearthstone_barrens_01.jpg?auto=format&dpr=1.5&fit=crop&fm=jpg&h=953&q=70&w=1395" alt="">
</figure>
<p class="title">Hearthstone Cinematic: Forged in the Barrens</p>
<span class="subtitle">Blizzard Entertainment</span>
</a>
</li>
이때는 다른 속성값을 줘야하는 태그의 data-up에 임의의 값을 넣어준다!
<!--js-->
gsap.set('[data-up]',{
opacity:0,
yPercent:100,
})
$('[data-up]').each(function(i,el){
1️⃣start = $(this).data('up');
2️⃣startVal =✨ (start)?start:"0% 80%"; ✨
gsap.to($(this),{
scrollTrigger:{
trigger:el,
start:3️⃣startVal,
end:"100% 0%",
// markers:true,
},
opacity:1,
yPercent:0,
})
})
start라는 변수에 $(this), 즉 data-up을 가진 속성 중 내가 선택한 것!, 이것의 data-up을 넣어준다.
startVal라는 변수에 삼항연산자를 사용하여 조건문을 넣어준다.
```
if(start){ //start가 맞다면~
start(); //start인 $(this).data('up')가 그대로 실행되고
} else { //start가 아니라면
"0% 80" // "0% 80%"가 입력되도록 한다~
}
```
위와 같은 if문과 동일한 문장이다.
startVal = (start) ? start : "0% 80%" ;
만약 start 변수가 존재한다면 (start 변수가 truthy한 경우),
startVal 변수에 start 변수의 값을 할당합니다.
그렇지 않은 경우에는 (start 변수가 falsy한 경우), startVal 변수에 "0% 80%" 값을 할당합니다.
scrollTrigger의 start옵션에 이 조건문이 담긴 startVal를 넣어주어 상황별로 조건 값이 입력된다.
아래와 같이 스크롤트리거를 사용, 어느 위치에 도달했을 때
양옆의 배경의 크기가 커져 커튼효과를 내도록 하였다.
1️⃣
gsap.set('.sc-commu .sidebg .leftbg', {width:'20vw'});
gsap.set('.sc-commu .sidebg .rightbg', {width:'20vw'});
✨sideBgTl = gsap.2️⃣timeline({
scrollTrigger:{
trigger:'.sc-commu',
start:"0% 90%",
end:"50% 80%",
scrub:0,
},
})
sideBgTl
4️⃣.addLabel('a')
3️⃣
.to('.sc-commu .sidebg .leftbg',{ width:'0vw', },5️⃣' a')
.to('.sc-commu .sidebg .rightbg',{ width:'0vw', },5️⃣ 'a')
❗❗ 주의 ❗❗
timeline 속성을 이용할 때는 꼭 변수를 할당해줘야 한다!!
gsap.set()으로 기본값을 설정
timeline을 사용한 스크롤트리거를 sideBgTl 변수에 할당.
gsap.to()로 이동 후 값 설정
.addLabel()을 사용, 값에 'a'를 넣어주어 라벨을 만들어 준다.
같이 묶어줄 .to()의 값에 만들어준 'a'라는 라벨을 달아주어 같은 제품으로 묶어준다.
그렇다면 타임라인이지만 각기 움직이지않고 동시에 움직이게 된다.
해당 국가의 시간을 나타나도록 하였고 am/pm으로 간편히 확인할 수 있도록 하였다.
// console.log('KST (한국 표준시):<br />', getWorldTime(+9), '<br /><br />');
// console.log('PST (태평양 표준시):<br />', getWorldTime(-8), '<br /><br />');
// console.log('PDT (태평양 표준시 DST):<br />', getWorldTime(-7), '<br /><br />');
// console.log('EST (뉴욕 시간):<br />', getWorldTime(-5), '<br /><br />');
// console.log('EST (LA 시간):<br />', getWorldTime(-7), '<br /><br />');
// console.log('EST (브라질 시간):<br />', getWorldTime(+9), '<br /><br />');
// console.log('EDT (뉴욕 시간 DST):<br />', getWorldTime(-4), '<br /><br />');
// console.log('CET (파리 시간):<br />', getWorldTime(+1), '<br /><br />');
// console.log('CEST (파리 시간 DST):<br />', getWorldTime(+2), '<br /><br />');
// console.log('CST (중국 표준시):<br />', getWorldTime(+8), '<br /><br />');
// console.log('UTC (세계 표준시):<br />', getWorldTime(0), '<br /><br />');
1️⃣
getWorldTime(-7,'.us-time')
getWorldTime(+9,'.br-time')
getWorldTime(+1,'.uk-time')
getWorldTime(+8,'.ch-time')
function getWorldTime(tzOffset, frame) { // 24시간제
var now = new Date();
var tz = now.getTime() + (now.getTimezoneOffset() * 60000) + (tzOffset * 3600000);
now.setTime(tz);
2️⃣
var hours = now.getHours();
var ampm = hours >= 12 ? 'PM' : 'AM';
hours = hours % 12;
hours = hours ? hours : 12; // 0시일 경우 12로 변경
var s =
leadingZeros(hours, 2) + ':' +
leadingZeros(now.getMinutes(), 2) + ' ' + ampm;
$(frame).html(s);
}
function leadingZeros(n, digits) {
var zero = '';
n = n.toString();
if (n.length < digits) {
for (i = 0; i < digits - n.length; i++)
zero += '0';
}
return zero + n;
}
/**
* 1초마다 업데이트
*/
3️⃣
setInterval(function() {
getWorldTime(tzOffset, frameSelector); // tzOffset과 frameSelector는 필요한 값으로 대체해야 합니다.
}, 1000);
각 나라별로 다른 클래스를 주어 시간차이를 주도록 함수에 기입
12를 기준으로 하여 am/pm 표현 하도록 설정
setInterval로 1초마다 업데이트가 되어 시간이 흘러가는걸 체크하도록 설정
각 국의 시간이 조금 맞지않아 시차를 수정하였고, 작업 도중 시간이 업데이트가 되지 않는 점을 확인해 다시금 수정하였습니다.
function getWorldTime(tzOffset, frame) {
var now = new Date();
var tz = now.getTime() + (now.getTimezoneOffset() * 60000) + (tzOffset * 3600000);
now.setTime(tz);
var hours = now.getHours();
var ampm = hours >= 12 ? 'pm' : 'am';
hours = hours % 12;
hours = hours ? hours : 12;
var s =
leadingZeros(hours, 2) + ':' +
leadingZeros(now.getMinutes(), 2) + ' ' + ampm;
$(frame).html(s);
}
function leadingZeros(n, digits) {
var zero = '';
n = n.toString();
if (n.length < digits) {
for (var i = 0; i < digits - n.length; i++)
zero += '0';
}
return zero + n;
}
/**
* 1초마다 업데이트
*/
setInterval(function () {
var tzOffset = arguments[0]; // 필요한 값을 대체
var frameSelector = arguments[1]; // 필요한 값을 대체
var frameElement = document.querySelector(frameSelector);
getWorldTime(tzOffset, frameElement);
}.bind(null, -8, '.us-time'), 1000);
setInterval(function () {
var tzOffset = arguments[0]; // 필요한 값을 대체
var frameSelector = arguments[1]; // 필요한 값을 대체
var frameElement = document.querySelector(frameSelector);
getWorldTime(tzOffset, frameElement);
}.bind(null, -3, '.br-time'), 1000);
setInterval(function () {
var tzOffset = arguments[0]; // 필요한 값을 대체
var frameSelector = arguments[1]; // 필요한 값을 대체
var frameElement = document.querySelector(frameSelector);
getWorldTime(tzOffset, frameElement);
}.bind(null, 0, '.uk-time'), 1000);
setInterval(function () {
var tzOffset = arguments[0]; // 필요한 값을 대체
var frameSelector = arguments[1]; // 필요한 값을 대체
var frameElement = document.querySelector(frameSelector);
getWorldTime(tzOffset, frameElement);
}.bind(null, 8, '.ch-time'), 1000);