반응형 웹 포트폴리오 코딩

오혜림·2022년 9월 1일
0

1. 체크포인트

1. 애니메이션 이슈

1-1) 라인 애니메이션
1-2) 백그라운드 무한루프 애니메이션
1-3) 백그라운드 canvas 리퀘스트 애니메이션
1-4) 인트로 애니메이션 gsap

1-1. 라인 애니메이션

html

 <section class="sc-visual">
            <div class="txt-area">
                <h2 class="sc-title">
                    <span class="tit-msg">S</span>
                    <span class="tit-msg">t</span>
                    <span class="tit-msg">r</span>
                    <span class="tit-msg">y</span>
                    <span class="tit-msg">d</span>
                    <span class="tit-msg">s</span>
                </h2>
                <div class="line gradient-line6 end">
                    <div class="guage"></div>
                </div>
                <p class="visual-desc">
                    <span class="desc-txt1">We're <span class="gradient-txt1">all</span> in</span>
                    <span class="desc-txt2 pc">Health + Wellness + Accountability.</span>
                    <span class="desc-txt2 mobile">Health / Wellness / Accountability.</span>
                </p>
                <div class="line gradient-line1 start">
                    <div class="guage"></div>
                </div>
                <strong class="gradient-txt2">Mind</strong>
                <div class="line gradient-line2 end">
                    <div class="guage"></div>
                </div>
                <strong class="gradient-txt3">Heart</strong>
                <div class="line gradient-line3 start">
                    <div class="guage"></div>
                </div>
                <strong class="gradient-txt4">Body</strong>
                <div class="line gradient-line4 end">
                    <div class="guage"></div>
                </div>
            </div>
            <figure class="thumb-area"></figure>
        </section>

라인의 위치를 고정시키고 기준점을 주어 애니메이션을 실행하기위해, 게이지에 라인이라는 부모요소를 한번 감싸주었다 => .line > .guage

scss

.line{
    display: flex;
    width: 100%;
    height: 0.2vh;
    margin: 5.5vh 0;
    .guage {
        width: inherit;
        height: inherit;
    }
    &.end{
        justify-content: flex-end;
    }
    &.start{
        justify-content: flex-start;
    }
    &.center{
        justify-content: center;
    }
}

.gradient-line1 {
    &>* {
        @include gradi-Blue1;
    }
}
.gradient-line2 {
    &>* {
        @include gradi-Blue2;
    }
}
.gradient-line3 {
    &>* {
        @include gradi-Pink;
    }
}
.gradient-line4 {
    &>* {
        @include gradi-Yellow;
    }
}
.gradient-line5 {
    &>* {
        @include gradi-Purple;
    }
}
.gradient-line6 {
    &>* {
        @include gradi-Green;
    }
}

.line => 라인의 크기 및 위치
.gradient-lineN > * => 라인의 컬러
.end,.start,.center => 움직이는 라인의 기준점 설정

j-query gsap

textMotion = gsap.timeline({
 scrollTrigger:{
  trigger:'.sc-visual .gradient-txt2',
  start:'top 90%',
  end:'150% -100%',
  scrub:1
 }
})

textMotion.addLabel('a')

.from('.sc-visual .gradient-line6 .guage',{width:"0%",duration:2},'a-=0.1')
.from('.sc-visual .gradient-line1 .guage',{width:"0%",duration:2},'a+=0.3')
.from('.sc-visual .gradient-line2 .guage',{width:"0%",duration:2},'a+=0.5')
.from('.sc-visual .gradient-line3 .guage',{width:"0%",duration:2},'a+=0.7')
.from('.sc-visual .gradient-line4 .guage',{width:"0%",duration:2},'a+=0.9')

gsap.from을 활용하여 width값을 0 -> 100% 설정해주면 게이지가 차오르는 애니메이션 효과를 줄 수 있다. css에서 라인의 기준점을 주었기때문에, .start는 왼쪽에서 오른쪽으로, end는 오른쪽에서 왼쪽으로, .center는 가운데의 기준점이 되어 애니메이션이 실행된다.

