React

React STEP 26 - gsap + react

2025. 3. 4. 14:43
728x90

⭐ Gsap

  • 웹 화면에 쉽게 사용할 수 있는 강력한 타임라인 기반의 애니메이션 자바스크립트 라이브러리입니다.
  • GSAP를 이용해서 멋진 인터랙티브한 웹사이트를 만들 수 있습니다.
  • https://greensock.com/react
  • https://www.npmjs.com/package/gsap
 

gsap

GSAP is a framework-agnostic JavaScript animation library that turns developers into animation superheroes. Build high-performance animations that work in **every** major browser. Animate CSS, SVG, canvas, React, Vue, WebGL, colors, strings, motion paths,.

www.npmjs.com

 

1. gsap install

  • install
npm install gsap
  • import
import gsap from 'gsap';
import ScrollToPlugin from 'gsap/ScrollToPlugin';

gsap.registerPlugin(ScrollToPlugin);

 

2. gsap - step1

  • 기본 구조 및 css 정의
  • gsap1.css
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic);

body, h1, h2, h3, h4, h5, h6, p, ul, ol, table, dl, dd {
	margin: 0;
	padding: 0;
}
h1 {
	font-size: 16px;
}
a {
	text-decoration: none;
	color: #000;
}
ul, ol {
	list-style: none;
}
img {
	max-width: 100%;
	vertical-align: top;
	border: none;
}
body {
	margin: 20px;
	padding: 20px;
	line-height: 1;
	font-family: "Open Sans", sans-serif;
	font-size: 1em;
	background-color: #f1f1f1;
	color: #555;
}
.title {
	margin: 0;
	padding: 0;
	font-size: 1.5em;
	font-weight: 300;
	color: #555;
}
.container {
	margin-top: 50px;
}
.ball {
	position: absolute;
	left: 0;
	top: 200px;
	width: 50px;
	height: 50px;
	background-color: #8ac007;
	border-radius: 25px;
}
  • App.js
import React, { Component, Fragment } from 'react';
import './App.css';
import gsap from 'gsap';
import './css/gsap1.css';

 class App extends Component {
    componentDidMount() {
        let ball = document.getElementsByClassName("ball")[0];

        ball.addEventListener("click", function() {
            gsap.fromTo(ball, {opacity: 0}, {opacity: 1, left: 300, duration: 0.3, delay: 2});
        });
    }

    render() {
        return (
            <Fragment>
                <h1 className='title'>basic :: React Example</h1>
                <div className='container'>
                    <div className='ball'></div>
                </div>
            </Fragment>
        )
    }
 }

 export default App;

 

3. gsap - step2

  • 헤더, 콘텐트, Scroll Page 만들기
  • gsap2.css
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,300,300italic,400italic,600,600italic,700,700italic,800,800italic);

body, h1, h2, h3, h4, h5, h6, p, ul, ol, table, dl, dd {
	margin: 0;
	padding: 0;
}
h1 {
	font-size: 16px;
}
a {
	text-decoration: none;
	color: #2f2f2f;
}
ul, ol {
	list-style: none;
}
img {
	max-width: 100%;
	vertical-align: top;
	border: none;
}
body {
	line-height: 1;
	font-family: "Open Sans", sans-serif;
	font-size: 1em;
}
.top {
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	min-width: 1100px;
	background-color: transparent;
}
.top.fixed {
	position: fixed;
	background-color: rgba(0,0,0,.1);
}
.top .top_inner {
	margin: 0 auto;
	padding: 30px 0;
	width: 1100px;
	height: 100px;
	box-sizing: border-box;
}
.top .logo {
	float: left;
	height: 40px;
}
.top .logo a img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
}
#gnb {
	float: left;
	margin-left: 80px;
}
#gnb li {
	display: inline-block;
}
#gnb li a {
	display: block;
	padding: 0 25px;
	line-height: 40px;
	text-transform: uppercase;
	font-size: 0.875em;
	font-weight: 400;
	color: #000;
}
#gnb li a:hover,
#gnb li.active a {
	color: #e5493a;
}
.content div {
	padding: 120px 40px 40px;
	height: 900px;
	text-transform: uppercase;
	font-size: 2em;
	font-weight: 300;
	color: #ccc;
	border-bottom: 1px solid #eaeaea;
	box-sizing: border-box;
}
  • App.js
import React, { Component, Fragment } from 'react';
import './App.css';
import gsap from 'gsap';
import './css/gsap2.css';
import Logo from './js2/step3/Logo';
import Navigation from './js2/step3/Navigation';
import Content from './js2/step3/Content';

 class App extends Component {
    render() {
        return (
            <div className='container'>
                <div className='top'>
                    <div className="top_inner">
                        <Logo />
                        <Navigation />
                    </div>
                </div>
                <Content />
            </div>
        )
    }
 }

 export default App;
  • Content.js : Content의 영역을 담을 컴포넌트
import React, { Component } from 'react';
import ContentList from './ContentList';

class Content extends React.Component {
    render() {
        return (
            <div className='content'>
                <ContentList id="area1">content1</ContentList>
                <ContentList id="area2">content2</ContentList>
                <ContentList id="area3">content3</ContentList>
                <ContentList id="area4">content4</ContentList>
                <ContentList id="area5">content5</ContentList>
                <ContentList id="area6">content6</ContentList>
                <ContentList id="area7">content7</ContentList>
                <ContentList id="area8">content8</ContentList>
            </div>
        )
    }
}

export default Content;
  • ContentList.js : Content의 공통 사용 컴포넌트
import React, { Component } from 'react';

class ContentList extends React.Component {
    render() {
        return (
            <div id={this.props.id}>{this.props.children}</div>
        );
    }
}

