릴리바이레드 사이트 리뉴얼 클론코딩

하늘·2022년 8월 12일
2

클론코딩

목록 보기
2/5
post-thumbnail

레퍼런스 사이트를 기반으로 릴리바이레드 사이트를 새롭게 리뉴얼 코딩 했습니다!

📎 릴리바이레드 둘러보기

📎 https://eveneul.github.io/iliybyred/
📎 https://github.com/eveneul/iliybyred

반응형이 아닌 적응형으로 만들었으며
제이쿼리, GSAP, box2d와 같은 스크립트를 이용해 홈페이지에 동적인 움직임을 부여했습니다.

🔍 구조 살펴보기

헤더 부분에는 로고, 검색 버튼, 더 보기 메뉴가 있으며
콘텐츠가 있는 부분은 main 태그의 container 클래스로,
그리고 footer는 따로 footer라고 지정해 준 다음 이 세 개의 태그를
wrapper라는 div 태그에 넣어 줬습니다

<div class="wrapper">
	<header class="header"></header>
	<main class="container"></main>
	<footer class="footer"></footer>
</div>

그리고 main에 섹션마다 div를 만들었습니다
특히 product 부분에는 배경의 색상이 바뀌기 때문에
배경의 크기 계산을 쉽게 하기 위해 첫 번째 섹션과 두 번째 섹션을 같이 묶은 다음, 형제 요소로 배경 요소를 넣었습니다.

<div class="bg-wrapper">
  <div class="bg"></div>
  <div class="sc-visual"></div>
  <div class="sc-product"></div>
</div>

<div class="sc-story"></div>
<div class="sc-video"></div>

⭐️ sc-visual

스크롤을 하면 왼쪽에 있는 스와이퍼 부분은 아래에 고정되어 있고,
오른쪽에 있는 이벤트 목록들은 스크롤되는 것이 보입니다

크게 왼쪽과 오른쪽으로 나뉘어져 있어 section 안에 visual-left와 visual-right로 나누어 작업했습니다

🔥 visual-left

swiper.js를 사용해서

  1. 오토 슬라이드가 되고,
  2. progress bar가 있고,
  3. prev, next 버튼이 작동되고,
  4. 현재 페이지 수와 전체 페이지 수를 표시해 주는

스크립트를 작성했습니다.

swiper 홈페이지에서 Demo 형식으로 스크립트 예시가 너무 잘되어 있어
복붙(...) 수준밖에 되지 않았지만 특히 progress bar 부분에서는 데모가 없어서 스스로 작성을 했어야 했습니다.

	var swiper = new Swiper('.visual-left .swiper', {
		effect: 'fade',
		spaceBetween: 0,
		centeredSlides: true,
		autoplay: {
			delay: 5000,
			disableOnInteraction: false,
		},
		speed: 1000,
		pagination: {
			el: '.count',
			type: 'fraction',
		},
		navigation: {
			nextEl: '.btn-set.next',
			prevEl: '.btn-set.prev',
		},
		loop: true,
		on: {
			init: function () {
				$('.swiper-progress-bar').removeClass('animate');
				$('.swiper-progress-bar').removeClass('active');
				$('.swiper-progress-bar').addClass('animate');
				$('.swiper-progress-bar').addClass('active');
			},
			slideChangeTransitionStart: function () {
				$('.swiper-progress-bar').removeClass('animate');
				$('.swiper-progress-bar').removeClass('active');
				$('.swiper-progress-bar').addClass('active');
			},
			slideChangeTransitionEnd: function () {
				$('.swiper-progress-bar').addClass('animate');
			},
		},
	});

progress bar부분은 on에서부터 시작되는데,
init으로 기초 설정을 해 주고, 슬라이드가 변경되면 (버튼이나 드래그로 현재 표시되는 슬라이드가 변경되면) slideChangeTransitionStart로 클래스를 지워 주고 반대의 경우에도 클래스를 넣었다 뺐다 하는 형식으로 작성했습니다.

처음에는 css keyframe으로 처리할까 했는데 슬라이드가 바뀌면 제대로 작동되지 않기 때문에 스크립트로 해결을 봤습니다.

또한 영역을 벗어날 동안 스크롤해도 스와이퍼가 밑 부분에 찰싹 붙는 방법은 css position: sticky를 사용했습니다!

🔥 rolling text

5초에 한 번씩 롤링되는 텍스트입니다