1-2. 백그라운드 무한루프 애니메이션

html

백그라운드를 코딩하고, 똑같은 백그라운드 코드를 복제한 뒤, 부모요소로 묶어 백그라운드 위치를 고정 및 백그라운드 배치를 한 후, 키프레임 애니메이션과 translateX를 활용하여 무한 루프 애니메이션을 구현한다.

scss

 .send-bg-wrap{
        position: absolute;
        top: 0;
        left: 0;
        // 배경이니까 absolute
        z-index: -1;
        display: flex;
        width: 100%;
        height: 100vh;
        animation: rolling 20s infinite linear;
    }
    .send-bg {
        position: relative;
        display: flex;
        flex: 1 0 100%;
        & > * {
            flex: 1;
        }
        .ic-img {
            flex-basis: 50%;
        }
        &::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            z-index: 3;
            display: inline-block;
            width: 100%;
            height: 100%;
            background-color: rgba(0,0,0,.89);
        }
    }
    
    // 백그라운드 css
    
    @keyframes rolling {
    0% {
        transform: translateX(0%);
     }
    100% {
        transform: translateX(-100%);
     }
    }
    
    // 백그라운드 애니메이션

1-3. 백그라운드 canvas 리퀘스트 애니메이션

스크롤 시, 마치 동영상처럼 움직이는 이미지를 구현하기 위해서 html canvas태그를 사용하고, 스크립트로 움직임을 구현해야한다.

const canvas = document.getElementById('canvas');
            const ctx = canvas.getContext('2d'); // 2d이미지
            canvas.width = 575;
            canvas.height = 696; // 캔버스크기
            const frameCount = 45; // 프레임카운트 45장
            const currentFrame = (idx) => {
                return `https://www.apple.com/105/media/us/airpods-max/2020/996b980b-3131-44f1-af6c-fe72f9b3bfb5/anim/turn/large_2x/large_2x_${idx.toString().padStart(4, '0')}.jpg`; // 자릿수치환 0001~
            }; // 리턴 필수

            const images = [];
            const card = {
                frame: 0,
            };
            for (let i = 0; i < frameCount; i++) {
                const img = new Image();
                img.src = currentFrame(i + 1);
                images.push(img);
            } // 반복문 통해서 프레임 수 증가
            gsap.to(card, {
                frame: frameCount - 1,
                snap: 'frame',
                ease: 'none',
                scrollTrigger: {
                    trigger: '.sc-together',
                    scrub: 1,
                    start: 'top top',
                    end: 'bottom bottom', //+=500% 내 영역이 5배만큼 가상스크롤
                    //markers:true,
                    // pin:true -> 고정 
                    // 리퀘스트 애니메이션
                },
                onUpdate: render,
            });
            images[0].onload = render;
            function render() {
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                ctx.drawImage(images[card.frame], 0, 0 ,575,696);
            }

1-4. 인트로 애니메이션 gsap

const introAni2 = gsap.timeline({
   paused:true
 })
introAni2.addLabel('a')
.from('.sc-visual .sc-title .tit-msg',{opacity:0, yPercent:103, stagger:0.2,duration:0.6},'a')
.from('.sc-visual .thumb-area',{top:"-70%",duration:1},'a') // top컨트롤
.from('.header',{opacity:0,duration:1.2},'a')


gsap.set('.loading .guage',{width:"100%"})
const introAni = gsap.timeline({
    onComplete:function(){
      introAni2.play();
    }
})
introAni.addLabel('a')
.to('.loading .guage', {width:0,delay:1},'a')
.to('.loading',{opacity:0,delay:1.5,duration:1,display:'none'},'a')

introAni -> introAni2 순서로 인트로 애니메이션을 구현할 때,
introAni2를 먼저 선언하고, paused:true를 통해 멈춤상태로 유지하다가
introAni를 선언하고 introAni의 애니메이션이 끝나면 introAni2를 실행하기 위해 play()를 사용한다.

profile
퍼블리싱 코딩기록

0개의 댓글