export default ContentList;
  • Logo.js : 헤더의 로고 컴포넌트
import React, { Component } from 'react';

class Logo extends React.Component {
    render() {
        return (
            <h1 className='logo'>
                <a href=''>
                    <img src="/assets/images/logo.png" alt='logo'></img>
                </a>
            </h1>
        )
    }
}

export default Logo;
  • Navigation.js : 실제 Navagation 행위가 이루어질 컴포넌트
import React, { Component } from 'react';
import gsap from 'gsap';
import ScrollToPlugin from 'gsap/ScrollToPlugin';

class Navigation extends Component {
    componentDidMount() {
        gsap.registerPlugin(ScrollToPlugin);

        let n = 0;
        let t = 0;
        let targety = 0;
        let scrollTimer = 0;
        let winHalf;

        let top = document.getElementsByClassName("top")[0];
        let content=document.getElementsByClassName("content")[0];
		let contentLi=content.children;
		let gnb=document.getElementById("gnb");
		let gnbLi=gnb.firstElementChild.children;
		gnbLi[n].classList.add("active");

		let init=() => winHalf=window.innerHeight/2;

		init();
        window.addEventListener("resize", init);

		window.addEventListener("scroll", () => {
			clearTimeout(scrollTimer);

			scrollTimer=setTimeout(() => {
				t=window.scrollY;

				if(t < contentLi[1].offsetTop-winHalf){
					n=0;
				}
				else if(t < contentLi[2].offsetTop-winHalf){
					n=1;
				}
				else if(t < contentLi[3].offsetTop-winHalf){
					n=2;
				}
				else if(t < contentLi[4].offsetTop-winHalf){
					n=3;
				}
				else if(t < contentLi[5].offsetTop-winHalf){
					n=4;
				}
				else if(t < contentLi[6].offsetTop-winHalf){
					n=5;
				}
				else if(t < contentLi[7].offsetTop-winHalf){
					n=6;
				}
				else{
					n=7;
				}

				// console.log("n : "+n);

				for(let i=0; i<gnbLi.length; i++){
					if(i === n){
						gnbLi[i].classList.add("active");
					}
					else{
						gnbLi[i].classList.remove("active");
					}
				}

				if(t > 80){
					if(top.classList.contains("fixed") === false){
						top.classList.add("fixed");
						gsap.fromTo(top, {top: -100}, {top: 0, duration: 0.3, delay: 0.5});
					}
				}
				else{
					if(top.classList.contains("fixed") === true){
						top.classList.remove("fixed");
						top.removeAttribute("style");
					}
				}
			}, 50);
		});

		for(let i=0; i<gnbLi.length; i++){
			gnbLi[i].addEventListener("click", e => {
				e.preventDefault();
				targety=contentLi[i].offsetTop;
				gsap.to(window, {scrollTo: targety, duration: 0.5});
			});
		}		
	}

	render(){
		return(
			<nav id="gnb">
				<ul>
					<li><a href="#area1">HOME</a></li>
					<li><a href="#area2">ABOUT US</a></li>
					<li><a href="#area3">PAGES</a></li>
					<li><a href="#area4">FEATURES</a></li>
					<li><a href="#area5">PORTFOLIO</a></li>
					<li><a href="#area6">BLOG</a></li>
					<li><a href="#area7">SHOP</a></li>
					<li><a href="#area8">CONTACT US</a></li>
				</ul>
			</nav>
		);
	}
}

export default Navigation;
  • 결과

 

 

728x90
저작자표시 비영리 변경금지 (새창열림)

'React' 카테고리의 다른 글

React STEP 27 - jquery + react  (0) 2025.03.04
React STEP 25 - 기본 구조 사용하기  (0) 2025.03.04
React STEP 24 - TODO 리스트 예제  (2) 2025.02.11
React STEP 23 - Create React App - 5  (1) 2025.02.11
React STEP 22 - Create React App - 4  (0) 2025.02.11
'React' 카테고리의 다른 글
  • React STEP 27 - jquery + react
  • React STEP 25 - 기본 구조 사용하기
  • React STEP 24 - TODO 리스트 예제
  • React STEP 23 - Create React App - 5
IT의 큰손
IT의 큰손
IT계의 큰손이 되고 싶은 개린이의 Log 일지
Developer Story HouseIT계의 큰손이 되고 싶은 개린이의 Log 일지
IT의 큰손
Developer Story House
IT의 큰손
전체
오늘
어제
  • 분류 전체보기 (457)
    • 정보처리기사 필기 (18)
    • 정보처리기사 실기 (12)
    • 정보처리기사 통합 QUIZ (12)
    • 빅데이터 (11)
    • 안드로이드 (11)
    • 웹페이지 (108)
    • 자바 (49)
    • SQLD (3)
    • 백준 알고리즘 (76)
    • 데이터베이스 (41)
    • 깃허브 (2)
    • Library (14)
    • Server (31)
    • 크롤링&스크래핑 (3)
    • Spring (23)
    • Vue.js (13)
    • React (27)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Developer Stroy House

인기 글

태그

  • jquery
  • DB
  • 프론트엔드
  • 정보보안전문가
  • 웹개발
  • jsp
  • it
  • css
  • React
  • 웹페이지
  • JavaScript
  • IT자격증
  • DBA
  • 웹개발자
  • 정보처리기사
  • 개발블로그
  • 백엔드
  • 개발자
  • 데이터베이스
  • 알고리즘
  • 앱개발자
  • IT자격증공부
  • ajax
  • 정보처리기사필기
  • 자바
  • html
  • IT개발자
  • java
  • 백준
  • 코딩테스트

최근 댓글

최근 글

Designed By hELLO
IT의 큰손
React STEP 26 - gsap + react
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.