일단 Y는 고정이 되어 있기 때문에 SASSY! 라는 텍스트에 SASS는 투명 처리를 해 주고,
롤링되는 LILLY와 SASSY에서는 Y만 투명하게 적용해서 LILL, SASS만 아래에서 내려오게 만들어 줬습니다

<p><span class="transparent">SASS</span>Y!</p>
<div class="rolling-text">
  <p class="lilly">LILL<span class="transparent">Y!</span></p>
  <p class="sassy">SASS<span class="transparent">Y!</span></p>

스크립트는 GSAP 플러그인의 도움을 받아 작성했습니다

	gsap.set('.rolling-text p', {
		yPercent: -100,
	});

	gsap.set('.lilly', {
		yPercent: 0,
	});

	const rollingText = gsap
		.timeline({
			defaults: {
				ease: 'none',
				delay: 3,
			},
		})
		.addLabel('m1')
		.to('.rolling-text .sassy', { yPercent: 0 }, 'm1')
		.to('.rolling-text .lilly', { yPercent: 100 }, 'm1')
		.set('.rolling-text .lilly', { yPercent: -100 })
		.addLabel('m2')
		.to('.rolling-text .lilly', { yPercent: 0 }, 'm2')
		.to('.rolling-text .sassy', { yPercent: 100 }, 'm2')
		.set('.rolling-text .sassy', { yPercent: -100 });
	rollingText.repeat(-1);

LILLY라는 글자가 내려오면 SASSY는 위로 위치해서 다음 롤링을 기다리고, SASSY가 내려오면 같이 내려간 LILLY는 바로 SASSY의 위에 올라가서 다음 롤링을 기다리는 식으로 gsap 타임라인을 통해 작성했습니다.

⭐️ sc-product

오른쪽에서 왼쪽으로 무한대로 흐르는 텍스트가 있고, 스크롤할수록 배경색도 바뀝니다

🔥 rolling text

          <div class="rolling-area">
            <div class="text">
              <span>lily! cheeky! sassy! </span>
              <span>lily! cheeky! sassy! </span>
            </div>
            <div class="text">
              <span>lily! cheeky! sassy! </span>
              <span>lily! cheeky! sassy! </span>
            </div>
          </div>

rolling-area와 text 클래스를 display: flex 속성으로 4 개의 span들이 가로로 정렬되게 만들었습니다

그리고 첫 번째 섹션과 달리 이번에는 css keyframes를 이용했습니다

	@keyframes rollingText {
		0% {
			transform: translateX(0%);
		}

		100% {
			transform: translateX(-100%);
		}
	}

	.rolling-area {
		display: flex;
		text-transform: uppercase;

		.text {
			display: flex;
			font-size: 187px;
			font-family: $font-en;
			// color: #000;
			color: $pink;
			font-weight: 700;
			line-height: 1;
			z-index: 99;
			animation: rollingText 27s linear infinite;

			span {
				display: block;
				margin-right: 55px;
			}
		}
	}

첫 번째 text 클래스가 왼쪽으로 모두 이동하면 키프레임의 0%로 이동해서 마치 무한대로 롤링되어 보이는 눈속임(?)을 이용한 것입니다

🔥 scroll 될 때 서서히 바뀌는 background-color

sc-visual과 sc-product, bg를 감싸고 있는 div에 position: relative를 주었고, 실제 바뀌는 bg라는 클래스는 position: absolute, top: 0, left: 0, bottom: 0, right: 0을 주어서 두 개의 섹션을 모두 차지하도록 두었습니다.

원래는 스크립트로 두 개의 섹션의 높이값을 계산하고 그 높이값을 bg의 height값으로 넣으려고 했으나 브라우저의 세로 크기가 바뀌면 오류가 생기는 점을 확인해서 html와 css로 제어하는 방식을 택했습니다.

	gsap.to('.bg', {
		autoAlpha: 1,
		ease: 'power1.in',
		scrollTrigger: {
			trigger: '.sc-visual',
			start: 'bottom center',
			end: 'bottom 100px',
			scrub: 1,
		},
	});

일단 css로 opacity값을 0으로 주고 sc-visual이 끝나는 점과 세로 스크롤바의 중앙이 만나면 autoAlpha로 opacity를 1로 바뀌게끔 설정했습니다

⭐️ sc-story

스크롤해 섹션에 도착했을 시 동그란 아티클들이 생겨나고 마우스를 움직이면 살짝씩 움직입니다

        <div class="bubble-area">
          <i class="bubble bubble-01" data-speed="-9"></i>
          <i class="bubble bubble-02" data-speed="-3"></i>
          <i class="bubble bubble-03" data-speed="5"></i>
          <i class="bubble bubble-04" data-speed="-7"></i>
          <i class="bubble bubble-05" data-speed="-5"></i>
          <i class="bubble bubble-06" data-speed="2"></i>
        </div>

각 아티클을 bubble이라는 클래스와, 위치값을 정하기 위해 숫자를 달아 각각의 클래스로 작성했습니다.

그리고 속도를 제어하기 위해 data-speed로 설정했습니다.

	const bubble = gsap.from('.sc-story .bubble', {
		scale: 0,
		opacity: 0,
		paused: true,
		stagger: 0.1,
	});

	ScrollTrigger.create({
		trigger: '.sc-story',
		start: 'top 40%',
		end: 'bottom top',
		onEnter: () => {
			bubble.play();
		},
	});

stagger로 한꺼번에 커지는 것이 아닌 따로따로 커지게 설정했습니다

onEnter로 해당 섹션에 도착했을 시 bubble이라는 함수가 실행되게 작성했습니다

⭐️ sc-video

https://mrdoob.com/projects/chromeexperiments/ball-pool/

사이트를 참고하고 스크립트를 수정해서 릴리바이레드 이미지와 잘 맞게 픽셀 하트 아이콘으로 변경했습니다

if (canvasList.length <= 20) {
			createBall(mouse.x, mouse.y);
		}

클릭하면 하트가 뿜어져서 나오는데, 최대 생성 개수는 20개로 설정했습니다

function startAni() {
	init();
	play();
}

gsap.to('.sc-video', {
	scrollTrigger: {
		trigger: '.sc-video',
		start: 'top center',
		end: 'bottom 100px',
		onEnter: startAni,
	},
});

그리고 init(), play() 함수를 실행시키면 첫 번째 섹션에서 실행이 되기 때문에 gsap의 onEnter로 해당 섹션에서 실행 함수가 작동되도록 했습니다

워낙 코드 길이도 길고 js 파일이 세 개나 되어서 어디에서 어떻게 손을 봐야 할지 막막했는데 사용하지 않을 함수를 하나하나 지우다 보니까 어느 정도 컨트롤이 가능해서 구현할 수 있었던 것 같습니다

⭐️ cursor

html에 cursor라는 클래스를 지정해 주어서 css로 모양을 잡아 줬습니다

  <div class="cursor"></div>
.cursor {
	display: flex;
	justify-content: center;
	align-items: center;
	position: fixed;
	top: 0;
	left: 0;
	width: 0;
	height: 0;
	z-index: 9999;
	pointer-events: none;
	mix-blend-mode: difference;
	background-color: $pink;
	border-radius: 50%;
	text-transform: uppercase;
	font-family: $font-en;
	font-weight: 700;
	font-size: 14px;
	color: #000;
}

이미지나 콘텐츠에 커서가 올라갔을 시 색상 반전이 되는 것이 포인트인데 mix-blend-mode: difference로 간편하게 적용할 수 있었습니다

	const w = 124;
	const h = 124;

	$(window).mousemove(function (e) {
		const xVal = e.clientX;
		const yVal = e.clientY;

		gsap.to('.cursor', {
			x: xVal,
			y: yVal,
		});
	});

	$('a').mousemove(function (e) {
		gsap.to('.cursor', {
			width: w,
			height: h,
			xPercent: -50,
			yPercent: -50,
		});

		if ($(e.target).parents('.visual-left').length) {
			$('.cursor').html('<span>discover</span>');
		} else if ($(e.target).parents('.visual-right').length) {
			$('.cursor').html('<span>event</span>');
		} else if ($(e.target).parents('.sc-product').length) {
			$('.cursor').html('<span>click</span>');
		} else if ($(e.target).parents('.sc-story').length) {
			$('.cursor').html('<span>story</span>');
		} else if ($(e.target).parents('.sc-video').length) {
			$('.cursor').html('<span>view</span>');
		} else {
			$('.cursor').html('');
		}
	});

	$('a').mouseout(function (e) {
		gsap.to('.cursor', {
			width: 0,
			height: 0,
		});
	});

a 태그에 올라갔을 시에만 크기가 0에서 124로 변하게 두었고
조건문을 사용해서 섹션마다 마우스 중앙에 나타나는 글자를 다르게 설정해 두었습니다

0개의 댓글