Codrops 원본

4 Exclusive Demos: Slideshows & Typographic Animations

텍스트 · MIT

텍스트 더 보기
ORIGINAL PREVIEW
4 Exclusive Demos: Slideshows & Typographic Animations 정적 미리보기

갤러리 안에서는 화면을 벗어나거나 움직임을 멈추면 예제도 닫힙니다. 다시 재생할 때는 처음부터 시작해요.

큰 화면으로 보기 새 탭

SOURCE FILES

원본 코드 읽기

37개 파일

수집한 원본 소스와 실행 안내를 함께 제공합니다.

OnScrollTypoAnimations/css/base.css
파일 저장

*,
*::after,
*::before {
	box-sizing: border-box;
}

:root {
	font-size: 18px;
	--color-text: #99928a;
	--color-bg: #181817;
	--color-link: #aa7f2d;
	--color-link-hover: #fff;
	--page-padding: 1rem;
}

body {
	margin: 0;
	color: var(--color-text);
	background-color: var(--color-bg);
	font-family: area-normal,-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	overflow-x: hidden;
	background-image: url(../img/bg1.jpg);
	background-size: cover;
	background-attachment: fixed;
	background-repeat: no-repeat;
	background-position: 50% 50%;
}

.demo-2 {
	--color-text: #ecdfeb;
	--color-bg: #704f6d;
	--color-link: #fff;
	--color-link-hover: #ecdfeb;
	font-family: "norman-variable", sans-serif;
	font-variation-settings: "wght" 400;
	background-image: url(../img/bg2.jpg);
}

.demo-3 {
	--color-text: #3a3330;
	--color-bg: #a59d9a;
	--color-link: #0f0a09;
	--color-link-hover: #3a3330;
	font-family: "marlide-display-variable", sans-serif;
	font-variation-settings: "wght" 340;
	background-image: url(../img/bg3.jpg);	
}

.demo-4 {
	--color-text: #fff;
	--color-bg: #000;
	--color-link: #c88768;
	--color-link-hover: #fff;
	font-family: "kudryashev-d-excontrast", sans-serif;
	font-weight: 300;
	background-image: url(../img/bg4.jpg);	
}

/* Page Loader */
.js .loading::before,
.js .loading::after {
	content: '';
	position: fixed;
	z-index: 1000;
}

.js .loading::before {
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: var(--color-bg);
}

.js .loading::after {
	top: 50%;
	left: 50%;
	width: 60px;
	height: 60px;
	margin: -30px 0 0 -30px;
	border-radius: 50%;
	opacity: 0.4;
	background: var(--color-link);
	animation: loaderAnim 0.7s linear infinite alternate forwards;

}

@keyframes loaderAnim {
	to {
		opacity: 1;
		transform: scale3d(0.5,0.5,1);
	}
}

a {
	text-decoration: none;
	color: var(--color-link);
	outline: none;
	cursor: pointer;
}

a:hover {
	color: var(--color-link-hover);
	outline: none;
}

/* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
a:focus {
	/* Provide a fallback style for browsers
	 that don't support :focus-visible */
	outline: none;
	background: lightgrey;
}

a:focus:not(:focus-visible) {
	/* Remove the focus indicator on mouse-focus for browsers
	 that do support :focus-visible */
	background: transparent;
}

a:focus-visible {
	/* Draw a very noticeable focus style for
	 keyboard-focus on browsers that do support
	 :focus-visible */
	outline: 2px solid red;
	background: transparent;
}

.unbutton {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	cursor: pointer;
}

.unbutton:focus {
	outline: none;
}

main {
	counter-reset: section;
}

.splitting .word {
	white-space: nowrap;
}

.frame {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	color: var(--color-title);
	padding: var(--page-padding);
	font-size: 13px;
	font-weight: 400;
	background: linear-gradient(to bottom, var(--color-bg), transparent);
	display: grid;
	grid-template-columns: 100%;
	grid-template-areas: 'title' 'demos' 'credits' 'sponsor';
	justify-content: start;
	align-content: space-between;
	align-items: start;
	z-index: 100;
	pointer-events: none;
	grid-gap: 0.5rem;
	font-style: normal;
	font-family: area-normal,-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
}

.frame a {
	pointer-events: auto;
}

.frame a:not(.frame__demo) {
	white-space: nowrap;
	overflow: hidden;
	position: relative;
}

.frame a:not(.frame__demo)::before {
	content: '';
	height: 1px;
	width: 100%;
	background: currentColor;
	position: absolute;
	top: 90%;
	transition: transform 0.3s;
	transform-origin: 0% 50%;
}

.frame a:not(.frame__demo):hover::before {
	transform: scaleX(0);
	transform-origin: 100% 50%;
}

.frame__title {
	grid-area: title;
	display: flex;
	align-items: flex-end;
}

.frame strong {
	font-weight: 800;
}

.frame__title-main {
	font-size: inherit;
	margin: 0;
	font-weight: inherit;
}

.frame__demos {
	grid-area: demos;
	display: grid;
	grid-auto-flow: column;
	justify-content: start;
	gap: 1rem;
}

.frame__demo {
	padding: 0.25rem 0.5rem 0.45rem;
	line-height: 1;
	text-align: center;
	min-width: 1.55rem;
}

.frame__demo--current {
	font-weight: bold;
	border: 1px solid;
	border-radius: 50%;
	color: var(--color-link-hover);
}

.frame__credits {
	grid-area: credits;
	display: flex;
	gap: 1rem;
}

.intro {
	height: 100vh;
    display: grid;
    grid-template-rows: 1fr auto;
    align-content: space-around;
	padding: var(--page-padding);
}

.intro__title {
	font-size: clamp(2rem,7vw,5rem);
	line-height: 1;
	margin: auto 0;
	position: relative;
}

.intro__title--medium {
	font-size: clamp(2rem,9vw,6rem);
}

.intro__title--big {
	font-size: clamp(2rem,11vw,8rem);
}

.text-gradient {
	background: linear-gradient(33deg, #4f361685 0%,rgb(231 217 185 / 68%) 100%);
    background-size: cover;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    text-fill-color: transparent;
}

.text-centered {
	text-align: center;
}

.text-right {
	text-align: right;
}

.centered {
	margin-right: auto;
	margin-left: auto;
}

.intro__info {
	position: relative;
	max-width: 250px;
	opacity: 0.6;
	line-height: 1.2;
	margin-bottom: 1rem;
	padding: 1rem;
	align-self: end;
}

.intro__info::after {
	content: '';
	position: absolute;
	left: 0%;
	width: 1px;
	height: 200vh;
	background: linear-gradient(to bottom,var(--color-text),transparent);
	top: 0;
}

.intro__info.centered::after {
	height: 4rem;
	left: 50%;
	top: 100%;
}

.broad.intro__info::after {
	width: 3px;
	left: calc(50% - 3px);
} 

.larger {
	font-size: 1.5rem;
}

.content {
	width: 100vw;
	position: relative;
	padding: var(--page-padding);
	padding-top: 50vh;
}

.content--left {
	padding-left: 3rem;
}

.upper {
	text-transform: uppercase;
}

.content__title {
	font-size: clamp(1.5rem,3.5vw,4rem);
	line-height: 1.2;
	max-width: 1000px;
}

.narrow {
	max-width: 800px;
}

.w400 {
	font-weight: 400;
}

.w600 {
	font-weight: 600;
}

.content__title--smaller {
	font-size: clamp(1rem,2.75vw,3rem);
}

.content__text {
	max-width: 600px;
	margin: 0;
}

.content__text--small {
	font-weight: 600;
	font-size: 13px;
}

.heart::before {
	content: '❤';
	position: absolute;
	width: 100%;
	left: 0;
	top: 130%;
	text-align: center;
	font-size: 65vh;
	-webkit-text-stroke: 1px var(--color-text);
    text-stroke: 1px var(--color-text);
    opacity: 0.5;
    -webkit-text-fill-color: transparent;
    text-fill-color: transparent;
    color: transparent;	
}

@media screen and (min-width: 53em) {
	:root {
		--page-padding: 1.5rem 1.5rem;
	}
	.frame { 
		background: none;
		height: 100vh; 
		grid-gap: 2rem;
		grid-template-columns: auto auto 1fr;
		grid-template-rows: auto auto;
		grid-template-areas: 'title demos sponsor' '... ... credits';
	}
	.frame__demos,
	.frame__credits {
		justify-self: end;
	}
}
OnScrollTypoAnimations/index.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>On-Scroll Letter Animations | Demo 1 | Codrops</title>
	<meta name="author" content="Codrops" />
	<link rel="shortcut icon" href="favicon.ico">
	<link rel="stylesheet" href="https://use.typekit.net/avv4vgl.css">
	<link rel="stylesheet" type="text/css" href="css/base.css" />
	<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
	<script>document.documentElement.className="js";</script>
	<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
</head>
<body class="demo-1 loading">
	<main>
		<div class="frame">
			<div class="frame__title"> 
				<h1 class="frame__title-main"><strong>On-Scroll Letter Animations</strong> inspired by <a href="https://www.epic.net/">Epic.net</a></h1> 
			</div>
			<nav class="frame__demos">
				<span>Demos: </span>
				<a href="index.html" class="frame__demo frame__demo--current">1</a>
				<a href="index2.html" class="frame__demo">2</a>
				<a href="index3.html" class="frame__demo">3</a>
				<a href="index4.html" class="frame__demo">4</a>
			</nav>
			<span class="frame__credits">
				<a href="http://tympanus.net/Development/DoubleSlideshow/">Previous demo</a>
				<a href="https://tympanus.net/codrops/?p=72565">Article</a>
			</span>
		</div>
		<div class="intro">
			<h1 class="intro__title intro__title--big upper text-gradient ">Smart<br> Autonomous <br>Adventure</h1>
			<span class="intro__info">Elevate your perspective. <br>Scroll on.</span>
		</div>
		<div class="content content--left upper">
			<h2 class="content__title w600" data-split>
				Our AI-powered drone integrates advanced technology to provide an effortless flying experience and deliver breathtaking aerial footage with a single touch.
			</h2>
		</div>
		<div class="content content--left upper">
			<h2 class="content__title content__title--smaller narrow w600" data-split>
				We are revolutionizing aerial photography with MoodVision &ndash; a new feature that adjusts camera settings to capture the mood and atmosphere of surroundings, providing stunning images that truly encapsulate the experience.
			</h2>
		</div>
		<div class="content content--left upper">
			<p class="content__text content__text--small">WARNING: This drone is not a toy. It is a high-tech, sophisticated device designed for aerial photography and videography. Please read the manual carefully before operating the drone, and be aware of your surroundings and any potential hazards, including people, animals, buildings, and power lines. Do not fly the drone in restricted airspaces or near airports. Fly responsibly and within the bounds of your local laws and regulations. Failure to follow these instructions could result in injury or damage to property. The manufacturer and seller shall not be held liable for any damages or injury caused by improper use.</p>
		</div>
	</main>
	<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js"></script>
	<script src="https://unpkg.com/split-type"></script>
	<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/bundled/lenis.js"></script>
	<script src="js/index.js"></script>
</body>
</html>
함께 쓰는 파일 35개 보기
OnScrollTypoAnimations/index2.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>On-Scroll Letter Animations | Demo 2 | Codrops</title>
	<meta name="author" content="Codrops" />
	<link rel="shortcut icon" href="favicon.ico">
	<link rel="stylesheet" href="https://use.typekit.net/zfk1tfr.css">
	<link rel="stylesheet" type="text/css" href="css/base.css" />
	<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
	<script>document.documentElement.className="js";</script>
	<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
</head>
<body class="demo-2 loading">
	<main>
		<div class="frame">
			<div class="frame__title"> 
				<h1 class="frame__title-main"><strong>On-Scroll Letter Animations</strong> inspired by <a href="https://www.epic.net/">Epic.net</a></h1> 
			</div>
			<nav class="frame__demos">
				<span>Demos: </span>
				<a href="index.html" class="frame__demo">1</a>
				<a href="index2.html" class="frame__demo frame__demo--current">2</a>
				<a href="index3.html" class="frame__demo">3</a>
				<a href="index4.html" class="frame__demo">4</a>
			</nav>
			<span class="frame__credits">
				<a href="http://tympanus.net/Development/DoubleSlideshow/">Previous demo</a>
				<a href="https://tympanus.net/codrops/?p=72565">Article</a>
			</span>
		</div>
		<div class="intro">
			<h1 class="intro__title text-centered upper w400 heart">Virtual romance <br>reimagined</h1>
			<span class="intro__info centered larger">Scroll into love</span>
		</div>
		<div class="content">
			<h2 class="content__title text-centered centered w400 narrow" data-split>
				Imagine a world where you can explore new virtual environments, meet new people, and form meaningful connections, all from the comfort of your own home.
			</h2>
		</div>
		<div class="content">
			<h2 class="content__title text-centered centered w400 narrow" data-split>That's the vision behind VirtLife&#8482;, a revolutionary dating platform that brings together a vibrant community of individuals from all over the world to connect and find love in the virtual world.</h2>
		</div>
		<div class="content">
			<p class="content__text">VirtLife&#8482; is a virtual reality dating platform intended for entertainment purposes only. The virtual interactions and connections formed on the platform are not real and should not be considered a substitute for real-life relationships. VirtLife&#8482; does not guarantee or warrant the accuracy, completeness, or usefulness of any information provided on the platform. Users are solely responsible for their interactions with others on the platform and VirtLife&#8482; shall not be held responsible for any damages arising from such interactions.</p>
		</div>
	</main>
	<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js"></script>
	<script src="https://unpkg.com/split-type"></script>
	<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/bundled/lenis.js"></script>
	<script src="js/index2.js"></script>
</body>
</html>
OnScrollTypoAnimations/index3.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>On-Scroll Letter Animations | Demo 3 | Codrops</title>
	<meta name="author" content="Codrops" />
	<link rel="shortcut icon" href="favicon.ico">
	<link rel="stylesheet" href="https://use.typekit.net/lce3oen.css">
	<link rel="stylesheet" type="text/css" href="css/base.css" />
	<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
	<script>document.documentElement.className="js";</script>
	<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
</head>
<body class="demo-3 loading">
	<main>
		<div class="frame">
			<div class="frame__title"> 
				<h1 class="frame__title-main"><strong>On-Scroll Letter Animations</strong> inspired by <a href="https://www.epic.net/">Epic.net</a></h1> 
			</div>
			<nav class="frame__demos">
				<span>Demos: </span>
				<a href="index.html" class="frame__demo">1</a>
				<a href="index2.html" class="frame__demo">2</a>
				<a href="index3.html" class="frame__demo frame__demo--current">3</a>
				<a href="index4.html" class="frame__demo">4</a>
			</nav>
			<span class="frame__credits">
				<a href="http://tympanus.net/Development/DoubleSlideshow/">Previous demo</a>
				<a href="https://tympanus.net/codrops/?p=72565">Article</a>
			</span>
		</div>
		<div class="intro">
			<h1 class="intro__title text-centered w400 intro__title--big">Empowering <br>Financial Futures</h1>
			<span class="intro__info centered text-centered larger">Explore<br> smart investing</span>
		</div>
		<div class="content">
			<h2 class="content__title text-centered centered w400 narrow" data-split>
				Our novel investment firm is dedicated to harnessing the power of artificial intelligence to drive the future of finance. By focusing on AI-driven investment opportunities, we aim to help our clients stay ahead of the curve and reach their financial goals with confidence. 
			</h2>
		</div>
		<div class="content">
			<h2 class="content__title text-centered centered content__title--smaller narrow w400" data-split>With our deep understanding of the latest AI technologies and trends, we are committed to finding and presenting the most promising investment options that have the potential to deliver strong and sustainable returns. Whether you're looking to diversify your portfolio or make a big impact in the AI market, we are here to support and empower your investment journey.</h2>
		</div>
		<div class="content">
			<p class="content__text">The information provided on this website is for general informational purposes only and should not be construed as investment advice. While every effort is made to ensure the accuracy and completeness of the information, IntelliInvests does not guarantee or make any representations regarding the use or the results of the use of the information. The information on this website is not intended to be used as the sole basis for investment decisions, and you should always seek professional advice before making any investment decisions. IntelliInvests will not be held responsible for any direct or indirect loss or damage that may arise from the use of the information provided on this website.</p>
		</div>
	</main>
	<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js"></script>
	<script src="https://unpkg.com/split-type"></script>
	<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/bundled/lenis.js"></script>
	<script src="js/index3.js"></script>
</body>
</html>
OnScrollTypoAnimations/index4.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
	<meta charset="UTF-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<title>On-Scroll Letter Animations | Demo 4 | Codrops</title>
	<meta name="author" content="Codrops" />
	<link rel="shortcut icon" href="favicon.ico">
	<link rel="stylesheet" href="https://use.typekit.net/ukl2bjz.css">
	<link rel="stylesheet" type="text/css" href="css/base.css" />
	<script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"></script>
	<script>document.documentElement.className="js";</script>
	<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
</head>
<body class="demo-4 loading">
	<main>
		<div class="frame">
			<div class="frame__title"> 
				<h1 class="frame__title-main"><strong>On-Scroll Letter Animations</strong> inspired by <a href="https://www.epic.net/">Epic.net</a></h1> 
			</div>
			<nav class="frame__demos">
				<span>Demos: </span>
				<a href="index.html" class="frame__demo">1</a>
				<a href="index2.html" class="frame__demo">2</a>
				<a href="index3.html" class="frame__demo">3</a>
                <a href="index4.html" class="frame__demo frame__demo--current">4</a>
			</nav>
			<span class="frame__credits">
				<a href="http://tympanus.net/Development/DoubleSlideshow/">Previous demo</a>
				<a href="https://tympanus.net/codrops/?p=72565">Article</a>
			</span>
		</div>
		<div class="intro">
			<h1 class="intro__title intro__title--medium centered text-right w400">Step into a world <br>without limits</h1>
			<span class="intro__info centered text-centered broad">Discover <br>Cross-reality <br>Gaming</span>
		</div>
		<div class="content centered">
			<h2 class="content__title centered content__title--smaller narrow w400" data-split>
				With Cross-Reality Gaming (CRG), players are no longer limited to just one type of reality. Move from a fully immersive virtual world to an augmented reality cityscape and back again, all within the same game 
			</h2>
		</div>
		<div class="content centered">
			<h2 class="content__title centered content__title--smaller narrow w400" data-split>Whether you want to escape into a fantastical virtual world, or bring the game into your own reality, CRG offers a level of versatility and unpredictability that traditional gaming can't match.</h2>
		</div>
		<div class="content">
			<p class="content__text">This website and its content are for informational purposes only. The virtual reality experiences and games offered on this platform are for entertainment purposes and do not represent real-life situations. Users should use the platform responsibly and in accordance with all applicable laws and regulations. The platform is not responsible for any harm or injury that may occur while using the virtual reality experiences or games. By using the platform, you acknowledge and agree to these terms.</p>
		</div>
	</main>
	<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/ScrollTrigger.min.js"></script>
	<script src="https://unpkg.com/split-type"></script>
	<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/bundled/lenis.js"></script>
	<script src="js/index4.js"></script>
</body>
</html>
OnScrollTypoAnimations/js/index.js
파일 저장


// Lenis smooth scrolling
let lenis;

const preloadFonts = (id) => {
    return new Promise((resolve) => {
        WebFont.load({
            typekit: {
                id: id
            },
            active: resolve
        });
    });
};

// Initialize Lenis smooth scrolling
const initSmoothScrolling = () => {
	
    lenis = new Lenis({
		lerp: 0.2,
		smooth: true
	});

    lenis.on('scroll', () => ScrollTrigger.update());

	const scrollFn = (time) => {
		lenis.raf(time);
		requestAnimationFrame(scrollFn);
	};
	
    requestAnimationFrame(scrollFn);

};

const animateWords = el => {

    // from: https://www.npmjs.com/package/split-type#splitting-text 
    // Important: The following style should be applied to all target elements. This prevents the characters from shifting slightly when text is split/reverted.
    gsap.set(el, {'font-kerning': 'none'});

    // Apply SplitType
    const st = new SplitType(el, { types: 'lines, words' });
    const lines = st.lines;

    const tl = gsap.timeline({
        scrollTrigger: {
            trigger: el,
            start: 'center center',
            end: '+=200%',
            scrub: true,
            pin: el
        }
    })
    .set(el, {perspective: 1000});

    for (const [linepos,line] of lines.entries()) {
        
        gsap.set(line, {transformStyle: 'preserve-3d'});
        const words = line.querySelectorAll('.word');
        gsap.set(words, {transformOrigin: '0% 50%'});
        
        tl
        .to(words, {
            ease: 'none',
            opacity: 0,
            yPercent: pos => pos*-100-300,
            rotationX: () => gsap.utils.random(-90,-10),
            rotationY: () => gsap.utils.random(0,20),
            rotationZ: pos => (pos+1)*-7,
            //stagger: 0.01,
        }, linepos*.08);

    }
    
};

// GSAP Scroll Triggers
const scroll = () => {
    [...document.querySelectorAll('[data-split]')].forEach(el => {
        animateWords(el)
    });
};

// Preload images and fonts
preloadFonts('lce3oen').then(() => {
    // Remove loader (loading class)
    document.body.classList.remove('loading');
    // Lenis (smooth scrolling)
    initSmoothScrolling();
    // GSAP Scroll Triggers
    scroll();
});
OnScrollTypoAnimations/js/index2.js
파일 저장


// Lenis smooth scrolling
let lenis;

const preloadFonts = (id) => {
    return new Promise((resolve) => {
        WebFont.load({
            typekit: {
                id: id
            },
            active: resolve
        });
    });
};

// Initialize Lenis smooth scrolling
const initSmoothScrolling = () => {
	
    lenis = new Lenis({
		lerp: 0.2,
		smooth: true
	});

    lenis.on('scroll', () => ScrollTrigger.update());

	const scrollFn = (time) => {
		lenis.raf(time);
		requestAnimationFrame(scrollFn);
	};
	
    requestAnimationFrame(scrollFn);

};

const animateWords = el => {
    
    // from: https://www.npmjs.com/package/split-type#splitting-text 
    // Important: The following style should be applied to all target elements. This prevents the characters from shifting slightly when text is split/reverted.
    gsap.set(el, {'font-kerning': 'none'});

    // Apply SplitType
    const st = new SplitType(el, { types: 'lines, words' });
    
    const lines = st.lines;

    const tl = gsap.timeline({
        scrollTrigger: {
            trigger: el,
            start: 'center center',
            end: '+=300%',
            scrub: true,
            pin: el
        }
    })
    .set(el, {perspective: 1000});

    for (const [linepos,line] of lines.entries()) {
        
        gsap.set(line, {transformStyle: 'preserve-3d'});

        const words = line.querySelectorAll('.word');
        
        tl
        .to(words, {
            ease: 'power2',
            opacity: 0,
            xPercent: (pos,_,arr) => pos < arr.length/2 ? Math.abs(pos-arr.length/2)*gsap.utils.random(-40,-10) : Math.abs(pos-arr.length/2)*gsap.utils.random(10,40),
            yPercent: (pos,_,arr) => Math.abs(pos-arr.length/2)*gsap.utils.random(-80,-40)-150,
            rotationY: (pos,_,arr) => pos > arr.length/2 ? Math.abs(pos-arr.length/2)*-15 : Math.abs(pos-arr.length/2)*15,
            z: (pos,_,arr) => Math.abs(pos - arr.length/2) ? gsap.utils.random(-40,-20) : gsap.utils.random(20,40),
            stagger: {
                each: 0.01,
                from: 'edges'
            },
            
        }, linepos*.05);

    }
    
};

// GSAP Scroll Triggers
const scroll = () => {
    [...document.querySelectorAll('[data-split]')].forEach(el => {
        animateWords(el)
    });
};

// Preload images and fonts
preloadFonts('lce3oen').then(() => {
    // Remove loader (loading class)
    document.body.classList.remove('loading');
    // Lenis (smooth scrolling)
    initSmoothScrolling();
    // GSAP Scroll Triggers
    scroll();
});


OnScrollTypoAnimations/js/index3.js
파일 저장


// Lenis smooth scrolling
let lenis;

const preloadFonts = (id) => {
    return new Promise((resolve) => {
        WebFont.load({
            typekit: {
                id: id
            },
            active: resolve
        });
    });
};

// Initialize Lenis smooth scrolling
const initSmoothScrolling = () => {
	
    lenis = new Lenis({
		lerp: 0.2,
		smooth: true
	});

    lenis.on('scroll', () => ScrollTrigger.update());

	const scrollFn = (time) => {
		lenis.raf(time);
		requestAnimationFrame(scrollFn);
	};
	
    requestAnimationFrame(scrollFn);

};

const animateWords = el => {
    
    // from: https://www.npmjs.com/package/split-type#splitting-text 
    // Important: The following style should be applied to all target elements. This prevents the characters from shifting slightly when text is split/reverted.
    gsap.set(el, {'font-kerning': 'none'});

    // Apply SplitType
    const st = new SplitType(el, { types: 'lines, words' });
    const lines = st.lines;

    const tl = gsap.timeline({
        scrollTrigger: {
            trigger: el,
            start: 'center center',
            end: '+=300%',
            scrub: true,
            pin: el
        }
    })
    .set(el, {perspective: 1000});

    for (const [linepos,line] of lines.entries()) {
        
        gsap.set(line, {transformStyle: 'preserve-3d'});

        const words = line.querySelectorAll('.word');
        
        tl
        .to(words, {
            ease: 'back.inOut',
            opacity: 0,
            rotationY: (pos,_,arr) => pos > arr.length/2 ? Math.abs(pos-arr.length/2)*-15 : Math.abs(pos-arr.length/2)*15,
            z: () => gsap.utils.random(-1000,-500),
            stagger: {
                each: 0.02,
                from: 'center'
            }
            
        }, linepos*.05);

    }
    
};

// GSAP Scroll Triggers
const scroll = () => {
    [...document.querySelectorAll('[data-split]')].forEach(el => {
        animateWords(el)
    });
};

// Preload images and fonts
preloadFonts('lce3oen').then(() => {
    // Remove loader (loading class)
    document.body.classList.remove('loading');
    // Lenis (smooth scrolling)
    initSmoothScrolling();
    // GSAP Scroll Triggers
    scroll();
});


OnScrollTypoAnimations/js/index4.js
파일 저장


// Lenis smooth scrolling
let lenis;

const preloadFonts = (id) => {
    return new Promise((resolve) => {
        WebFont.load({
            typekit: {
                id: id
            },
            active: resolve
        });
    });
};

// Initialize Lenis smooth scrolling
const initSmoothScrolling = () => {
	
    lenis = new Lenis({
		lerp: 0.2,
		smooth: true
	});

    lenis.on('scroll', () => ScrollTrigger.update());

	const scrollFn = (time) => {
		lenis.raf(time);
		requestAnimationFrame(scrollFn);
	};
	
    requestAnimationFrame(scrollFn);

};

const animateWords = el => {
    
    // from: https://www.npmjs.com/package/split-type#splitting-text 
    // Important: The following style should be applied to all target elements. This prevents the characters from shifting slightly when text is split/reverted.
    gsap.set(el, {'font-kerning': 'none'});

    // Apply SplitType
    const st = new SplitType(el, { types: 'lines, words' });
    
    const lines = st.lines;
    const words = st.words;

    const tl = gsap.timeline({
        scrollTrigger: {
            trigger: el,
            start: 'center center',
            end: '+=300%',
            scrub: true,
            pin: el
        }
    })
    .set(el, {perspective: 1000});

    gsap.set(lines, {transformStyle: 'preserve-3d'});

    tl
    .to(words, {
        ease: 'back.in(2)',
        opacity: 0,
        rotationX: (pos,_,arr) => Math.abs(pos-arr.length/2)*-15,
        z: -1000,
        stagger: {
            each: 0.03,
            from: 'center'
        }
        
    });
};

// GSAP Scroll Triggers
const scroll = () => {
    [...document.querySelectorAll('[data-split]')].forEach(el => {
        animateWords(el)
    });
};

// Preload images and fonts
preloadFonts('lce3oen').then(() => {
    // Remove loader (loading class)
    document.body.classList.remove('loading');
    // Lenis (smooth scrolling)
    initSmoothScrolling();
    // GSAP Scroll Triggers
    scroll();
});


OnScrollTypoAnimations/js/utils.js
파일 저장

// Preload images
const preloadFonts = (id) => {
    return new Promise((resolve) => {
        WebFont.load({
            typekit: {
                id: id
            },
            active: resolve
        });
    });
};

export {
    preloadFonts
};
LICENSE실행 안내·자료
파일 저장

MIT License

Copyright (c) 2009 - 2022 [Codrops](https://tympanus.net/codrops)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Bundled dependency licenses실행 안내·자료
파일 저장

https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/README.md
[![LENIS](https://assets.studiofreight.com/lenis/header.png)](https://github.com/studio-freight/lenis)

[![npm version](https://img.shields.io/badge/dynamic/json?color=blue&label=npm&prefix=v&query=version&suffix=%20&url=https%3A%2F%2Fraw.githubusercontent.com%2Fstudio-freight%2Flenis%2Fmain%2Fpackage.json)](https://www.npmjs.com/package/@studio-freight/lenis)

## Introduction

🚧 Still in WIP, API might change with new releases 🚧

This is our take on smooth scroll, lightweight, hard working, smooth as butter scroll. See [Demo](https://lenis.studiofreight.com/)

<br>

## Features

- Performant
- Lightweight [(~2Kb gzipped)](https://bundlejs.com/?q=%40studio-freight%2Flenis)
- Run scroll in main thread
- Accessibility (CMD+F page search, keyboard navigation, keep scroll position on page refresh, etc.)
- External RAF
- SSR proof
- Not opinionated
- Tree-shakeable
- Custom scroll easing/duration

<br>

| Feature                     | [Locomotive-scroll](https://github.com/locomotivemtl/locomotive-scroll) | [GSAP ScrollSmoother](https://greensock.com/scrollsmoother/)                                  | [Lenis](https://github.com/studio-freight/lenis)            |
| --------------------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Native scrollbar            | ❌                                                                      | ✅                                                                                            | ✅                                                          |
| Native scroll inputs        | ❌                                                                      | ✅                                                                                            | ❌                                                          |
| Normalize scroll experience | ✅                                                                      | ❌                                                                                            | ✅                                                          |
| Accessibility               | ❌                                                                      | ❌                                                                                            | ✅                                                          |
| CSS Sticky                  | ❌                                                                      | ❌                                                                                            | ✅                                                          |
| IntsersectionObserver       | ❌                                                                      | ❌                                                                                            | ✅                                                          |
| Open source                 | ✅                                                                      | ❌                                                                                            | ✅                                                          |
| Built-in animation system   | ✅                                                                      | ✅                                                                                            | ❌                                                          |
| Size (gzip)                 | [12.33KB](https://bundlejs.com/?q=locomotive-scroll)                    | [26.08KB](https://bundlejs.com/?q=gsap%2FScrollSmoother&treeshake=%5B%7BScrollSmoother%7D%5D) | [2.13kb](https://bundlejs.com/?q=%40studio-freight%2Flenis) |

<br>

## Installing

using package manager:

```bash
$ npm i @studio-freight/lenis
```

<br/>

using scripts:

```htmt
<script src="https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.27/bundled/lenis.js"></script>
```

<br>

## Setup

Basic setup

```js
import Lenis from '@studio-freight/lenis'

const lenis = new Lenis({
  duration: 1.2,
  easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)), // https://www.desmos.com/calculator/brs54l4xou
  direction: 'vertical', // vertical, horizontal
  gestureDirection: 'vertical', // vertical, horizontal, both
  smooth: true,
  mouseMultiplier: 1,
  smoothTouch: false,
  touchMultiplier: 2,
  infinite: false,
})

//get scroll value
lenis.on('scroll', ({ scroll, limit, velocity, direction, progress }) => {
  console.log({ scroll, limit, velocity, direction, progress })
})

function raf(time) {
  lenis.raf(time)
  requestAnimationFrame(raf)
}

requestAnimationFrame(raf)
```

<br/>

Using custom scroll container

```js
const lenis = new Lenis({
  wrapper: NodeElement, // element which has overflow
  content: NodeElement, // usually wrapper's direct child
})
```

<br/>

## Instance settings

| Option             | Type          | Default                                            | Description                                                                                                                                                     |
| ------------------ | ------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wrapper`          | `NodeElement` | `window`                                           | Default element which has overflow                                                                                                                              |
| `content`          | `NodeElement` | `document.documentElement`                                         | `wrapper`'s direct child                                                                                                                                        |
| `duration`         | `number`      | `1.2`                                              | Specifies the duration of the animation                                                                                                                         |
| `easing`           | `function`    | `(t) => Math.min(1, 1.001 - Math.pow(2, -10 * t))` | Specifies the rate of change of a specific value, our default is custom but you can pick one from [Easings.net](https://easings.net/en)                         |
| `direction`        | `string`      | `vertical`                                         | `vertical` or `horizontal` scrolling.                                                                                                                           |
| `gestureDirection` | `string`      | `vertical`                                         | `vertical`, `horizontal` or `both`.                                                                                                                             |
| `smooth`           | `boolean`     | `true`                                             | Enable or disable 'smoothness'                                                                                                                                  |
| `mouseMultiplier`  | `number`      | `1`                                                | This value is passed directly to [Virtual Scroll](https://github.com/ayamflow/virtual-scroll)                                                                   |
| `smoothTouch`      | `boolean`     | `false`                                            | Enable or disable 'smoothness' while scrolling using touch. Note: We have disabled it by default because touch devices native smoothness is impossible to mimic |
| `touchMultiplier`  | `number`      | `string`                                           | This value is passed directly to [Virtual Scroll](https://github.com/ayamflow/virtual-scroll)                                                                   |
| `infinite`         | `boolean`     | `false`                                            | Enable infinite scrolling!                                                                                                                                      |

<br/>

## Instance Methods

| Method                                                   | Description                                                   | Arguments                                                                                                                                                                                                                                                                                                                         |
| -------------------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `raf(time)`                                              | Must be called every frame for internal usage.                |                                                                                                                                                                                                                                                                                                                                   |
| `scrollTo(target,{offset, duration, easing, immediate})` | Scroll to a target.                                           | `target`: can be `Number`, `NodeElement` or `String` (CSS selector).<br> `offset` : `Number` equivalent to [scroll-padding-top](https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-padding-top).<br>`duration` : `Number` scroll duration in seconds.<br>`easing` : `Function`.<br>`immediate` : ignore duration and easing. |
| `on(id,callback({scroll,limit,velocity,direction}))`     | `id` can be any of the following [instance events](#instance-events) to listen. |                                                                                                                                                                                                                                                                                                                                   |
| `stop()`                                                 | To pause the scroll                                           |                                                                                                                                                                                                                                                                                                                                   |
| `start()`                                                | To resume the scroll                                          |                                                                                                                                                                                                                                                                                                                                   |
| `destroy()`                                              | To destroy the instance and remove all events.                |                                                                                                                                                                                                                                                                                                                                   |

## Instance Events

| Event    | Callback Arguments                                                                                                                                   |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scroll` | `scroll`: returns scroll position. <br>`limit`: returns scroll limit. <br>`velocity`: returns scroll velocity. <br>`direction`: returns `1` or `-1`. |

<br/>

## Considerations

### Things to consider if you want to add Lenis to your codebase will be listed here.

#### Make sure `scroll-behavior` is set to initial or not set at all (thanks [@thagxt](https://github.com/thagxt))

```css
html {
  scroll-behavior: initial;
}
```

#### Keep html and body elements default sized ([see this issue](https://github.com/studio-freight/lenis/issues/10))

```css
html,
body {
  min-height: 100%;
  height: auto;
}
```

#### Use `data-lenis-prevent` attribute on nested scroll elements. In addition, we advice you to add `overscroll-behavior: contain` on this element.

```html
<div data-lenis-prevent>scroll content</div>
```

#### Manually use `lenis.scrollTo('#anchor')` on anchor link click ([see this issue](https://github.com/studio-freight/lenis/issues/19))

```html
<a href="#anchor" onclick="lenis.scrollTo('#anchor')">scroll to anchor</a>
```

<br>

## Limitations

- no support of CSS scroll-snap
- can only run 60fps maximum on Safari ([source](https://bugs.webkit.org/show_bug.cgi?id=173434))

<br>

## Tutorials

- [Scroll Animation Ideas for Image Grids](https://tympanus.net/Development/ScrollAnimationsGrid/) by [Codrops](https://tympanus.net/codrops)
- [How to Animate SVG Shapes on Scroll](https://tympanus.net/codrops/2022/06/08/how-to-animate-svg-shapes-on-scroll) by [Codrops](https://tympanus.net/codrops)
- [The BEST smooth scrolling library for your Webflow website! (Lenis)](https://www.youtube.com/watch?v=VtCqTLRRMII) by [Diego Toda de Oliveira](https://www.diegoliv.works/)
- [Easy smooth scroll in @Webflow with Lenis + GSAP ScrollTrigger tutorial](https://www.youtube.com/watch?v=gRKuzQTXq74) by [También Studio](https://www.tambien.studio/)

<br>

## Plugins

- [Loconative-scroll](https://github.com/quentinhocde/loconative-scroll#how-to-switch-from-locomotive-scroll-to-loconative-scroll) by [Quentin Hocde](https://twitter.com/QuentinHocde)

<br>

## Lenis in use

- [Wyre](https://www.sendwyre.com/) by [Studio Freight](https://www.studiofreight.com/)
- [Lunchbox](https://lunchbox.io/) by [Studio Freight](https://www.studiofreight.com/)
- [Easol](https://easol.com/) by [Studio Freight](https://www.studiofreight.com/)
- [Repeat](https://getrepeat.io/) by [Studio Freight](https://www.studiofreight.com/)
- [Dragonfly](https://dragonfly.xyz/) by [Studio Freight](https://www.studiofreight.com/)
- [Yuga Labs](https://yuga.com/) by [Antinomy Studio](https://antinomy.studio/)
- [Quentin Hocde's Portfolio](https://quentinhocde.com) by [Quentin Hocde](https://twitter.com/QuentinHocde)
- [Houses Of](https://housesof.world) by [Félix P.](https://flayks.com/) & [Shelby Kay](https://shelbykay.dev/)
- [Shelby Kay's Portfolio](https://shelbykay.dev) by [Shelby Kay](https://shelbykay.dev/)
- [Heights Agency Portfolio](https://www.heights.agency/) by [Francesco Michelini](https://www.francescomichelini.com/)
- [Goodship](https://goodship.io) by [Studio Freight](https://www.studiofreight.com/)
- [Flayks' Portfolio](https://flayks.com) by [Félix P.](https://flayks.com/) & [Shelby Kay](https://shelbykay.dev/)

<br/>

## Authors

This set of hooks is curated and maintained by the Studio Freight Darkroom team:

- Clement Roche ([@clementroche\_](https://twitter.com/clementroche_)) – [Studio Freight](https://studiofreight.com)
- Guido Fier ([@uido15](https://twitter.com/uido15)) – [Studio Freight](https://studiofreight.com)
- Leandro Soengas ([@lsoengas](https://twitter.com/lsoengas)) - [Studio Freight](https://studiofreight.com)
- Franco Arza ([@arzafran](https://twitter.com/arzafran)) - [Studio Freight](https://studiofreight.com)

<br/>

## License

[The MIT License.](https://opensource.org/licenses/MIT)


https://cdn.jsdelivr.net/gh/studio-freight/lenis@0.2.28/package.json
{
  "name": "@studio-freight/lenis",
  "version": "0.2.28",
  "description": "Lenis is a smooth scroll library to normalize the scrolling experience across devices",
  "files": [
    "dist"
  ],
  "sideEffects": false,
  "source": "src/lenis.js",
  "main": "dist/lenis.js",
  "umd:main": "dist/lenis.umd.js",
  "module": "dist/lenis.mjs",
  "types": "dist/lenis.d.ts",
  "exports": {
    "require": "./dist/lenis.js",
    "default": "./dist/lenis.modern.mjs"
  },
  "devDependencies": {
    "@size-limit/preset-small-lib": "^8.1.0",
    "husky": "^8.0.2",
    "lint-staged": "^13.0.3",
    "microbundle": "^0.15.1",
    "path": "^0.12.7",
    "prettier": "^2.8.0",
    "rimraf": "^3.0.2",
    "size-limit": "^8.1.0",
    "stats.js": "^0.17.0",
    "typescript": "^4.9.3",
    "vite": "^3.2.4"
  },
  "dependencies": {
    "tiny-emitter": "^2.1.0",
    "virtual-scroll": "^2.2.1"
  },
  "author": "studio-freight",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/studio-freight/lenis.git"
  },
  "scripts": {
    "dev": "microbundle watch -i src/lenis.js --format umd --compress --no-sourcemap --no-pkg-main --external none --output ./bundled --name 'Lenis' & npm run dev:website",
    "dev:website": "npm run dev:website --prefix ./website",
    "size": "size-limit",
    "clean": "rimraf dist && rimraf bundled",
    "build": "npm run clean && npm run build:light && npm run build:bundle && npm run build:types",
    "build:types": "tsc --allowJs -d --emitDeclarationOnly --declarationDir dist --removeComments ./src/lenis.js ./src/maths.js",
    "build:light": "microbundle",
    "build:bundle": "microbundle build -i src/lenis.js --format umd --compress --no-sourcemap --no-pkg-main --external none --output ./bundled --name Lenis",
    "build:website": "vite build",
    "prebuild": "npm run clean",
    "preversion": "npm run build",
    "postversion": "git push --follow-tags",
    "prepublishOnly": "npm run build",
    "prepare": "husky install"
  },
  "bugs": {
    "url": "https://github.com/studio-freight/lenis/issues"
  },
  "homepage": "https://github.com/studio-freight/lenis#readme",
  "keywords": [
    "smooth",
    "scroll"
  ],
  "size-limit": [
    {
      "limit": "4.5 kB",
      "path": "dist/lenis.js"
    },
    {
      "limit": "4.5 kB",
      "path": "dist/lenis.mjs"
    },
    {
      "limit": "4.5 kB",
      "path": "dist/lenis.modern.mjs"
    },
    {
      "limit": "4.5 kB",
      "path": "dist/lenis.umd.js"
    }
  ],
  "lint-staged": {
    "*.js": "eslint --cache --fix",
    "*.{js,css,scss,md}": "prettier --write"
  }
}


Standard MIT permission and disclaimer for the original Lenis 0.2.28 MIT declaration. Original authors are retained in its README above.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


GSAP standard license snapshot
Source: https://gsap.com/community/standard-license/
Retrieved: 2026-09-22T04:22:49.089Z
Original distribution copyright and version headers remain in the runtime code.

Standard "No Charge" GSAP License

 I. DEFINITIONS

 “GSAP License” means the terms and conditions of this GSAP Software License Agreement.

 "GSAP Products" means any Software made available at gsap.com (https://gsap.com) or any successor sites, including but not limited to the GSAP animation library and related plugins, tools, or extensions.

 "Permitted Uses" means the implementation and/or use of GSAP Products on any website, web application, or digital interface by any person or entity (which may include, for clarity, those of companies that compete with Webflow in other areas of business).

 "Prohibited Uses" means any implementation and/or use of GSAP Products in tools that allow users to build visual animations without code that encourages, induces, or materially assists in creating a solution that competes with Webflow’s visual animation building capabilities.

 "Competitive Products" means any software, tool, or service that enables users to create, edit, or manage animations through a visual interface or builder similar to Webflow (https://webflow.com).

 II. GRANT OF LICENSE

 Subject to the terms and conditions of this GSAP License, Webflow grants you a non-exclusive, worldwide license to use, reproduce, display, and implement GSAP Products solely for Permitted Uses.

 III. RESTRICTIONS

 You may not:

 Use any GSAP Products for any Prohibited Uses without prior written consent;

 Reverse engineer any GSAP Products for the purpose of creating Competitive Products;

 Remove or alter any proprietary notices or branding from GSAP Products.

 IV. OWNERSHIP AND INTELLECTUAL PROPERTY

 All intellectual property rights in GSAP Products, including but not limited to copyright, patents, trademarks, and trade secrets, remain the exclusive property of Webflow. This GSAP License does not transfer any ownership rights in GSAP Products to you.

 V. TERMINATION

 Webflow may terminate this GSAP License and revoke your access in its discretion if you fail to comply with any of these terms and conditions. Upon termination, you must cease all use of GSAP Products and destroy all copies in your possession.

 VI. MISCELLANEOUS PROVISIONS

 General: This GSAP License is incorporated into and subject to Webflow’s Terms of Service available here (https://webflow.com/legal/terms) ("Terms of Service"). In the event of any conflict or inconsistency between this GSAP License and the Terms of Service, the terms of this GSAP License shall govern in relation to your use of any GSAP Products.

 Amendments: Webflow reserves the right to update or modify this GSAP License at any time by posting the revised terms on this website, provided that any such updates or modifications shall not result in any material degradation to the security, integrity, or functionality of any GSAP Products. You understand and agree that your continued use of any GSAP Products after such revisions to this GSAP License constitutes your acceptance of this GSAP License as revised. If you do not accept the revised GSAP License, you are prohibited from using versions of the GSAP Products released after the effective date of the revised GSAP License (as well as any updates made to previous versions). Notwithstanding, you may continue using previous versions of GSAP Products under the applicable terms licensed to you prior to the effective date of the revised GSAP License (for clarity, excluding any updates made thereto).

 No Waiver: Failure of Webflow to enforce any provision of this GSAP License shall not constitute a waiver of future enforcement of that or any other provision.

 FAQ

 Is it acceptable for AI tools like ChatGPT, Cursor, Lovable, Webstudio, etc. to generate GSAP code?
 Absolutely! AI-generated code is not a "Prohibited Use".

 What if a WordPress plugin or theme or other niche tool allows users to create GSAP-driven effects through a visual interface? Is that prohibited?
 We want to encourage developers to build on top of GSAP, including visual tools that don't directly compete with Webflow's rich animation-building capabilities. If you are not sure if your product might be considered a "Prohibited Use", feel free to contact us (https://gsap.com/contact) so we can talk through it!

 Can I really use GSAP in commercial projects without paying anything?
 Yes, really! Commercial usage is covered under the standard license. All of GSAP including the plugins that were formerly "members-only" like SplitText (https://gsap.com/docs/v3/Plugins/SplitText/) and MorphSVG (https://gsap.com/docs/v3/Plugins/MorphSVGPlugin) can be used in commercial projects at no charge. Enjoy! 💚

 Effective date: April 30, 2025

 Last modified date: May 30, 2025

 Copyright (©) 2025, Webflow

ZoomSlideshow/css/base.css
파일 저장

*,
*::after,
*::before {
	box-sizing: border-box;
}

:root {
	font-size: 18px;
	--color-text: #fff;
	--color-bg: #000;
	--color-link: #fff;
	--color-link-hover: #fff;
}

body {
	margin: 0;
	color: var(--color-text);
	background-color: var(--color-bg);
	font-family: area-normal,-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	width: 100%;
	height: 100vh;
	overflow: hidden;
	touch-action: none;
}

/* Page Loader */
.js .loading::before,
.js .loading::after {
	content: '';
	position: fixed;
	z-index: 1000;
}

.js .loading::before {
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: #f0f0f0;
}

.js .loading::after {
	top: 50%;
	left: 50%;
	width: 20vw;
	aspect-ratio: 0.75;
	transform: translate3d(-50%,-50%,0);
	background-color: #f0f0f0;
	animation: loaderAnim 1s linear infinite alternate forwards;

}

@keyframes loaderAnim {
	to {
		background-color: #ccc;
	}
}

a {
	text-decoration: none;
	color: var(--color-link);
	outline: none;
	cursor: pointer;
	opacity: 0.6;
}

a:hover {
	color: var(--color-link-hover);
	outline: none;
	opacity: 1;
}

/* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
a:focus {
	/* Provide a fallback style for browsers
	 that don't support :focus-visible */
	outline: none;
	background: lightgrey;
}

a:focus:not(:focus-visible) {
	/* Remove the focus indicator on mouse-focus for browsers
	 that do support :focus-visible */
	background: transparent;
}

a:focus-visible {
	/* Draw a very noticeable focus style for
	 keyboard-focus on browsers that do support
	 :focus-visible */
	outline: 2px solid red;
	background: transparent;
}

.unbutton {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	color: inherit;
	cursor: pointer;
}

.unbutton:focus {
	outline: none;
}

main {
	display: grid;
	grid-template-areas: 'main';
	position: relative;
	width: 100%;
	height: 100vh;
	overflow: hidden;
	place-items: center;
}

.frame {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	color: var(--color-title);
	padding: 1rem;
	font-size: 13px;
	font-weight: 600;
	display: grid;
	grid-template-columns: 100%;
	grid-template-areas: 'title' 'demos' 'credits' 'sponsor';
	justify-content: start;
	align-content: space-between;
	align-items: start;
	z-index: 100;
	pointer-events: none;
	grid-gap: 0.5rem;
}

.frame a {
	pointer-events: auto;
}

.frame a:not(.frame__demo) {
	white-space: nowrap;
	overflow: hidden;
	position: relative;
}

.frame a:not(.frame__demo)::before {
	content: '';
	height: 1px;
	width: 100%;
	background: currentColor;
	position: absolute;
	top: 90%;
	transition: transform 0.3s;
	transform-origin: 0% 50%;
}

.frame a:not(.frame__demo):hover::before {
	transform: scaleX(0);
	transform-origin: 100% 50%;
}

.frame__title {
	grid-area: title;
	display: flex;
	align-items: flex-end;
}

.frame strong {
	font-weight: 800;
}

.frame__title-main {
	font-size: inherit;
	margin: 0;
	font-weight: inherit;
}

.frame__demos {
	grid-area: demos;
	display: flex;
	gap: 1rem;
}

.frame__demo {
	text-decoration: none;
}

.frame__demo--current {
	font-weight: 800;
	color: var(--color-link-hover);
}

.frame__credits {
	grid-area: credits;
	display: flex;
	gap: 1rem;
}

.slider {
	grid-area: main;
	position: relative;
	overflow: hidden;
	display: grid;
	place-items: center;
	width: 100%;
	height: 100vh;
}

.slider__item {
	grid-area: 1 / 1 / -1 / -1;
	position: relative;
	width: 100%;
	aspect-ratio: 2.5 / 3;
	overflow: hidden;
	display: grid;
	place-items: center;
	pointer-events: none;
	transform: scale(0);
	opacity: 0;
	z-index: 3;
}

.slider__item--current {
	opacity: 1;
	pointer-events: auto;
	z-index: 50;
	transform: scale(0.3);
	z-index: 2;
}

.slider__item--previous {
	z-index: 1;
	opacity: 1;
	transform: scale(1);
}

.slider__item-inner {
	position: relative;
	width: 100%;
	height: 100%;
	display: grid;
	place-items: center;
	background-size: cover;
	background-position: 50% 50%;
}

.slider-nav {
	grid-area: main;
	padding: 1rem;
	width: 100%;
	line-height: 1;
	display: grid;
	grid-template-areas: 'prev next';
	z-index: 2;
	justify-content: space-between;
}

.slider-nav__item {
	line-height: 1.5;
	position: relative;
	text-transform: uppercase;
	display: block;
	font-family: "afronaut", sans-serif;
	font-weight: 400;
	font-size: clamp(1rem,7vw,3rem);
	transition: opacity 0.3s;
}

.slider-nav__item span {
	display: inline-block;
	pointer-events: none;
}

.slider-nav__item:hover {
	opacity: 0.5;
}

.slider-nav__item--prev {
	grid-area: prev;
}

.slider-nav__item--next {
	grid-area: next;
}

@media screen and (min-width: 53em) {
	.frame { 
		height: 100vh; 
		grid-gap: 2rem;
		grid-template-columns: auto auto 1fr;
		grid-template-rows: auto auto;
		grid-template-areas: 'title demos sponsor' 'credits ... ... ';
	}
	.frame__demos {
		justify-self: end;
	}
}
ZoomSlideshow/index.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Zoom Slideshow | Demo 1 | Codrops</title>
		<meta name="author" content="Codrops" />
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="stylesheet" href="https://use.typekit.net/scu3jka.css">
		<link rel="stylesheet" type="text/css" href="css/base.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting-cells.css" />
		<script>document.documentElement.className="js";</script>
		<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
	</head>
	<body class="demo-1 loading">
		<main>
			<div class="frame">
				<div class="frame__title"> 
					<h1 class="frame__title-main"><strong>Zoom Slideshow</strong> inspired by <a href="https://www.laurenbamford.com/">Lauren Bamford</a></h1> 
				</div>
				<nav class="frame__demos">
					<span>Demos: </span>
					<span class="frame__demo frame__demo--current">1</span>
					<a href="index2.html" class="frame__demo">2</a>
				</nav>
				<span class="frame__credits">
					<a href="http://tympanus.net/Development/OnScrollTypoAnimations/">Previous demo</a>
					<a href="https://tympanus.net/codrops/?p=72565">Article</a>
				</span>
			</div>
			<div class="slider">
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/1.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/2.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/3.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/4.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/5.jpg)"></div></div>
			</div>
			<nav class="slider-nav">
				<button class="unbutton slider-nav__item slider-nav__item--prev"><span>Prev</span></button>
				<button class="unbutton slider-nav__item slider-nav__item--next"><span>Next</span></button>
			</nav>
		</main>
		<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/Observer.min.js"></script>
		<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
		<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
		<script type="module" src="js/demo1/index.js"></script>
	</body>
</html>
ZoomSlideshow/index2.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Zoom Slideshow | Demo 2 | Codrops</title>
		<meta name="author" content="Codrops" />
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="stylesheet" href="https://use.typekit.net/scu3jka.css">
		<link rel="stylesheet" type="text/css" href="css/base.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting-cells.css" />
		<script>document.documentElement.className="js";</script>
		<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
	</head>
	<body class="demo-2 loading">
		<main>
			<div class="frame">
				<div class="frame__title"> 
					<h1 class="frame__title-main"><strong>Zoom Slideshow</strong> inspired by <a href="https://www.laurenbamford.com/">Lauren Bamford</a></h1> 
				</div>
				<nav class="frame__demos">
					<span>Demos: </span>
					<a href="index.html" class="frame__demo">1</a>
					<span class="frame__demo frame__demo--current">2</span>
				</nav>
				<span class="frame__credits">
					<a href="http://tympanus.net/Development/OnScrollTypoAnimations/">Previous demo</a>
					<a href="https://tympanus.net/codrops/?p=72565">Article</a>
				</span>
			</div>
			<div class="slider">
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/1.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/2.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/3.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/4.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/5.jpg)"></div></div>
			</div>
			<nav class="slider-nav">
				<button class="unbutton slider-nav__item slider-nav__item--prev"><span>Prev</span></button>
				<button class="unbutton slider-nav__item slider-nav__item--next"><span>Next</span></button>
			</nav>
		</main>
		<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/Observer.min.js"></script>
		<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
		<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
		<script type="module" src="js/demo2/index.js"></script>
	</body>
</html>
ZoomSlideshow/js/demo1/index.js
파일 저장

// Import the Slider class from the slider.js module
import { Slider } from './slider.js';

// Define an object containing navigation controls for the slider
const navigation = {
	'next': document.querySelector('.slider-nav > .slider-nav__item--next'),
	'prev': document.querySelector('.slider-nav > .slider-nav__item--prev')
};

// Instantiate a new Slider object, passing the DOM element with the .slider class as the target
const slider = new Slider(document.querySelector('.slider'));

const initializeSlider = () => {
	// Define the navigate function to call the appropriate Slider method based on the action parameter (next or prev)
	const navigate = action => slider[action](); 

	// Add click event listeners to the navigation controls, calling the navigate function with the appropriate action
	navigation.next.addEventListener('click', () => navigate('next'));
	navigation.prev.addEventListener('click', () => navigate('prev'));

	// Create an (GSAP) Observer to handle wheel, touch, scroll, and pointer events
	// Trigger the navigate function accordingly to navigate through the slider
	Observer.create({
		target: window,
		type: 'wheel,touch,scroll,pointer',
		onUp : () => navigate('next'), 
		onDown : () => navigate('prev'),
		wheelSpeed: -1
	});
};

// Check if the total number of slides is less than 3, and return early if so
if (slider.slidesTotal >= 3) {
    initializeSlider();
} 
else {
    console.log('Not enough slides. Exiting...');
}

// Preload background images of the slider items
// Once all images are loaded, remove the 'loading' class from the body element
imagesLoaded(document.querySelectorAll('.slider__item-inner'), {background: true}, () => document.body.classList.remove('loading'));
ZoomSlideshow/js/demo1/slider.js
파일 저장

// Slider class definition for managing a slideshow
export class Slider {
	DOM = {
		el: null
	};
	// Define a private property to store the current slide index
	#current = 0;

	// Constructor accepts a DOM element representing the slider
	constructor(DOM_el) {
		this.DOM.el = DOM_el;
		
		// Create an array of all slides
		this.slides = [...this.DOM.el.querySelectorAll('.slider__item')];
		
		// Calculate the total number of slides
		this.slidesTotal = this.slides.length;

		// Set the current slide's class to 'slider__item--current'
		this.slides[this.current].classList.add('slider__item--current');
		
		// Set the previous slide's class to 'slider__item--previous'
		this.slides[this.getPreviousPosition()].classList.add('slider__item--previous');
	}
	
	// Method to get the index of the previous slide
	getPreviousPosition() {
		return this.current != 0 ? this.current - 1 : this.slidesTotal - 1;
	}
	
	// Method to get the index of the slide before the previous slide
	getPreviousPreviousPosition() {
		const position = this.getPreviousPosition();
		return position != 0 ? position-1 : this.slidesTotal - 1;
	}
	
	// Method to get the index of the next slide
	getNextPosition() {
		return this.current != this.slidesTotal - 1 ? this.current + 1 : 0;
	}
	
	// Method to navigate to the next slide
	next() {
		this.navigate(1);
	}
	
	// Method to navigate to the previous slide
	prev() {
		this.navigate(0);
	}
	
	// Getter for the current slide index
	get current() {
		return this.#current;
	}
	
	// Setter for the current slide index
	set current(value) {
		this.#current = value;
	}
	
	// Method to navigate the slider in the given direction (1 for next, 0 for previous)
	navigate(direction) {
		
		// Return early if an animation is in progress
		if ( this.isAnimating ) return false;
		this.isAnimating = true;
		
		// Define variables to reference the current, next, previous, and slide before previous slide
		const currentSlide = this.slides[this.current];
		const nextSlide = this.slides[this.getNextPosition()];
		const previousSlide = this.slides[this.getPreviousPosition()];
		const previousPreviousSlide = this.slides[this.getPreviousPreviousPosition()];
		
		// Animate the slider navigation using GSAP
		const tl = gsap.timeline({
			defaults: {
				duration: 1.1, 
				ease: 'expo.inOut'
			},
			onStart: () => {
				if ( !direction ) {
					gsap.set(previousPreviousSlide, {opacity: 1, scale: 1});
				}

				// Set z-indexes for proper layering
				const incomingSlide = direction ? nextSlide : previousSlide;
				// Reset slides z-indexes
				gsap.set(this.slides, {zIndex: 0, willChange: 'transform, opacity'});
				gsap.set(incomingSlide, {zIndex: direction ? 3 : 2});
				gsap.set(currentSlide, {zIndex: direction ? 2 : 3});
				gsap.set(direction ? previousSlide : previousPreviousSlide, {zIndex: 1});
			},
			onComplete: () => {
				// Update classes for current and previous slides based on direction
				currentSlide.classList.remove('slider__item--current');
				previousSlide.classList.remove('slider__item--previous');
				(direction ? nextSlide : previousSlide).classList.add('slider__item--current');
				(direction ? currentSlide : previousPreviousSlide).classList.add('slider__item--previous');

				// Set the isAnimating property to false, indicating that the animation is complete
				this.isAnimating = false;
			}
		})
		.to(currentSlide, {
			scale: direction
		})
		.fromTo(direction ? nextSlide : previousSlide, {
			scale: direction ? 0 : 1,
			opacity: 1
		}, {
			scale: 0.3
		}, 0)

		// Update the current slide index based on the navigation direction
		this.current = direction ? this.getNextPosition() : this.getPreviousPosition();
	}
}
ZoomSlideshow/js/demo2/index.js
파일 저장

// Import the Slider class from the slider.js module
import { Slider } from './slider2.js';

// Define an object containing navigation controls for the slider
const navigation = {
	'next': document.querySelector('.slider-nav > .slider-nav__item--next'),
	'prev': document.querySelector('.slider-nav > .slider-nav__item--prev')
};

// Instantiate a new Slider object, passing the DOM element with the .slider class as the target
const slider = new Slider(document.querySelector('.slider'));

const initializeSlider = () => {
	// Define the navigate function to call the appropriate Slider method based on the action parameter (next or prev)
	const navigate = action => slider[action](); 

	// Add click event listeners to the navigation controls, calling the navigate function with the appropriate action
	navigation.next.addEventListener('click', () => navigate('next'));
	navigation.prev.addEventListener('click', () => navigate('prev'));

	// Create an (GSAP) Observer to handle wheel, touch, scroll, and pointer events
	// Trigger the navigate function accordingly to navigate through the slider
	Observer.create({
		target: window,
		type: 'wheel,touch,scroll,pointer',
		onUp : () => navigate('next'), 
		onDown : () => navigate('prev'),
		wheelSpeed: -1
	});
};

// Check if the total number of slides is less than 3, and return early if so
if (slider.slidesTotal >= 3) {
    initializeSlider();
} 
else {
    console.log('Not enough slides. Exiting...');
}

// Preload background images of the slider items
// Once all images are loaded, remove the 'loading' class from the body element
imagesLoaded(document.querySelectorAll('.slider__item-inner'), {background: true}, () => document.body.classList.remove('loading'));
ZoomSlideshow/js/demo2/slider2.js
파일 저장

// Slider class definition for managing a slideshow
export class Slider {
	DOM = {
		el: null
	};
	// Define a private property to store the current slide index
	#current = 0;

	// Constructor accepts a DOM element representing the slider
	constructor(DOM_el) {
		this.DOM.el = DOM_el;
		gsap.set(this.DOM.el, {perspective: 500});
		// Create an array of all slides
		this.slides = [...this.DOM.el.querySelectorAll('.slider__item')];
		
		// Calculate the total number of slides
		this.slidesTotal = this.slides.length;

		// Set the current slide's class to 'slider__item--current'
		this.slides[this.current].classList.add('slider__item--current');
		
		// Set the previous slide's class to 'slider__item--previous'
		this.slides[this.getPreviousPosition()].classList.add('slider__item--previous');
	}
	
	// Method to get the index of the previous slide
	getPreviousPosition() {
		return this.current != 0 ? this.current - 1 : this.slidesTotal - 1;
	}
	
	// Method to get the index of the slide before the previous slide
	getPreviousPreviousPosition() {
		const position = this.getPreviousPosition();
		return position != 0 ? position-1 : this.slidesTotal - 1;
	}
	
	// Method to get the index of the next slide
	getNextPosition() {
		return this.current != this.slidesTotal - 1 ? this.current + 1 : 0;
	}
	
	// Method to navigate to the next slide
	next() {
		this.navigate(1);
	}
	
	// Method to navigate to the previous slide
	prev() {
		this.navigate(0);
	}
	
	// Getter for the current slide index
	get current() {
		return this.#current;
	}
	
	// Setter for the current slide index
	set current(value) {
		this.#current = value;
	}
	
	// Method to navigate the slider in the given direction (1 for next, 0 for previous)
	navigate(direction) {
		
		// Return early if an animation is in progress
		if ( this.isAnimating ) return false;
		this.isAnimating = true;
		
		// Define variables to reference the current, next, previous, and slide before previous slide
		const currentSlide = this.slides[this.current];
		const nextSlide = this.slides[this.getNextPosition()];
		const previousSlide = this.slides[this.getPreviousPosition()];
		const previousPreviousSlide = this.slides[this.getPreviousPreviousPosition()];
		
        // Next slide's inner image
        const nextSlideInner = nextSlide.querySelector('.slider__item-inner')

		// Animate the slider navigation using GSAP
		const tl = gsap.timeline({
			defaults: {
				duration: 1, 
				ease: 'power4.inOut'
			},
			onStart: () => {
				if ( !direction ) {
					gsap.set(previousPreviousSlide, {opacity: 1, scale: 1});
				}

				// Set z-indexes for proper layering
				const incomingSlide = direction ? nextSlide : previousSlide;
				// Reset slides z-indexes and rotations
				gsap.set(this.slides, {zIndex: 0, rotationX: 0, willChange: 'transform, opacity'});
				gsap.set(incomingSlide, {zIndex: direction ? 3 : 2});
				gsap.set(currentSlide, {zIndex: direction ? 2 : 3});
				gsap.set(direction ? previousSlide : previousPreviousSlide, {zIndex: 1});
			},
			onComplete: () => {
				// Update classes for current and previous slides based on direction
				currentSlide.classList.remove('slider__item--current');
				previousSlide.classList.remove('slider__item--previous');
				(direction ? nextSlide : previousSlide).classList.add('slider__item--current');
				(direction ? currentSlide : previousPreviousSlide).classList.add('slider__item--previous');

				// Set the isAnimating property to false, indicating that the animation is complete
				this.isAnimating = false;
			}
		})
		.to(currentSlide, {
			scale: direction,
			rotationX: () => !direction ? -90 : 0
		})
		.fromTo(direction ? nextSlide : previousSlide, {
			scale: direction ? 0 : 1,
			rotationX: () => direction ? -90 : 0,
			opacity: 1,
		}, {
			duration: 0.8,
			ease: 'expo',
			scale: 0.3,
			rotationX: 0
		}, 0.5)

		// Animate the inner image too if direction is 'next'
		if ( direction ) {
			tl.fromTo(nextSlideInner, {
				scale: 2
			}, {
				duration: 0.8,
				ease: 'expo',
				scale: 1,
			}, 0.5)
		}

		// Update the current slide index based on the navigation direction
		this.current = direction ? this.getNextPosition() : this.getPreviousPosition();
	}
}
LICENSE실행 안내·자료
파일 저장

MIT License

Copyright (c) 2009 - 2022 [Codrops](https://tympanus.net/codrops)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Bundled dependency licenses실행 안내·자료
파일 저장

https://cdn.jsdelivr.net/npm/splitting@1.1.0/LICENSE.md
MIT License

Copyright (c) 2018 Stephen Shaw

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


https://cdn.jsdelivr.net/npm/imagesloaded@5.0.0/LICENSE.md
Copyright (c) 2011-2022 [David DeSandro](https://desandro.com) and [contributors](https://github.com/desandro/imagesloaded/graphs/contributors)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


GSAP standard license snapshot
Source: https://gsap.com/community/standard-license/
Retrieved: 2026-09-22T04:22:49.089Z
Original distribution copyright and version headers remain in the runtime code.

Standard "No Charge" GSAP License

 I. DEFINITIONS

 “GSAP License” means the terms and conditions of this GSAP Software License Agreement.

 "GSAP Products" means any Software made available at gsap.com (https://gsap.com) or any successor sites, including but not limited to the GSAP animation library and related plugins, tools, or extensions.

 "Permitted Uses" means the implementation and/or use of GSAP Products on any website, web application, or digital interface by any person or entity (which may include, for clarity, those of companies that compete with Webflow in other areas of business).

 "Prohibited Uses" means any implementation and/or use of GSAP Products in tools that allow users to build visual animations without code that encourages, induces, or materially assists in creating a solution that competes with Webflow’s visual animation building capabilities.

 "Competitive Products" means any software, tool, or service that enables users to create, edit, or manage animations through a visual interface or builder similar to Webflow (https://webflow.com).

 II. GRANT OF LICENSE

 Subject to the terms and conditions of this GSAP License, Webflow grants you a non-exclusive, worldwide license to use, reproduce, display, and implement GSAP Products solely for Permitted Uses.

 III. RESTRICTIONS

 You may not:

 Use any GSAP Products for any Prohibited Uses without prior written consent;

 Reverse engineer any GSAP Products for the purpose of creating Competitive Products;

 Remove or alter any proprietary notices or branding from GSAP Products.

 IV. OWNERSHIP AND INTELLECTUAL PROPERTY

 All intellectual property rights in GSAP Products, including but not limited to copyright, patents, trademarks, and trade secrets, remain the exclusive property of Webflow. This GSAP License does not transfer any ownership rights in GSAP Products to you.

 V. TERMINATION

 Webflow may terminate this GSAP License and revoke your access in its discretion if you fail to comply with any of these terms and conditions. Upon termination, you must cease all use of GSAP Products and destroy all copies in your possession.

 VI. MISCELLANEOUS PROVISIONS

 General: This GSAP License is incorporated into and subject to Webflow’s Terms of Service available here (https://webflow.com/legal/terms) ("Terms of Service"). In the event of any conflict or inconsistency between this GSAP License and the Terms of Service, the terms of this GSAP License shall govern in relation to your use of any GSAP Products.

 Amendments: Webflow reserves the right to update or modify this GSAP License at any time by posting the revised terms on this website, provided that any such updates or modifications shall not result in any material degradation to the security, integrity, or functionality of any GSAP Products. You understand and agree that your continued use of any GSAP Products after such revisions to this GSAP License constitutes your acceptance of this GSAP License as revised. If you do not accept the revised GSAP License, you are prohibited from using versions of the GSAP Products released after the effective date of the revised GSAP License (as well as any updates made to previous versions). Notwithstanding, you may continue using previous versions of GSAP Products under the applicable terms licensed to you prior to the effective date of the revised GSAP License (for clarity, excluding any updates made thereto).

 No Waiver: Failure of Webflow to enforce any provision of this GSAP License shall not constitute a waiver of future enforcement of that or any other provision.

 FAQ

 Is it acceptable for AI tools like ChatGPT, Cursor, Lovable, Webstudio, etc. to generate GSAP code?
 Absolutely! AI-generated code is not a "Prohibited Use".

 What if a WordPress plugin or theme or other niche tool allows users to create GSAP-driven effects through a visual interface? Is that prohibited?
 We want to encourage developers to build on top of GSAP, including visual tools that don't directly compete with Webflow's rich animation-building capabilities. If you are not sure if your product might be considered a "Prohibited Use", feel free to contact us (https://gsap.com/contact) so we can talk through it!

 Can I really use GSAP in commercial projects without paying anything?
 Yes, really! Commercial usage is covered under the standard license. All of GSAP including the plugins that were formerly "members-only" like SplitText (https://gsap.com/docs/v3/Plugins/SplitText/) and MorphSVG (https://gsap.com/docs/v3/Plugins/MorphSVGPlugin) can be used in commercial projects at no charge. Enjoy! 💚

 Effective date: April 30, 2025

 Last modified date: May 30, 2025

 Copyright (©) 2025, Webflow

LineTypeEffect/css/base.css
파일 저장

*,
*::after,
*::before {
	box-sizing: border-box;
}

:root {
	font-size: 16px;
	--color-text: #fff;
	--color-text-alt: #302c31;
	--color-bg: #1e1b1f;
	--color-link: #fff;
	--color-link-hover: #fff;
}

body {
	margin: 0;
	color: var(--color-text);
	background-color: var(--color-bg);
	font-family: area-normal,-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	width: 100%;
	overflow-x: hidden;
}

/* Page Loader */
.js .loading::before,
.js .loading::after {
	content: '';
	position: fixed;
	z-index: 1000;
}

.js .loading::before {
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: var(--color-bg);
}

.js .loading::after {
	top: 50%;
	left: 50%;
	width: 60px;
	height: 60px;
	margin: -30px 0 0 -30px;
	border-radius: 50%;
	opacity: 0.4;
	background: var(--color-link);
	animation: loaderAnim 0.7s linear infinite alternate forwards;

}

@keyframes loaderAnim {
	to {
		opacity: 1;
		transform: scale3d(0.5,0.5,1);
	}
}

a {
	text-decoration: none;
	color: var(--color-link);
	outline: none;
	cursor: pointer;
}

a:hover {
	color: var(--color-link-hover);
	outline: none;
}

/* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
a:focus {
	/* Provide a fallback style for browsers
	 that don't support :focus-visible */
	outline: none;
	background: lightgrey;
}

a:focus:not(:focus-visible) {
	/* Remove the focus indicator on mouse-focus for browsers
	 that do support :focus-visible */
	background: transparent;
}

a:focus-visible {
	/* Draw a very noticeable focus style for
	 keyboard-focus on browsers that do support
	 :focus-visible */
	outline: 2px solid red;
	background: transparent;
}

.unbutton {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	cursor: pointer;
}

.unbutton:focus {
	outline: none;
}

.frame {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	color: var(--color-title);
	padding: 1rem;
	font-size: 13px;
	font-weight: 600;
	display: grid;
	grid-template-columns: 100%;
	grid-template-areas: 'title' 'credits' 'sponsor';
	justify-content: start;
	align-content: space-between;
	align-items: start;
	z-index: 100;
	pointer-events: none;
	grid-gap: 0.5rem;
}

.frame a {
	pointer-events: auto;
}

.frame a:not(.frame__demo) {
	white-space: nowrap;
	overflow: hidden;
	position: relative;
}

.frame a:not(.frame__demo)::before {
	content: '';
	height: 1px;
	width: 100%;
	background: currentColor;
	position: absolute;
	top: 90%;
	transition: transform 0.3s;
	transform-origin: 0% 50%;
}

.frame a:not(.frame__demo):hover::before {
	transform: scaleX(0);
	transform-origin: 100% 50%;
}

.frame__title {
	grid-area: title;
	display: flex;
	align-items: flex-end;
}

.frame strong {
	font-weight: 800;
}

.frame__title-main {
	font-size: inherit;
	margin: 0;
	font-weight: inherit;
}

.frame__credits {
	grid-area: credits;
	display: flex;
	gap: 1rem;
}

main {
	counter-reset: section;
}

.content {
	display: flex;
	flex-direction: column;
	width: 100vw;
	height: 100vh;
	justify-content: center;
	position: relative;
	align-items: center;
}

.content::before {
	counter-increment: section; 
	content: "Effect No. " counter(section);
	font-weight: 800;
	font-size: 1rem;
	margin-bottom: 10vh;
	text-transform: uppercase;
	color: var(--color-text-alt);
	z-index: -1;
}

.linetype {
	position: relative;
	display: grid;
	place-items: center;	
	margin: 0;
	cursor: default;
}

.linetype__text {
	line-height: 1;
	font-size: 10vw;
	grid-area: 1 / -1;
	font-weight: 400;
	pointer-events: none;
}

.linetype__line {
	width: 100%;
	height: var(--thickness-line);
	background: var(--color-line);
	grid-area: 1 / -1;
	transform-origin: 0% 50%;
	transform: scale3d(0,1,1);
	pointer-events: none;
}

.linetype--1 {
	--thickness-line: 10px;
	--color-line: #5714bd;
}

.linetype--2 {
	--thickness-line: 18px;
	--color-line: #ee8120;
}

.linetype--3 {
	--thickness-line: 2px;
	--color-line: #7f6cba;
}

.linetype--4 {
	--thickness-line: 5px;
	--color-line: linear-gradient(to right, #8415e2, blue);
}

.linetype--5 {
	--thickness-line: 2px;
	--color-line: #f1f1f1;
}

.linetype--6 {
	overflow: hidden;
	--thickness-line: 11vh;
	--color-line: #de4010;
	--color-line: linear-gradient(to left, #de4010, #10debe);
}

.linetype--7 {
	--thickness-line: 18px;
	--color-line: hsl(321deg 82% 50% / 88%);
}

.linetype--8 {
	--thickness-line: 30px;
	--color-line: #e9b563;
}

.char-wrap {
	display: inline-block;
	position: relative;
	overflow: hidden;
}

.font-1 {
	color: #463ba0;
	text-transform: uppercase;
	font-family: "owners-xxwide", sans-serif;
	font-weight: 700;
	font-size: 8vw;
}

.font-2 {
	font-size: 15vw;
	color: #f7d859;
	font-family: "jetlab-variable", sans-serif;
	font-variation-settings: "LIFT" 0, "HORZ" 0, "VERT" 34, "THRU" 50;
	text-shadow: 0 0 5px rgba(0,0,0,0.5);
}

.font-3 {
	font-size: 14vw;
	color: #bc77cf;
	font-family: "zuume-edge", sans-serif;
	font-weight: 400;
	font-style: normal;
	text-transform: uppercase;
}

.font-4 {
	color: #b5a1ed;
	font-family: "goldich", sans-serif;
	font-weight: 400;
	font-style: normal;
}

.font-5 {
	text-transform: uppercase;
	font-family: "cc-deadline-open-variable", sans-serif;
	font-variation-settings: "slnt" 0, "wdth" 50;
}

.font-6 {
	font-family: "lulo-outline", sans-serif;
	color: #c54c26;
	font-weight: 700;
	font-style: normal;
	font-size: 6vw;
	letter-spacing: -0.15em;
	line-height: 0.7;
    padding-top: 0.2em;
}

.font-7 {
	padding: 0 0.25em;
	font-family: "magno-sans-variable", sans-serif;
	font-variation-settings: "wght" 775;
}

.font-8 {
	font-family: "owners-xxwide", sans-serif;
	color: beige;
	font-weight: 700;
	font-size: 8vw;
}

@media screen and (min-width: 53em) {
	.frame { 
		height: 100vh; 
		grid-gap: 2rem;
		grid-template-columns: auto 1fr;
		grid-template-rows: auto auto;
		grid-template-areas: 'title sponsor' 'credits ... ';
	}
	.frame__demos {
		justify-self: end;
	}
}
LineTypeEffect/css/splitting-cells.css
파일 저장

.splitting.cells img { width: 100%; display: block; }

@supports ( display: grid ) {
  .splitting.cells {
    position: relative;
    overflow: hidden;
    background-size: cover;
    visibility: hidden;
  }

  .splitting .cell-grid {
    background: inherit;
    position: absolute;
    top: 0; 
    left: 0; 
    width: 100%; 
    height: 100%;
    display: grid;
    grid-template: repeat( var(--row-total), 1fr ) / repeat( var(--col-total), 1fr );
  }

  .splitting .cell {
    background: inherit;
    position: relative;
    overflow: hidden;
  }

  .splitting .cell-inner {
    background: inherit;
    position: absolute;
    visibility: visible;
    /* Size to fit the whole container size */
    width: calc(100% * var(--col-total));
    height: calc(100% * var(--row-total));
    /* Position properly */
    left: calc(-100% * var(--col-index));
    top: calc(-100% * var(--row-index));
  }

  /* Helper variables for advanced effects */
  .splitting .cell {
    --center-x: calc((var(--col-total) - 1) / 2);
    --center-y: calc((var(--row-total) - 1) / 2);

    /* Offset from center, positive & negative */
    --offset-x: calc(var(--col-index) - var(--center-x));
    --offset-y: calc(var(--row-index) - var(--center-y));

    /* Absolute distance from center, only positive */
    --distance-x: calc( (var(--offset-x) * var(--offset-x)) / var(--center-x) );

    /* Absolute distance from center, only positive */
    --distance-y: calc( (var(--offset-y) * var(--offset-y)) / var(--center-y) );
  }
}
LineTypeEffect/css/splitting.css
파일 저장

/* Recommended styles for Splitting */
.splitting .word,
.splitting .char {
  display: inline-block;
}

/* Psuedo-element chars */
.splitting .char {
  position: relative;
}

/**
 * Populate the psuedo elements with the character to allow for expanded effects
 * Set to `display: none` by default; just add `display: block` when you want
 * to use the psuedo elements
 */
.splitting .char::before,
.splitting .char::after {
  content: attr(data-char);
  position: absolute;
  top: 0;
  left: 0;
  visibility: hidden;
  transition: inherit;
  user-select: none;
}

/* Expanded CSS Variables */

.splitting {
  /* The center word index */
  --word-center: calc((var(--word-total) - 1) / 2);

  /* The center character index */
  --char-center: calc((var(--char-total) - 1) / 2);

  /* The center character index */
  --line-center: calc((var(--line-total) - 1) / 2);
}

.splitting .word {
  /* Pecent (0-1) of the word's position */
  --word-percent: calc(var(--word-index) / var(--word-total));

  /* Pecent (0-1) of the line's position */
  --line-percent: calc(var(--line-index) / var(--line-total));
}

.splitting .char {
  /* Percent (0-1) of the char's position */
  --char-percent: calc(var(--char-index) / var(--char-total));

  /* Offset from center, positive & negative */
  --char-offset: calc(var(--char-index) - var(--char-center));

  /* Absolute distance from center, only positive */
  --distance: calc(
     (var(--char-offset) * var(--char-offset)) / var(--char-center)
  );

  /* Distance from center where -1 is the far left, 0 is center, 1 is far right */
  --distance-sine: calc(var(--char-offset) / var(--char-center));

  /* Distance from center where 1 is far left/far right, 0 is center */
  --distance-percent: calc((var(--distance) / var(--char-center)));
}
LineTypeEffect/index.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Line & Letter Hover Animations | Codrops</title>
		<meta name="author" content="Codrops" />
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="stylesheet" href="https://use.typekit.net/jyx5rut.css">
		<link rel="stylesheet" type="text/css" href="css/base.css" />
		<link rel="stylesheet" href="css/splitting.css" />
		<link rel="stylesheet" href="css/splitting-cells.css" />
		<script>document.documentElement.className="js";</script>
		<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
	</head>
	<body>
		<main>
			<div class="frame">
				<div class="frame__title"> 
					<h1 class="frame__title-main"><strong>Line &amp; Letter Hover Animations</strong></h1> 
				</div>
				<span class="frame__credits">
					<a href="http://tympanus.net/Development/ZoomSlideshow/">Previous demo</a>
					<a href="https://tympanus.net/codrops/?p=72565">Article</a>
				</span>
			</div>
			<section class="content">
				<h2 class="linetype linetype--1">
					<span class="linetype__text font-1" data-splitting>Ebullient</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--2">
					<span class="linetype__text font-2" data-splitting>Eudaimonic</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--3">
					<span class="linetype__text font-3" data-splitting>Gregarious</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--4">
					<span class="linetype__text font-4" data-splitting>Sagacious</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--5">
					<span class="linetype__text font-5" data-splitting>Bulletproof</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--6">
					<span class="linetype__text font-6" data-splitting>Unflappable</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--7">
					<span class="linetype__text font-7" data-splitting>Indefatigable</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
			<section class="content">
				<h2 class="linetype linetype--8" data-charWrap>
					<span class="linetype__text font-8" data-splitting>Urbane</span>
					<div class="linetype__line"></div>
				</h2>
			</section>
		</main>
		<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
		<script src="js/gsap.min.js"></script>
		<script src="js/splitting.min.js"></script>
		<script type="module" src="js/index.js"></script>
	</body>
</html>
LineTypeEffect/js/gsap.min.js
파일 저장

/*!
 * GSAP 3.11.5
 * https://greensock.com
 * 
 * @license Copyright 2023, GreenSock. All rights reserved.
 * Subject to the terms at https://greensock.com/standard-license or for Club GreenSock members, the agreement issued with that membership.
 * @author: Jack Doyle, jack@greensock.com
 */

!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t=t||self).window=t.window||{})}(this,function(e){"use strict";function _inheritsLoose(t,e){t.prototype=Object.create(e.prototype),(t.prototype.constructor=t).__proto__=e}function _assertThisInitialized(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}function r(t){return"string"==typeof t}function s(t){return"function"==typeof t}function t(t){return"number"==typeof t}function u(t){return void 0===t}function v(t){return"object"==typeof t}function w(t){return!1!==t}function x(){return"undefined"!=typeof window}function y(t){return s(t)||r(t)}function P(t){return(i=yt(t,ot))&&Pe}function Q(t,e){return console.warn("Invalid property",t,"set to",e,"Missing plugin? gsap.registerPlugin()")}function R(t,e){return!e&&console.warn(t)}function S(t,e){return t&&(ot[t]=e)&&i&&(i[t]=e)||ot}function T(){return 0}function ea(t){var e,r,i=t[0];if(v(i)||s(i)||(t=[t]),!(e=(i._gsap||{}).harness)){for(r=gt.length;r--&&!gt[r].targetTest(i););e=gt[r]}for(r=t.length;r--;)t[r]&&(t[r]._gsap||(t[r]._gsap=new qt(t[r],e)))||t.splice(r,1);return t}function fa(t){return t._gsap||ea(Mt(t))[0]._gsap}function ga(t,e,r){return(r=t[e])&&s(r)?t[e]():u(r)&&t.getAttribute&&t.getAttribute(e)||r}function ha(t,e){return(t=t.split(",")).forEach(e)||t}function ia(t){return Math.round(1e5*t)/1e5||0}function ja(t){return Math.round(1e7*t)/1e7||0}function ka(t,e){var r=e.charAt(0),i=parseFloat(e.substr(2));return t=parseFloat(t),"+"===r?t+i:"-"===r?t-i:"*"===r?t*i:t/i}function la(t,e){for(var r=e.length,i=0;t.indexOf(e[i])<0&&++i<r;);return i<r}function ma(){var t,e,r=ct.length,i=ct.slice(0);for(dt={},t=ct.length=0;t<r;t++)(e=i[t])&&e._lazy&&(e.render(e._lazy[0],e._lazy[1],!0)._lazy=0)}function na(t,e,r,i){ct.length&&!B&&ma(),t.render(e,r,i||B&&e<0&&(t._initted||t._startAt)),ct.length&&!B&&ma()}function oa(t){var e=parseFloat(t);return(e||0===e)&&(t+"").match(at).length<2?e:r(t)?t.trim():t}function pa(t){return t}function qa(t,e){for(var r in e)r in t||(t[r]=e[r]);return t}function ta(t,e){for(var r in e)"__proto__"!==r&&"constructor"!==r&&"prototype"!==r&&(t[r]=v(e[r])?ta(t[r]||(t[r]={}),e[r]):e[r]);return t}function ua(t,e){var r,i={};for(r in t)r in e||(i[r]=t[r]);return i}function va(t){var e=t.parent||L,r=t.keyframes?function _setKeyframeDefaults(i){return function(t,e){for(var r in e)r in t||"duration"===r&&i||"ease"===r||(t[r]=e[r])}}(Z(t.keyframes)):qa;if(w(t.inherit))for(;e;)r(t,e.vars.defaults),e=e.parent||e._dp;return t}function xa(t,e,r,i,n){void 0===r&&(r="_first"),void 0===i&&(i="_last");var a,s=t[i];if(n)for(a=e[n];s&&s[n]>a;)s=s._prev;return s?(e._next=s._next,s._next=e):(e._next=t[r],t[r]=e),e._next?e._next._prev=e:t[i]=e,e._prev=s,e.parent=e._dp=t,e}function ya(t,e,r,i){void 0===r&&(r="_first"),void 0===i&&(i="_last");var n=e._prev,a=e._next;n?n._next=a:t[r]===e&&(t[r]=a),a?a._prev=n:t[i]===e&&(t[i]=n),e._next=e._prev=e.parent=null}function za(t,e){!t.parent||e&&!t.parent.autoRemoveChildren||t.parent.remove(t),t._act=0}function Aa(t,e){if(t&&(!e||e._end>t._dur||e._start<0))for(var r=t;r;)r._dirty=1,r=r.parent;return t}function Ca(t,e,r,i){return t._startAt&&(B?t._startAt.revert(ht):t.vars.immediateRender&&!t.vars.autoRevert||t._startAt.render(e,!0,i))}function Ea(t){return t._repeat?Tt(t._tTime,t=t.duration()+t._rDelay)*t:0}function Ga(t,e){return(t-e._start)*e._ts+(0<=e._ts?0:e._dirty?e.totalDuration():e._tDur)}function Ha(t){return t._end=ja(t._start+(t._tDur/Math.abs(t._ts||t._rts||X)||0))}function Ia(t,e){var r=t._dp;return r&&r.smoothChildTiming&&t._ts&&(t._start=ja(r._time-(0<t._ts?e/t._ts:((t._dirty?t.totalDuration():t._tDur)-e)/-t._ts)),Ha(t),r._dirty||Aa(r,t)),t}function Ja(t,e){var r;if((e._time||e._initted&&!e._dur)&&(r=Ga(t.rawTime(),e),(!e._dur||Ot(0,e.totalDuration(),r)-e._tTime>X)&&e.render(r,!0)),Aa(t,e)._dp&&t._initted&&t._time>=t._dur&&t._ts){if(t._dur<t.duration())for(r=t;r._dp;)0<=r.rawTime()&&r.totalTime(r._tTime),r=r._dp;t._zTime=-X}}function Ka(e,r,i,n){return r.parent&&za(r),r._start=ja((t(i)?i:i||e!==L?xt(e,i,r):e._time)+r._delay),r._end=ja(r._start+(r.totalDuration()/Math.abs(r.timeScale())||0)),xa(e,r,"_first","_last",e._sort?"_start":0),bt(r)||(e._recent=r),n||Ja(e,r),e._ts<0&&Ia(e,e._tTime),e}function La(t,e){return(ot.ScrollTrigger||Q("scrollTrigger",e))&&ot.ScrollTrigger.create(e,t)}function Ma(t,e,r,i,n){return Kt(t,e,n),t._initted?!r&&t._pt&&!B&&(t._dur&&!1!==t.vars.lazy||!t._dur&&t.vars.lazy)&&f!==Rt.frame?(ct.push(t),t._lazy=[n,i],1):void 0:1}function Ra(t,e,r,i){var n=t._repeat,a=ja(e)||0,s=t._tTime/t._tDur;return s&&!i&&(t._time*=a/t._dur),t._dur=a,t._tDur=n?n<0?1e10:ja(a*(n+1)+t._rDelay*n):a,0<s&&!i&&Ia(t,t._tTime=t._tDur*s),t.parent&&Ha(t),r||Aa(t.parent,t),t}function Sa(t){return t instanceof Xt?Aa(t):Ra(t,t._dur)}function Va(e,r,i){var n,a,s=t(r[1]),o=(s?2:1)+(e<2?0:1),u=r[o];if(s&&(u.duration=r[1]),u.parent=i,e){for(n=u,a=i;a&&!("immediateRender"in n);)n=a.vars.defaults||{},a=w(a.vars.inherit)&&a.parent;u.immediateRender=w(n.immediateRender),e<2?u.runBackwards=1:u.startAt=r[o-1]}return new Jt(r[0],u,r[1+o])}function Wa(t,e){return t||0===t?e(t):e}function Ya(t,e){return r(t)&&(e=st.exec(t))?e[1]:""}function _a(t,e){return t&&v(t)&&"length"in t&&(!e&&!t.length||t.length-1 in t&&v(t[0]))&&!t.nodeType&&t!==h}function cb(r){return r=Mt(r)[0]||R("Invalid scope")||{},function(t){var e=r.current||r.nativeElement||r;return Mt(t,e.querySelectorAll?e:e===r?R("Invalid scope")||a.createElement("div"):r)}}function db(t){return t.sort(function(){return.5-Math.random()})}function eb(t){if(s(t))return t;var p=v(t)?t:{each:t},_=jt(p.ease),m=p.from||0,g=parseFloat(p.base)||0,y={},e=0<m&&m<1,T=isNaN(m)||e,b=p.axis,w=m,x=m;return r(m)?w=x={center:.5,edges:.5,end:1}[m]||0:!e&&T&&(w=m[0],x=m[1]),function(t,e,r){var i,n,a,s,o,u,h,l,f,c=(r||p).length,d=y[c];if(!d){if(!(f="auto"===p.grid?0:(p.grid||[1,U])[1])){for(h=-U;h<(h=r[f++].getBoundingClientRect().left)&&f<c;);f--}for(d=y[c]=[],i=T?Math.min(f,c)*w-.5:m%f,n=f===U?0:T?c*x/f-.5:m/f|0,l=U,u=h=0;u<c;u++)a=u%f-i,s=n-(u/f|0),d[u]=o=b?Math.abs("y"===b?s:a):G(a*a+s*s),h<o&&(h=o),o<l&&(l=o);"random"===m&&db(d),d.max=h-l,d.min=l,d.v=c=(parseFloat(p.amount)||parseFloat(p.each)*(c<f?c-1:b?"y"===b?c/f:f:Math.max(f,c/f))||0)*("edges"===m?-1:1),d.b=c<0?g-c:g,d.u=Ya(p.amount||p.each)||0,_=_&&c<0?Yt(_):_}return c=(d[t]-d.min)/d.max||0,ja(d.b+(_?_(c):c)*d.v)+d.u}}function fb(i){var n=Math.pow(10,((i+"").split(".")[1]||"").length);return function(e){var r=ja(Math.round(parseFloat(e)/i)*i*n);return(r-r%1)/n+(t(e)?0:Ya(e))}}function gb(h,e){var l,f,r=Z(h);return!r&&v(h)&&(l=r=h.radius||U,h.values?(h=Mt(h.values),(f=!t(h[0]))&&(l*=l)):h=fb(h.increment)),Wa(e,r?s(h)?function(t){return f=h(t),Math.abs(f-t)<=l?f:t}:function(e){for(var r,i,n=parseFloat(f?e.x:e),a=parseFloat(f?e.y:0),s=U,o=0,u=h.length;u--;)(r=f?(r=h[u].x-n)*r+(i=h[u].y-a)*i:Math.abs(h[u]-n))<s&&(s=r,o=u);return o=!l||s<=l?h[o]:e,f||o===e||t(e)?o:o+Ya(e)}:fb(h))}function hb(t,e,r,i){return Wa(Z(t)?!e:!0===r?!!(r=0):!i,function(){return Z(t)?t[~~(Math.random()*t.length)]:(r=r||1e-5)&&(i=r<1?Math.pow(10,(r+"").length-2):1)&&Math.floor(Math.round((t-r/2+Math.random()*(e-t+.99*r))/r)*r*i)/i})}function lb(e,r,t){return Wa(t,function(t){return e[~~r(t)]})}function ob(t){for(var e,r,i,n,a=0,s="";~(e=t.indexOf("random(",a));)i=t.indexOf(")",e),n="["===t.charAt(e+7),r=t.substr(e+7,i-e-7).match(n?at:tt),s+=t.substr(a,e-a)+hb(n?r:+r[0],n?0:+r[1],+r[2]||1e-5),a=i+1;return s+t.substr(a,t.length-a)}function rb(t,e,r){var i,n,a,s=t.labels,o=U;for(i in s)(n=s[i]-e)<0==!!r&&n&&o>(n=Math.abs(n))&&(a=i,o=n);return a}function tb(t){return za(t),t.scrollTrigger&&t.scrollTrigger.kill(!!B),t.progress()<1&&St(t,"onInterrupt"),t}function wb(t){if(x()){var e=(t=!t.name&&t.default||t).name,r=s(t),i=e&&!r&&t.init?function(){this._props=[]}:t,n={init:T,render:fe,add:Qt,kill:_e,modifier:pe,rawVars:0},a={targetTest:0,get:0,getSetter:re,aliases:{},register:0};if(Ft(),t!==i){if(pt[e])return;qa(i,qa(ua(t,n),a)),yt(i.prototype,yt(n,ua(t,a))),pt[i.prop=e]=i,t.targetTest&&(gt.push(i),ft[e]=1),e=("css"===e?"CSS":e.charAt(0).toUpperCase()+e.substr(1))+"Plugin"}S(e,i),t.register&&t.register(Pe,i,ge)}else Ct.push(t)}function zb(t,e,r){return(6*(t+=t<0?1:1<t?-1:0)<1?e+(r-e)*t*6:t<.5?r:3*t<2?e+(r-e)*(2/3-t)*6:e)*Pt+.5|0}function Ab(e,r,i){var n,a,s,o,u,h,l,f,c,d,p=e?t(e)?[e>>16,e>>8&Pt,e&Pt]:0:Dt.black;if(!p){if(","===e.substr(-1)&&(e=e.substr(0,e.length-1)),Dt[e])p=Dt[e];else if("#"===e.charAt(0)){if(e.length<6&&(e="#"+(n=e.charAt(1))+n+(a=e.charAt(2))+a+(s=e.charAt(3))+s+(5===e.length?e.charAt(4)+e.charAt(4):"")),9===e.length)return[(p=parseInt(e.substr(1,6),16))>>16,p>>8&Pt,p&Pt,parseInt(e.substr(7),16)/255];p=[(e=parseInt(e.substr(1),16))>>16,e>>8&Pt,e&Pt]}else if("hsl"===e.substr(0,3))if(p=d=e.match(tt),r){if(~e.indexOf("="))return p=e.match(et),i&&p.length<4&&(p[3]=1),p}else o=+p[0]%360/360,u=p[1]/100,n=2*(h=p[2]/100)-(a=h<=.5?h*(u+1):h+u-h*u),3<p.length&&(p[3]*=1),p[0]=zb(o+1/3,n,a),p[1]=zb(o,n,a),p[2]=zb(o-1/3,n,a);else p=e.match(tt)||Dt.transparent;p=p.map(Number)}return r&&!d&&(n=p[0]/Pt,a=p[1]/Pt,s=p[2]/Pt,h=((l=Math.max(n,a,s))+(f=Math.min(n,a,s)))/2,l===f?o=u=0:(c=l-f,u=.5<h?c/(2-l-f):c/(l+f),o=l===n?(a-s)/c+(a<s?6:0):l===a?(s-n)/c+2:(n-a)/c+4,o*=60),p[0]=~~(o+.5),p[1]=~~(100*u+.5),p[2]=~~(100*h+.5)),i&&p.length<4&&(p[3]=1),p}function Bb(t){var r=[],i=[],n=-1;return t.split(Et).forEach(function(t){var e=t.match(rt)||[];r.push.apply(r,e),i.push(n+=e.length+1)}),r.c=i,r}function Cb(t,e,r){var i,n,a,s,o="",u=(t+o).match(Et),h=e?"hsla(":"rgba(",l=0;if(!u)return t;if(u=u.map(function(t){return(t=Ab(t,e,1))&&h+(e?t[0]+","+t[1]+"%,"+t[2]+"%,"+t[3]:t.join(","))+")"}),r&&(a=Bb(t),(i=r.c).join(o)!==a.c.join(o)))for(s=(n=t.replace(Et,"1").split(rt)).length-1;l<s;l++)o+=n[l]+(~i.indexOf(l)?u.shift()||h+"0,0,0,0)":(a.length?a:u.length?u:r).shift());if(!n)for(s=(n=t.split(Et)).length-1;l<s;l++)o+=n[l]+u[l];return o+n[s]}function Fb(t){var e,r=t.join(" ");if(Et.lastIndex=0,Et.test(r))return e=zt.test(r),t[1]=Cb(t[1],e),t[0]=Cb(t[0],e,Bb(t[1])),!0}function Ob(t){var e=(t+"").split("("),r=It[e[0]];return r&&1<e.length&&r.config?r.config.apply(null,~t.indexOf("{")?[function _parseObjectInString(t){for(var e,r,i,n={},a=t.substr(1,t.length-3).split(":"),s=a[0],o=1,u=a.length;o<u;o++)r=a[o],e=o!==u-1?r.lastIndexOf(","):r.length,i=r.substr(0,e),n[s]=isNaN(i)?i.replace(Lt,"").trim():+i,s=r.substr(e+1).trim();return n}(e[1])]:function _valueInParentheses(t){var e=t.indexOf("(")+1,r=t.indexOf(")"),i=t.indexOf("(",e);return t.substring(e,~i&&i<r?t.indexOf(")",r+1):r)}(t).split(",").map(oa)):It._CE&&Bt.test(t)?It._CE("",t):r}function Qb(t,e){for(var r,i=t._first;i;)i instanceof Xt?Qb(i,e):!i.vars.yoyoEase||i._yoyo&&i._repeat||i._yoyo===e||(i.timeline?Qb(i.timeline,e):(r=i._ease,i._ease=i._yEase,i._yEase=r,i._yoyo=e)),i=i._next}function Sb(t,e,r,i){void 0===r&&(r=function easeOut(t){return 1-e(1-t)}),void 0===i&&(i=function easeInOut(t){return t<.5?e(2*t)/2:1-e(2*(1-t))/2});var n,a={easeIn:e,easeOut:r,easeInOut:i};return ha(t,function(t){for(var e in It[t]=ot[t]=a,It[n=t.toLowerCase()]=r,a)It[n+("easeIn"===e?".in":"easeOut"===e?".out":".inOut")]=It[t+"."+e]=a[e]}),a}function Tb(e){return function(t){return t<.5?(1-e(1-2*t))/2:.5+e(2*(t-.5))/2}}function Ub(r,t,e){function Im(t){return 1===t?1:i*Math.pow(2,-10*t)*H((t-a)*n)+1}var i=1<=t?t:1,n=(e||(r?.3:.45))/(t<1?t:1),a=n/N*(Math.asin(1/i)||0),s="out"===r?Im:"in"===r?function(t){return 1-Im(1-t)}:Tb(Im);return n=N/n,s.config=function(t,e){return Ub(r,t,e)},s}function Vb(e,r){function Qm(t){return t?--t*t*((r+1)*t+r)+1:0}void 0===r&&(r=1.70158);var t="out"===e?Qm:"in"===e?function(t){return 1-Qm(1-t)}:Tb(Qm);return t.config=function(t){return Vb(e,t)},t}var I,B,l,L,h,n,a,i,o,f,c,d,p,_,m,g,b,O,k,M,A,C,D,E,z,F,Y,j,V={autoSleep:120,force3D:"auto",nullTargetWarn:1,units:{lineHeight:""}},q={duration:.5,overwrite:!1,delay:0},U=1e8,X=1/U,N=2*Math.PI,W=N/4,K=0,G=Math.sqrt,$=Math.cos,H=Math.sin,J="function"==typeof ArrayBuffer&&ArrayBuffer.isView||function(){},Z=Array.isArray,tt=/(?:-?\.?\d|\.)+/gi,et=/[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g,rt=/[-+=.]*\d+[.e-]*\d*[a-z%]*/g,it=/[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi,nt=/[+-]=-?[.\d]+/,at=/[^,'"\[\]\s]+/gi,st=/^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i,ot={},ut={suppressEvents:!0,isStart:!0,kill:!1},ht={suppressEvents:!0,kill:!1},lt={suppressEvents:!0},ft={},ct=[],dt={},pt={},_t={},mt=30,gt=[],vt="",yt=function _merge(t,e){for(var r in e)t[r]=e[r];return t},Tt=function _animationCycle(t,e){var r=Math.floor(t/=e);return t&&r===t?r-1:r},bt=function _isFromOrFromStart(t){var e=t.data;return"isFromStart"===e||"isStart"===e},wt={_start:0,endTime:T,totalDuration:T},xt=function _parsePosition(t,e,i){var n,a,s,o=t.labels,u=t._recent||wt,h=t.duration()>=U?u.endTime(!1):t._dur;return r(e)&&(isNaN(e)||e in o)?(a=e.charAt(0),s="%"===e.substr(-1),n=e.indexOf("="),"<"===a||">"===a?(0<=n&&(e=e.replace(/=/,"")),("<"===a?u._start:u.endTime(0<=u._repeat))+(parseFloat(e.substr(1))||0)*(s?(n<0?u:i).totalDuration()/100:1)):n<0?(e in o||(o[e]=h),o[e]):(a=parseFloat(e.charAt(n-1)+e.substr(n+1)),s&&i&&(a=a/100*(Z(i)?i[0]:i).totalDuration()),1<n?_parsePosition(t,e.substr(0,n-1),i)+a:h+a)):null==e?h:+e},Ot=function _clamp(t,e,r){return r<t?t:e<r?e:r},kt=[].slice,Mt=function toArray(t,e,i){return l&&!e&&l.selector?l.selector(t):!r(t)||i||!n&&Ft()?Z(t)?function _flatten(t,e,i){return void 0===i&&(i=[]),t.forEach(function(t){return r(t)&&!e||_a(t,1)?i.push.apply(i,Mt(t)):i.push(t)})||i}(t,i):_a(t)?kt.call(t,0):t?[t]:[]:kt.call((e||a).querySelectorAll(t),0)},At=function mapRange(e,t,r,i,n){var a=t-e,s=i-r;return Wa(n,function(t){return r+((t-e)/a*s||0)})},St=function _callback(t,e,r){var i,n,a,s=t.vars,o=s[e],u=l,h=t._ctx;if(o)return i=s[e+"Params"],n=s.callbackScope||t,r&&ct.length&&ma(),h&&(l=h),a=i?o.apply(n,i):o.call(n),l=u,a},Ct=[],Pt=255,Dt={aqua:[0,Pt,Pt],lime:[0,Pt,0],silver:[192,192,192],black:[0,0,0],maroon:[128,0,0],teal:[0,128,128],blue:[0,0,Pt],navy:[0,0,128],white:[Pt,Pt,Pt],olive:[128,128,0],yellow:[Pt,Pt,0],orange:[Pt,165,0],gray:[128,128,128],purple:[128,0,128],green:[0,128,0],red:[Pt,0,0],pink:[Pt,192,203],cyan:[0,Pt,Pt],transparent:[Pt,Pt,Pt,0]},Et=function(){var t,e="(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b";for(t in Dt)e+="|"+t+"\\b";return new RegExp(e+")","gi")}(),zt=/hsl[a]?\(/,Rt=(k=Date.now,M=500,A=33,C=k(),D=C,z=E=1e3/240,g={time:0,frame:0,tick:function tick(){xl(!0)},deltaRatio:function deltaRatio(t){return b/(1e3/(t||60))},wake:function wake(){o&&(!n&&x()&&(h=n=window,a=h.document||{},ot.gsap=Pe,(h.gsapVersions||(h.gsapVersions=[])).push(Pe.version),P(i||h.GreenSockGlobals||!h.gsap&&h||{}),m=h.requestAnimationFrame,Ct.forEach(wb)),p&&g.sleep(),_=m||function(t){return setTimeout(t,z-1e3*g.time+1|0)},d=1,xl(2))},sleep:function sleep(){(m?h.cancelAnimationFrame:clearTimeout)(p),d=0,_=T},lagSmoothing:function lagSmoothing(t,e){M=t||1/0,A=Math.min(e||33,M)},fps:function fps(t){E=1e3/(t||240),z=1e3*g.time+E},add:function add(n,t,e){var a=t?function(t,e,r,i){n(t,e,r,i),g.remove(a)}:n;return g.remove(n),F[e?"unshift":"push"](a),Ft(),a},remove:function remove(t,e){~(e=F.indexOf(t))&&F.splice(e,1)&&e<=O&&O--},_listeners:F=[]}),Ft=function _wake(){return!d&&Rt.wake()},It={},Bt=/^[\d.\-M][\d.\-,\s]/,Lt=/["']/g,Yt=function _invertEase(e){return function(t){return 1-e(1-t)}},jt=function _parseEase(t,e){return t&&(s(t)?t:It[t]||Ob(t))||e};function xl(t){var e,r,i,n,a=k()-D,s=!0===t;if(M<a&&(C+=a-A),(0<(e=(i=(D+=a)-C)-z)||s)&&(n=++g.frame,b=i-1e3*g.time,g.time=i/=1e3,z+=e+(E<=e?4:E-e),r=1),s||(p=_(xl)),r)for(O=0;O<F.length;O++)F[O](i,b,n,t)}function fn(t){return t<j?Y*t*t:t<.7272727272727273?Y*Math.pow(t-1.5/2.75,2)+.75:t<.9090909090909092?Y*(t-=2.25/2.75)*t+.9375:Y*Math.pow(t-2.625/2.75,2)+.984375}ha("Linear,Quad,Cubic,Quart,Quint,Strong",function(t,e){var r=e<5?e+1:e;Sb(t+",Power"+(r-1),e?function(t){return Math.pow(t,r)}:function(t){return t},function(t){return 1-Math.pow(1-t,r)},function(t){return t<.5?Math.pow(2*t,r)/2:1-Math.pow(2*(1-t),r)/2})}),It.Linear.easeNone=It.none=It.Linear.easeIn,Sb("Elastic",Ub("in"),Ub("out"),Ub()),Y=7.5625,j=1/2.75,Sb("Bounce",function(t){return 1-fn(1-t)},fn),Sb("Expo",function(t){return t?Math.pow(2,10*(t-1)):0}),Sb("Circ",function(t){return-(G(1-t*t)-1)}),Sb("Sine",function(t){return 1===t?1:1-$(t*W)}),Sb("Back",Vb("in"),Vb("out"),Vb()),It.SteppedEase=It.steps=ot.SteppedEase={config:function config(t,e){void 0===t&&(t=1);var r=1/t,i=t+(e?0:1),n=e?1:0;return function(t){return((i*Ot(0,.99999999,t)|0)+n)*r}}},q.ease=It["quad.out"],ha("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt",function(t){return vt+=t+","+t+"Params,"});var Vt,qt=function GSCache(t,e){this.id=K++,(t._gsap=this).target=t,this.harness=e,this.get=e?e.get:ga,this.set=e?e.getSetter:re},Ut=((Vt=Animation.prototype).delay=function delay(t){return t||0===t?(this.parent&&this.parent.smoothChildTiming&&this.startTime(this._start+t-this._delay),this._delay=t,this):this._delay},Vt.duration=function duration(t){return arguments.length?this.totalDuration(0<this._repeat?t+(t+this._rDelay)*this._repeat:t):this.totalDuration()&&this._dur},Vt.totalDuration=function totalDuration(t){return arguments.length?(this._dirty=0,Ra(this,this._repeat<0?t:(t-this._repeat*this._rDelay)/(this._repeat+1))):this._tDur},Vt.totalTime=function totalTime(t,e){if(Ft(),!arguments.length)return this._tTime;var r=this._dp;if(r&&r.smoothChildTiming&&this._ts){for(Ia(this,t),!r._dp||r.parent||Ja(r,this);r&&r.parent;)r.parent._time!==r._start+(0<=r._ts?r._tTime/r._ts:(r.totalDuration()-r._tTime)/-r._ts)&&r.totalTime(r._tTime,!0),r=r.parent;!this.parent&&this._dp.autoRemoveChildren&&(0<this._ts&&t<this._tDur||this._ts<0&&0<t||!this._tDur&&!t)&&Ka(this._dp,this,this._start-this._delay)}return(this._tTime!==t||!this._dur&&!e||this._initted&&Math.abs(this._zTime)===X||!t&&!this._initted&&(this.add||this._ptLookup))&&(this._ts||(this._pTime=t),na(this,t,e)),this},Vt.time=function time(t,e){return arguments.length?this.totalTime(Math.min(this.totalDuration(),t+Ea(this))%(this._dur+this._rDelay)||(t?this._dur:0),e):this._time},Vt.totalProgress=function totalProgress(t,e){return arguments.length?this.totalTime(this.totalDuration()*t,e):this.totalDuration()?Math.min(1,this._tTime/this._tDur):this.ratio},Vt.progress=function progress(t,e){return arguments.length?this.totalTime(this.duration()*(!this._yoyo||1&this.iteration()?t:1-t)+Ea(this),e):this.duration()?Math.min(1,this._time/this._dur):this.ratio},Vt.iteration=function iteration(t,e){var r=this.duration()+this._rDelay;return arguments.length?this.totalTime(this._time+(t-1)*r,e):this._repeat?Tt(this._tTime,r)+1:1},Vt.timeScale=function timeScale(t){if(!arguments.length)return this._rts===-X?0:this._rts;if(this._rts===t)return this;var e=this.parent&&this._ts?Ga(this.parent._time,this):this._tTime;return this._rts=+t||0,this._ts=this._ps||t===-X?0:this._rts,this.totalTime(Ot(-Math.abs(this._delay),this._tDur,e),!0),Ha(this),function _recacheAncestors(t){for(var e=t.parent;e&&e.parent;)e._dirty=1,e.totalDuration(),e=e.parent;return t}(this)},Vt.paused=function paused(t){return arguments.length?(this._ps!==t&&((this._ps=t)?(this._pTime=this._tTime||Math.max(-this._delay,this.rawTime()),this._ts=this._act=0):(Ft(),this._ts=this._rts,this.totalTime(this.parent&&!this.parent.smoothChildTiming?this.rawTime():this._tTime||this._pTime,1===this.progress()&&Math.abs(this._zTime)!==X&&(this._tTime-=X)))),this):this._ps},Vt.startTime=function startTime(t){if(arguments.length){this._start=t;var e=this.parent||this._dp;return!e||!e._sort&&this.parent||Ka(e,this,t-this._delay),this}return this._start},Vt.endTime=function endTime(t){return this._start+(w(t)?this.totalDuration():this.duration())/Math.abs(this._ts||1)},Vt.rawTime=function rawTime(t){var e=this.parent||this._dp;return e?t&&(!this._ts||this._repeat&&this._time&&this.totalProgress()<1)?this._tTime%(this._dur+this._rDelay):this._ts?Ga(e.rawTime(t),this):this._tTime:this._tTime},Vt.revert=function revert(t){void 0===t&&(t=lt);var e=B;return B=t,(this._initted||this._startAt)&&(this.timeline&&this.timeline.revert(t),this.totalTime(-.01,t.suppressEvents)),"nested"!==this.data&&!1!==t.kill&&this.kill(),B=e,this},Vt.globalTime=function globalTime(t){for(var e=this,r=arguments.length?t:e.rawTime();e;)r=e._start+r/(e._ts||1),e=e._dp;return!this.parent&&this._sat?this._sat.vars.immediateRender?-1:this._sat.globalTime(t):r},Vt.repeat=function repeat(t){return arguments.length?(this._repeat=t===1/0?-2:t,Sa(this)):-2===this._repeat?1/0:this._repeat},Vt.repeatDelay=function repeatDelay(t){if(arguments.length){var e=this._time;return this._rDelay=t,Sa(this),e?this.time(e):this}return this._rDelay},Vt.yoyo=function yoyo(t){return arguments.length?(this._yoyo=t,this):this._yoyo},Vt.seek=function seek(t,e){return this.totalTime(xt(this,t),w(e))},Vt.restart=function restart(t,e){return this.play().totalTime(t?-this._delay:0,w(e))},Vt.play=function play(t,e){return null!=t&&this.seek(t,e),this.reversed(!1).paused(!1)},Vt.reverse=function reverse(t,e){return null!=t&&this.seek(t||this.totalDuration(),e),this.reversed(!0).paused(!1)},Vt.pause=function pause(t,e){return null!=t&&this.seek(t,e),this.paused(!0)},Vt.resume=function resume(){return this.paused(!1)},Vt.reversed=function reversed(t){return arguments.length?(!!t!==this.reversed()&&this.timeScale(-this._rts||(t?-X:0)),this):this._rts<0},Vt.invalidate=function invalidate(){return this._initted=this._act=0,this._zTime=-X,this},Vt.isActive=function isActive(){var t,e=this.parent||this._dp,r=this._start;return!(e&&!(this._ts&&this._initted&&e.isActive()&&(t=e.rawTime(!0))>=r&&t<this.endTime(!0)-X))},Vt.eventCallback=function eventCallback(t,e,r){var i=this.vars;return 1<arguments.length?(e?(i[t]=e,r&&(i[t+"Params"]=r),"onUpdate"===t&&(this._onUpdate=e)):delete i[t],this):i[t]},Vt.then=function then(t){var i=this;return new Promise(function(e){function Ao(){var t=i.then;i.then=null,s(r)&&(r=r(i))&&(r.then||r===i)&&(i.then=t),e(r),i.then=t}var r=s(t)?t:pa;i._initted&&1===i.totalProgress()&&0<=i._ts||!i._tTime&&i._ts<0?Ao():i._prom=Ao})},Vt.kill=function kill(){tb(this)},Animation);function Animation(t){this.vars=t,this._delay=+t.delay||0,(this._repeat=t.repeat===1/0?-2:t.repeat||0)&&(this._rDelay=t.repeatDelay||0,this._yoyo=!!t.yoyo||!!t.yoyoEase),this._ts=1,Ra(this,+t.duration,1,1),this.data=t.data,l&&(this._ctx=l).data.push(this),d||Rt.wake()}qa(Ut.prototype,{_time:0,_start:0,_end:0,_tTime:0,_tDur:0,_dirty:0,_repeat:0,_yoyo:!1,parent:null,_initted:!1,_rDelay:0,_ts:1,_dp:0,ratio:0,_zTime:-X,_prom:0,_ps:!1,_rts:1});var Xt=function(i){function Timeline(t,e){var r;return void 0===t&&(t={}),(r=i.call(this,t)||this).labels={},r.smoothChildTiming=!!t.smoothChildTiming,r.autoRemoveChildren=!!t.autoRemoveChildren,r._sort=w(t.sortChildren),L&&Ka(t.parent||L,_assertThisInitialized(r),e),t.reversed&&r.reverse(),t.paused&&r.paused(!0),t.scrollTrigger&&La(_assertThisInitialized(r),t.scrollTrigger),r}_inheritsLoose(Timeline,i);var e=Timeline.prototype;return e.to=function to(t,e,r){return Va(0,arguments,this),this},e.from=function from(t,e,r){return Va(1,arguments,this),this},e.fromTo=function fromTo(t,e,r,i){return Va(2,arguments,this),this},e.set=function set(t,e,r){return e.duration=0,e.parent=this,va(e).repeatDelay||(e.repeat=0),e.immediateRender=!!e.immediateRender,new Jt(t,e,xt(this,r),1),this},e.call=function call(t,e,r){return Ka(this,Jt.delayedCall(0,t,e),r)},e.staggerTo=function staggerTo(t,e,r,i,n,a,s){return r.duration=e,r.stagger=r.stagger||i,r.onComplete=a,r.onCompleteParams=s,r.parent=this,new Jt(t,r,xt(this,n)),this},e.staggerFrom=function staggerFrom(t,e,r,i,n,a,s){return r.runBackwards=1,va(r).immediateRender=w(r.immediateRender),this.staggerTo(t,e,r,i,n,a,s)},e.staggerFromTo=function staggerFromTo(t,e,r,i,n,a,s,o){return i.startAt=r,va(i).immediateRender=w(i.immediateRender),this.staggerTo(t,e,i,n,a,s,o)},e.render=function render(t,e,r){var i,n,a,s,o,u,h,l,f,c,d,p,_=this._time,m=this._dirty?this.totalDuration():this._tDur,g=this._dur,v=t<=0?0:ja(t),y=this._zTime<0!=t<0&&(this._initted||!g);if(this!==L&&m<v&&0<=t&&(v=m),v!==this._tTime||r||y){if(_!==this._time&&g&&(v+=this._time-_,t+=this._time-_),i=v,f=this._start,u=!(l=this._ts),y&&(g||(_=this._zTime),!t&&e||(this._zTime=t)),this._repeat){if(d=this._yoyo,o=g+this._rDelay,this._repeat<-1&&t<0)return this.totalTime(100*o+t,e,r);if(i=ja(v%o),v===m?(s=this._repeat,i=g):((s=~~(v/o))&&s===v/o&&(i=g,s--),g<i&&(i=g)),c=Tt(this._tTime,o),!_&&this._tTime&&c!==s&&this._tTime-c*o-this._dur<=0&&(c=s),d&&1&s&&(i=g-i,p=1),s!==c&&!this._lock){var T=d&&1&c,b=T===(d&&1&s);if(s<c&&(T=!T),_=T?0:g,this._lock=1,this.render(_||(p?0:ja(s*o)),e,!g)._lock=0,this._tTime=v,!e&&this.parent&&St(this,"onRepeat"),this.vars.repeatRefresh&&!p&&(this.invalidate()._lock=1),_&&_!==this._time||u!=!this._ts||this.vars.onRepeat&&!this.parent&&!this._act)return this;if(g=this._dur,m=this._tDur,b&&(this._lock=2,_=T?g:-1e-4,this.render(_,!0),this.vars.repeatRefresh&&!p&&this.invalidate()),this._lock=0,!this._ts&&!u)return this;Qb(this,p)}}if(this._hasPause&&!this._forcing&&this._lock<2&&(h=function _findNextPauseTween(t,e,r){var i;if(e<r)for(i=t._first;i&&i._start<=r;){if("isPause"===i.data&&i._start>e)return i;i=i._next}else for(i=t._last;i&&i._start>=r;){if("isPause"===i.data&&i._start<e)return i;i=i._prev}}(this,ja(_),ja(i)))&&(v-=i-(i=h._start)),this._tTime=v,this._time=i,this._act=!l,this._initted||(this._onUpdate=this.vars.onUpdate,this._initted=1,this._zTime=t,_=0),!_&&i&&!e&&!s&&(St(this,"onStart"),this._tTime!==v))return this;if(_<=i&&0<=t)for(n=this._first;n;){if(a=n._next,(n._act||i>=n._start)&&n._ts&&h!==n){if(n.parent!==this)return this.render(t,e,r);if(n.render(0<n._ts?(i-n._start)*n._ts:(n._dirty?n.totalDuration():n._tDur)+(i-n._start)*n._ts,e,r),i!==this._time||!this._ts&&!u){h=0,a&&(v+=this._zTime=-X);break}}n=a}else{n=this._last;for(var w=t<0?t:i;n;){if(a=n._prev,(n._act||w<=n._end)&&n._ts&&h!==n){if(n.parent!==this)return this.render(t,e,r);if(n.render(0<n._ts?(w-n._start)*n._ts:(n._dirty?n.totalDuration():n._tDur)+(w-n._start)*n._ts,e,r||B&&(n._initted||n._startAt)),i!==this._time||!this._ts&&!u){h=0,a&&(v+=this._zTime=w?-X:X);break}}n=a}}if(h&&!e&&(this.pause(),h.render(_<=i?0:-X)._zTime=_<=i?1:-1,this._ts))return this._start=f,Ha(this),this.render(t,e,r);this._onUpdate&&!e&&St(this,"onUpdate",!0),(v===m&&this._tTime>=this.totalDuration()||!v&&_)&&(f!==this._start&&Math.abs(l)===Math.abs(this._ts)||this._lock||(!t&&g||!(v===m&&0<this._ts||!v&&this._ts<0)||za(this,1),e||t<0&&!_||!v&&!_&&m||(St(this,v===m&&0<=t?"onComplete":"onReverseComplete",!0),!this._prom||v<m&&0<this.timeScale()||this._prom())))}return this},e.add=function add(e,i){var n=this;if(t(i)||(i=xt(this,i,e)),!(e instanceof Ut)){if(Z(e))return e.forEach(function(t){return n.add(t,i)}),this;if(r(e))return this.addLabel(e,i);if(!s(e))return this;e=Jt.delayedCall(0,e)}return this!==e?Ka(this,e,i):this},e.getChildren=function getChildren(t,e,r,i){void 0===t&&(t=!0),void 0===e&&(e=!0),void 0===r&&(r=!0),void 0===i&&(i=-U);for(var n=[],a=this._first;a;)a._start>=i&&(a instanceof Jt?e&&n.push(a):(r&&n.push(a),t&&n.push.apply(n,a.getChildren(!0,e,r)))),a=a._next;return n},e.getById=function getById(t){for(var e=this.getChildren(1,1,1),r=e.length;r--;)if(e[r].vars.id===t)return e[r]},e.remove=function remove(t){return r(t)?this.removeLabel(t):s(t)?this.killTweensOf(t):(ya(this,t),t===this._recent&&(this._recent=this._last),Aa(this))},e.totalTime=function totalTime(t,e){return arguments.length?(this._forcing=1,!this._dp&&this._ts&&(this._start=ja(Rt.time-(0<this._ts?t/this._ts:(this.totalDuration()-t)/-this._ts))),i.prototype.totalTime.call(this,t,e),this._forcing=0,this):this._tTime},e.addLabel=function addLabel(t,e){return this.labels[t]=xt(this,e),this},e.removeLabel=function removeLabel(t){return delete this.labels[t],this},e.addPause=function addPause(t,e,r){var i=Jt.delayedCall(0,e||T,r);return i.data="isPause",this._hasPause=1,Ka(this,i,xt(this,t))},e.removePause=function removePause(t){var e=this._first;for(t=xt(this,t);e;)e._start===t&&"isPause"===e.data&&za(e),e=e._next},e.killTweensOf=function killTweensOf(t,e,r){for(var i=this.getTweensOf(t,r),n=i.length;n--;)Nt!==i[n]&&i[n].kill(t,e);return this},e.getTweensOf=function getTweensOf(e,r){for(var i,n=[],a=Mt(e),s=this._first,o=t(r);s;)s instanceof Jt?la(s._targets,a)&&(o?(!Nt||s._initted&&s._ts)&&s.globalTime(0)<=r&&s.globalTime(s.totalDuration())>r:!r||s.isActive())&&n.push(s):(i=s.getTweensOf(a,r)).length&&n.push.apply(n,i),s=s._next;return n},e.tweenTo=function tweenTo(t,e){e=e||{};var r,i=this,n=xt(i,t),a=e.startAt,s=e.onStart,o=e.onStartParams,u=e.immediateRender,h=Jt.to(i,qa({ease:e.ease||"none",lazy:!1,immediateRender:!1,time:n,overwrite:"auto",duration:e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale())||X,onStart:function onStart(){if(i.pause(),!r){var t=e.duration||Math.abs((n-(a&&"time"in a?a.time:i._time))/i.timeScale());h._dur!==t&&Ra(h,t,0,1).render(h._time,!0,!0),r=1}s&&s.apply(h,o||[])}},e));return u?h.render(0):h},e.tweenFromTo=function tweenFromTo(t,e,r){return this.tweenTo(e,qa({startAt:{time:xt(this,t)}},r))},e.recent=function recent(){return this._recent},e.nextLabel=function nextLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t))},e.previousLabel=function previousLabel(t){return void 0===t&&(t=this._time),rb(this,xt(this,t),1)},e.currentLabel=function currentLabel(t){return arguments.length?this.seek(t,!0):this.previousLabel(this._time+X)},e.shiftChildren=function shiftChildren(t,e,r){void 0===r&&(r=0);for(var i,n=this._first,a=this.labels;n;)n._start>=r&&(n._start+=t,n._end+=t),n=n._next;if(e)for(i in a)a[i]>=r&&(a[i]+=t);return Aa(this)},e.invalidate=function invalidate(t){var e=this._first;for(this._lock=0;e;)e.invalidate(t),e=e._next;return i.prototype.invalidate.call(this,t)},e.clear=function clear(t){void 0===t&&(t=!0);for(var e,r=this._first;r;)e=r._next,this.remove(r),r=e;return this._dp&&(this._time=this._tTime=this._pTime=0),t&&(this.labels={}),Aa(this)},e.totalDuration=function totalDuration(t){var e,r,i,n=0,a=this,s=a._last,o=U;if(arguments.length)return a.timeScale((a._repeat<0?a.duration():a.totalDuration())/(a.reversed()?-t:t));if(a._dirty){for(i=a.parent;s;)e=s._prev,s._dirty&&s.totalDuration(),o<(r=s._start)&&a._sort&&s._ts&&!a._lock?(a._lock=1,Ka(a,s,r-s._delay,1)._lock=0):o=r,r<0&&s._ts&&(n-=r,(!i&&!a._dp||i&&i.smoothChildTiming)&&(a._start+=r/a._ts,a._time-=r,a._tTime-=r),a.shiftChildren(-r,!1,-Infinity),o=0),s._end>n&&s._ts&&(n=s._end),s=e;Ra(a,a===L&&a._time>n?a._time:n,1,1),a._dirty=0}return a._tDur},Timeline.updateRoot=function updateRoot(t){if(L._ts&&(na(L,Ga(t,L)),f=Rt.frame),Rt.frame>=mt){mt+=V.autoSleep||120;var e=L._first;if((!e||!e._ts)&&V.autoSleep&&Rt._listeners.length<2){for(;e&&!e._ts;)e=e._next;e||Rt.sleep()}}},Timeline}(Ut);qa(Xt.prototype,{_lock:0,_hasPause:0,_forcing:0});function ac(t,e,i,n,a,o){var u,h,l,f;if(pt[t]&&!1!==(u=new pt[t]).init(a,u.rawVars?e[t]:function _processVars(t,e,i,n,a){if(s(t)&&(t=Gt(t,a,e,i,n)),!v(t)||t.style&&t.nodeType||Z(t)||J(t))return r(t)?Gt(t,a,e,i,n):t;var o,u={};for(o in t)u[o]=Gt(t[o],a,e,i,n);return u}(e[t],n,a,o,i),i,n,o)&&(i._pt=h=new ge(i._pt,a,t,0,1,u.render,u,0,u.priority),i!==c))for(l=i._ptLookup[i._targets.indexOf(a)],f=u._props.length;f--;)l[u._props[f]]=h;return u}function gc(t,r,e,i){var n,a,s=r.ease||i||"power1.inOut";if(Z(r))a=e[t]||(e[t]=[]),r.forEach(function(t,e){return a.push({t:e/(r.length-1)*100,v:t,e:s})});else for(n in r)a=e[n]||(e[n]=[]),"ease"===n||a.push({t:parseFloat(t),v:r[n],e:s})}var Nt,Wt,Qt=function _addPropTween(t,e,i,n,a,o,u,h,l,f){s(n)&&(n=n(a||0,t,o));var c,d=t[e],p="get"!==i?i:s(d)?l?t[e.indexOf("set")||!s(t["get"+e.substr(3)])?e:"get"+e.substr(3)](l):t[e]():d,_=s(d)?l?ee:te:Zt;if(r(n)&&(~n.indexOf("random(")&&(n=ob(n)),"="===n.charAt(1)&&(!(c=ka(p,n)+(Ya(p)||0))&&0!==c||(n=c))),!f||p!==n||Wt)return isNaN(p*n)||""===n?(d||e in t||Q(e,n),function _addComplexStringPropTween(t,e,r,i,n,a,s){var o,u,h,l,f,c,d,p,_=new ge(this._pt,t,e,0,1,le,null,n),m=0,g=0;for(_.b=r,_.e=i,r+="",(d=~(i+="").indexOf("random("))&&(i=ob(i)),a&&(a(p=[r,i],t,e),r=p[0],i=p[1]),u=r.match(it)||[];o=it.exec(i);)l=o[0],f=i.substring(m,o.index),h?h=(h+1)%5:"rgba("===f.substr(-5)&&(h=1),l!==u[g++]&&(c=parseFloat(u[g-1])||0,_._pt={_next:_._pt,p:f||1===g?f:",",s:c,c:"="===l.charAt(1)?ka(c,l)-c:parseFloat(l)-c,m:h&&h<4?Math.round:0},m=it.lastIndex);return _.c=m<i.length?i.substring(m,i.length):"",_.fp=s,(nt.test(i)||d)&&(_.e=0),this._pt=_}.call(this,t,e,p,n,_,h||V.stringFilter,l)):(c=new ge(this._pt,t,e,+p||0,n-(p||0),"boolean"==typeof d?oe:se,0,_),l&&(c.fp=l),u&&c.modifier(u,this,t),this._pt=c)},Kt=function _initTween(t,e,r){var i,n,a,s,o,u,h,l,f,c,d,p,_,m=t.vars,g=m.ease,v=m.startAt,y=m.immediateRender,T=m.lazy,b=m.onUpdate,x=m.onUpdateParams,O=m.callbackScope,k=m.runBackwards,M=m.yoyoEase,A=m.keyframes,S=m.autoRevert,C=t._dur,P=t._startAt,D=t._targets,E=t.parent,z=E&&"nested"===E.data?E.vars.targets:D,R="auto"===t._overwrite&&!I,F=t.timeline;if(!F||A&&g||(g="none"),t._ease=jt(g,q.ease),t._yEase=M?Yt(jt(!0===M?g:M,q.ease)):0,M&&t._yoyo&&!t._repeat&&(M=t._yEase,t._yEase=t._ease,t._ease=M),t._from=!F&&!!m.runBackwards,!F||A&&!m.stagger){if(p=(l=D[0]?fa(D[0]).harness:0)&&m[l.prop],i=ua(m,ft),P&&(P._zTime<0&&P.progress(1),e<0&&k&&y&&!S?P.render(-1,!0):P.revert(k&&C?ht:ut),P._lazy=0),v){if(za(t._startAt=Jt.set(D,qa({data:"isStart",overwrite:!1,parent:E,immediateRender:!0,lazy:!P&&w(T),startAt:null,delay:0,onUpdate:b,onUpdateParams:x,callbackScope:O,stagger:0},v))),t._startAt._dp=0,t._startAt._sat=t,e<0&&(B||!y&&!S)&&t._startAt.revert(ht),y&&C&&e<=0&&r<=0)return void(e&&(t._zTime=e))}else if(k&&C&&!P)if(e&&(y=!1),a=qa({overwrite:!1,data:"isFromStart",lazy:y&&!P&&w(T),immediateRender:y,stagger:0,parent:E},i),p&&(a[l.prop]=p),za(t._startAt=Jt.set(D,a)),t._startAt._dp=0,t._startAt._sat=t,e<0&&(B?t._startAt.revert(ht):t._startAt.render(-1,!0)),t._zTime=e,y){if(!e)return}else _initTween(t._startAt,X,X);for(t._pt=t._ptCache=0,T=C&&w(T)||T&&!C,n=0;n<D.length;n++){if(h=(o=D[n])._gsap||ea(D)[n]._gsap,t._ptLookup[n]=c={},dt[h.id]&&ct.length&&ma(),d=z===D?n:z.indexOf(o),l&&!1!==(f=new l).init(o,p||i,t,d,z)&&(t._pt=s=new ge(t._pt,o,f.name,0,1,f.render,f,0,f.priority),f._props.forEach(function(t){c[t]=s}),f.priority&&(u=1)),!l||p)for(a in i)pt[a]&&(f=ac(a,i,t,d,o,z))?f.priority&&(u=1):c[a]=s=Qt.call(t,o,a,"get",i[a],d,z,0,m.stringFilter);t._op&&t._op[n]&&t.kill(o,t._op[n]),R&&t._pt&&(Nt=t,L.killTweensOf(o,c,t.globalTime(e)),_=!t.parent,Nt=0),t._pt&&T&&(dt[h.id]=1)}u&&me(t),t._onInit&&t._onInit(t)}t._onUpdate=b,t._initted=(!t._op||t._pt)&&!_,A&&e<=0&&F.render(U,!0,!0)},Gt=function _parseFuncOrString(t,e,i,n,a){return s(t)?t.call(e,i,n,a):r(t)&&~t.indexOf("random(")?ob(t):t},$t=vt+"repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert",Ht={};ha($t+",id,stagger,delay,duration,paused,scrollTrigger",function(t){return Ht[t]=1});var Jt=function(z){function Tween(e,r,i,n){var a;"number"==typeof r&&(i.duration=r,r=i,i=null);var s,o,u,h,l,f,c,d,p=(a=z.call(this,n?r:va(r))||this).vars,_=p.duration,m=p.delay,g=p.immediateRender,T=p.stagger,b=p.overwrite,x=p.keyframes,O=p.defaults,k=p.scrollTrigger,M=p.yoyoEase,A=r.parent||L,S=(Z(e)||J(e)?t(e[0]):"length"in r)?[e]:Mt(e);if(a._targets=S.length?ea(S):R("GSAP target "+e+" not found. https://greensock.com",!V.nullTargetWarn)||[],a._ptLookup=[],a._overwrite=b,x||T||y(_)||y(m)){if(r=a.vars,(s=a.timeline=new Xt({data:"nested",defaults:O||{},targets:A&&"nested"===A.data?A.vars.targets:S})).kill(),s.parent=s._dp=_assertThisInitialized(a),s._start=0,T||y(_)||y(m)){if(h=S.length,c=T&&eb(T),v(T))for(l in T)~$t.indexOf(l)&&((d=d||{})[l]=T[l]);for(o=0;o<h;o++)(u=ua(r,Ht)).stagger=0,M&&(u.yoyoEase=M),d&&yt(u,d),f=S[o],u.duration=+Gt(_,_assertThisInitialized(a),o,f,S),u.delay=(+Gt(m,_assertThisInitialized(a),o,f,S)||0)-a._delay,!T&&1===h&&u.delay&&(a._delay=m=u.delay,a._start+=m,u.delay=0),s.to(f,u,c?c(o,f,S):0),s._ease=It.none;s.duration()?_=m=0:a.timeline=0}else if(x){va(qa(s.vars.defaults,{ease:"none"})),s._ease=jt(x.ease||r.ease||"none");var C,P,D,E=0;if(Z(x))x.forEach(function(t){return s.to(S,t,">")}),s.duration();else{for(l in u={},x)"ease"===l||"easeEach"===l||gc(l,x[l],u,x.easeEach);for(l in u)for(C=u[l].sort(function(t,e){return t.t-e.t}),o=E=0;o<C.length;o++)(D={ease:(P=C[o]).e,duration:(P.t-(o?C[o-1].t:0))/100*_})[l]=P.v,s.to(S,D,E),E+=D.duration;s.duration()<_&&s.to({},{duration:_-s.duration()})}}_||a.duration(_=s.duration())}else a.timeline=0;return!0!==b||I||(Nt=_assertThisInitialized(a),L.killTweensOf(S),Nt=0),Ka(A,_assertThisInitialized(a),i),r.reversed&&a.reverse(),r.paused&&a.paused(!0),(g||!_&&!x&&a._start===ja(A._time)&&w(g)&&function _hasNoPausedAncestors(t){return!t||t._ts&&_hasNoPausedAncestors(t.parent)}(_assertThisInitialized(a))&&"nested"!==A.data)&&(a._tTime=-X,a.render(Math.max(0,-m)||0)),k&&La(_assertThisInitialized(a),k),a}_inheritsLoose(Tween,z);var e=Tween.prototype;return e.render=function render(t,e,r){var i,n,a,s,o,u,h,l,f,c=this._time,d=this._tDur,p=this._dur,_=t<0,m=d-X<t&&!_?d:t<X?0:t;if(p){if(m!==this._tTime||!t||r||!this._initted&&this._tTime||this._startAt&&this._zTime<0!=_){if(i=m,l=this.timeline,this._repeat){if(s=p+this._rDelay,this._repeat<-1&&_)return this.totalTime(100*s+t,e,r);if(i=ja(m%s),m===d?(a=this._repeat,i=p):((a=~~(m/s))&&a===m/s&&(i=p,a--),p<i&&(i=p)),(u=this._yoyo&&1&a)&&(f=this._yEase,i=p-i),o=Tt(this._tTime,s),i===c&&!r&&this._initted)return this._tTime=m,this;a!==o&&(l&&this._yEase&&Qb(l,u),!this.vars.repeatRefresh||u||this._lock||(this._lock=r=1,this.render(ja(s*a),!0).invalidate()._lock=0))}if(!this._initted){if(Ma(this,_?t:i,r,e,m))return this._tTime=0,this;if(c!==this._time)return this;if(p!==this._dur)return this.render(t,e,r)}if(this._tTime=m,this._time=i,!this._act&&this._ts&&(this._act=1,this._lazy=0),this.ratio=h=(f||this._ease)(i/p),this._from&&(this.ratio=h=1-h),i&&!c&&!e&&!a&&(St(this,"onStart"),this._tTime!==m))return this;for(n=this._pt;n;)n.r(h,n.d),n=n._next;l&&l.render(t<0?t:!i&&u?-X:l._dur*l._ease(i/this._dur),e,r)||this._startAt&&(this._zTime=t),this._onUpdate&&!e&&(_&&Ca(this,t,0,r),St(this,"onUpdate")),this._repeat&&a!==o&&this.vars.onRepeat&&!e&&this.parent&&St(this,"onRepeat"),m!==this._tDur&&m||this._tTime!==m||(_&&!this._onUpdate&&Ca(this,t,0,!0),!t&&p||!(m===this._tDur&&0<this._ts||!m&&this._ts<0)||za(this,1),e||_&&!c||!(m||c||u)||(St(this,m===d?"onComplete":"onReverseComplete",!0),!this._prom||m<d&&0<this.timeScale()||this._prom()))}}else!function _renderZeroDurationTween(t,e,r,i){var n,a,s,o=t.ratio,u=e<0||!e&&(!t._start&&function _parentPlayheadIsBeforeStart(t){var e=t.parent;return e&&e._ts&&e._initted&&!e._lock&&(e.rawTime()<0||_parentPlayheadIsBeforeStart(e))}(t)&&(t._initted||!bt(t))||(t._ts<0||t._dp._ts<0)&&!bt(t))?0:1,h=t._rDelay,l=0;if(h&&t._repeat&&(l=Ot(0,t._tDur,e),a=Tt(l,h),t._yoyo&&1&a&&(u=1-u),a!==Tt(t._tTime,h)&&(o=1-u,t.vars.repeatRefresh&&t._initted&&t.invalidate())),u!==o||B||i||t._zTime===X||!e&&t._zTime){if(!t._initted&&Ma(t,e,i,r,l))return;for(s=t._zTime,t._zTime=e||(r?X:0),r=r||e&&!s,t.ratio=u,t._from&&(u=1-u),t._time=0,t._tTime=l,n=t._pt;n;)n.r(u,n.d),n=n._next;e<0&&Ca(t,e,0,!0),t._onUpdate&&!r&&St(t,"onUpdate"),l&&t._repeat&&!r&&t.parent&&St(t,"onRepeat"),(e>=t._tDur||e<0)&&t.ratio===u&&(u&&za(t,1),r||B||(St(t,u?"onComplete":"onReverseComplete",!0),t._prom&&t._prom()))}else t._zTime||(t._zTime=e)}(this,t,e,r);return this},e.targets=function targets(){return this._targets},e.invalidate=function invalidate(t){return t&&this.vars.runBackwards||(this._startAt=0),this._pt=this._op=this._onUpdate=this._lazy=this.ratio=0,this._ptLookup=[],this.timeline&&this.timeline.invalidate(t),z.prototype.invalidate.call(this,t)},e.resetTo=function resetTo(t,e,r,i){d||Rt.wake(),this._ts||this.play();var n,a=Math.min(this._dur,(this._dp._time-this._start)*this._ts);return this._initted||Kt(this,a),n=this._ease(a/this._dur),function _updatePropTweens(t,e,r,i,n,a,s){var o,u,h,l,f=(t._pt&&t._ptCache||(t._ptCache={}))[e];if(!f)for(f=t._ptCache[e]=[],h=t._ptLookup,l=t._targets.length;l--;){if((o=h[l][e])&&o.d&&o.d._pt)for(o=o.d._pt;o&&o.p!==e&&o.fp!==e;)o=o._next;if(!o)return Wt=1,t.vars[e]="+=0",Kt(t,s),Wt=0,1;f.push(o)}for(l=f.length;l--;)(o=(u=f[l])._pt||u).s=!i&&0!==i||n?o.s+(i||0)+a*o.c:i,o.c=r-o.s,u.e&&(u.e=ia(r)+Ya(u.e)),u.b&&(u.b=o.s+Ya(u.b))}(this,t,e,r,i,n,a)?this.resetTo(t,e,r,i):(Ia(this,0),this.parent||xa(this._dp,this,"_first","_last",this._dp._sort?"_start":0),this.render(0))},e.kill=function kill(t,e){if(void 0===e&&(e="all"),!(t||e&&"all"!==e))return this._lazy=this._pt=0,this.parent?tb(this):this;if(this.timeline){var i=this.timeline.totalDuration();return this.timeline.killTweensOf(t,e,Nt&&!0!==Nt.vars.overwrite)._first||tb(this),this.parent&&i!==this.timeline.totalDuration()&&Ra(this,this._dur*this.timeline._tDur/i,0,1),this}var n,a,s,o,u,h,l,f=this._targets,c=t?Mt(t):f,d=this._ptLookup,p=this._pt;if((!e||"all"===e)&&function _arraysMatch(t,e){for(var r=t.length,i=r===e.length;i&&r--&&t[r]===e[r];);return r<0}(f,c))return"all"===e&&(this._pt=0),tb(this);for(n=this._op=this._op||[],"all"!==e&&(r(e)&&(u={},ha(e,function(t){return u[t]=1}),e=u),e=function _addAliasesToVars(t,e){var r,i,n,a,s=t[0]?fa(t[0]).harness:0,o=s&&s.aliases;if(!o)return e;for(i in r=yt({},e),o)if(i in r)for(n=(a=o[i].split(",")).length;n--;)r[a[n]]=r[i];return r}(f,e)),l=f.length;l--;)if(~c.indexOf(f[l]))for(u in a=d[l],"all"===e?(n[l]=e,o=a,s={}):(s=n[l]=n[l]||{},o=e),o)(h=a&&a[u])&&("kill"in h.d&&!0!==h.d.kill(u)||ya(this,h,"_pt"),delete a[u]),"all"!==s&&(s[u]=1);return this._initted&&!this._pt&&p&&tb(this),this},Tween.to=function to(t,e,r){return new Tween(t,e,r)},Tween.from=function from(t,e){return Va(1,arguments)},Tween.delayedCall=function delayedCall(t,e,r,i){return new Tween(e,0,{immediateRender:!1,lazy:!1,overwrite:!1,delay:t,onComplete:e,onReverseComplete:e,onCompleteParams:r,onReverseCompleteParams:r,callbackScope:i})},Tween.fromTo=function fromTo(t,e,r){return Va(2,arguments)},Tween.set=function set(t,e){return e.duration=0,e.repeatDelay||(e.repeat=0),new Tween(t,e)},Tween.killTweensOf=function killTweensOf(t,e,r){return L.killTweensOf(t,e,r)},Tween}(Ut);qa(Jt.prototype,{_targets:[],_lazy:0,_startAt:0,_op:0,_onInit:0}),ha("staggerTo,staggerFrom,staggerFromTo",function(r){Jt[r]=function(){var t=new Xt,e=kt.call(arguments,0);return e.splice("staggerFromTo"===r?5:4,0,0),t[r].apply(t,e)}});function oc(t,e,r){return t.setAttribute(e,r)}function wc(t,e,r,i){i.mSet(t,e,i.m.call(i.tween,r,i.mt),i)}var Zt=function _setterPlain(t,e,r){return t[e]=r},te=function _setterFunc(t,e,r){return t[e](r)},ee=function _setterFuncWithParam(t,e,r,i){return t[e](i.fp,r)},re=function _getSetter(t,e){return s(t[e])?te:u(t[e])&&t.setAttribute?oc:Zt},se=function _renderPlain(t,e){return e.set(e.t,e.p,Math.round(1e6*(e.s+e.c*t))/1e6,e)},oe=function _renderBoolean(t,e){return e.set(e.t,e.p,!!(e.s+e.c*t),e)},le=function _renderComplexString(t,e){var r=e._pt,i="";if(!t&&e.b)i=e.b;else if(1===t&&e.e)i=e.e;else{for(;r;)i=r.p+(r.m?r.m(r.s+r.c*t):Math.round(1e4*(r.s+r.c*t))/1e4)+i,r=r._next;i+=e.c}e.set(e.t,e.p,i,e)},fe=function _renderPropTweens(t,e){for(var r=e._pt;r;)r.r(t,r.d),r=r._next},pe=function _addPluginModifier(t,e,r,i){for(var n,a=this._pt;a;)n=a._next,a.p===i&&a.modifier(t,e,r),a=n},_e=function _killPropTweensOf(t){for(var e,r,i=this._pt;i;)r=i._next,i.p===t&&!i.op||i.op===t?ya(this,i,"_pt"):i.dep||(e=1),i=r;return!e},me=function _sortPropTweensByPriority(t){for(var e,r,i,n,a=t._pt;a;){for(e=a._next,r=i;r&&r.pr>a.pr;)r=r._next;(a._prev=r?r._prev:n)?a._prev._next=a:i=a,(a._next=r)?r._prev=a:n=a,a=e}t._pt=i},ge=(PropTween.prototype.modifier=function modifier(t,e,r){this.mSet=this.mSet||this.set,this.set=wc,this.m=t,this.mt=r,this.tween=e},PropTween);function PropTween(t,e,r,i,n,a,s,o,u){this.t=e,this.s=i,this.c=n,this.p=r,this.r=a||se,this.d=s||this,this.set=o||Zt,this.pr=u||0,(this._next=t)&&(t._prev=this)}ha(vt+"parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger",function(t){return ft[t]=1}),ot.TweenMax=ot.TweenLite=Jt,ot.TimelineLite=ot.TimelineMax=Xt,L=new Xt({sortChildren:!1,defaults:q,autoRemoveChildren:!0,id:"root",smoothChildTiming:!0}),V.stringFilter=Fb;function Dc(t){return(be[t]||xe).map(function(t){return t()})}function Ec(){var t=Date.now(),o=[];2<t-Oe&&(Dc("matchMediaInit"),Te.forEach(function(t){var e,r,i,n,a=t.queries,s=t.conditions;for(r in a)(e=h.matchMedia(a[r]).matches)&&(i=1),e!==s[r]&&(s[r]=e,n=1);n&&(t.revert(),i&&o.push(t))}),Dc("matchMediaRevert"),o.forEach(function(t){return t.onMatch(t)}),Oe=t,Dc("matchMedia"))}var ye,Te=[],be={},xe=[],Oe=0,Me=((ye=Context.prototype).add=function add(t,i,n){function Dw(){var t,e=l,r=a.selector;return e&&e!==a&&e.data.push(a),n&&(a.selector=cb(n)),l=a,t=i.apply(a,arguments),s(t)&&a._r.push(t),l=e,a.selector=r,a.isReverted=!1,t}s(t)&&(n=i,i=t,t=s);var a=this;return a.last=Dw,t===s?Dw(a):t?a[t]=Dw:Dw},ye.ignore=function ignore(t){var e=l;l=null,t(this),l=e},ye.getTweens=function getTweens(){var e=[];return this.data.forEach(function(t){return t instanceof Context?e.push.apply(e,t.getTweens()):t instanceof Jt&&!(t.parent&&"nested"===t.parent.data)&&e.push(t)}),e},ye.clear=function clear(){this._r.length=this.data.length=0},ye.kill=function kill(e,t){var r=this;if(e){var i=this.getTweens();this.data.forEach(function(t){"isFlip"===t.data&&(t.revert(),t.getChildren(!0,!0,!1).forEach(function(t){return i.splice(i.indexOf(t),1)}))}),i.map(function(t){return{g:t.globalTime(0),t:t}}).sort(function(t,e){return e.g-t.g||-1}).forEach(function(t){return t.t.revert(e)}),this.data.forEach(function(t){return!(t instanceof Ut)&&t.revert&&t.revert(e)}),this._r.forEach(function(t){return t(e,r)}),this.isReverted=!0}else this.data.forEach(function(t){return t.kill&&t.kill()});if(this.clear(),t){var n=Te.indexOf(this);~n&&Te.splice(n,1)}},ye.revert=function revert(t){this.kill(t||{})},Context);function Context(t,e){this.selector=e&&cb(e),this.data=[],this._r=[],this.isReverted=!1,t&&this.add(t)}var Ae,Se=((Ae=MatchMedia.prototype).add=function add(t,e,r){v(t)||(t={matches:t});var i,n,a,s=new Me(0,r||this.scope),o=s.conditions={};for(n in this.contexts.push(s),e=s.add("onMatch",e),s.queries=t)"all"===n?a=1:(i=h.matchMedia(t[n]))&&(Te.indexOf(s)<0&&Te.push(s),(o[n]=i.matches)&&(a=1),i.addListener?i.addListener(Ec):i.addEventListener("change",Ec));return a&&e(s),this},Ae.revert=function revert(t){this.kill(t||{})},Ae.kill=function kill(e){this.contexts.forEach(function(t){return t.kill(e,!0)})},MatchMedia);function MatchMedia(t){this.contexts=[],this.scope=t}var Ce={registerPlugin:function registerPlugin(){for(var t=arguments.length,e=new Array(t),r=0;r<t;r++)e[r]=arguments[r];e.forEach(function(t){return wb(t)})},timeline:function timeline(t){return new Xt(t)},getTweensOf:function getTweensOf(t,e){return L.getTweensOf(t,e)},getProperty:function getProperty(i,t,e,n){r(i)&&(i=Mt(i)[0]);var a=fa(i||{}).get,s=e?pa:oa;return"native"===e&&(e=""),i?t?s((pt[t]&&pt[t].get||a)(i,t,e,n)):function(t,e,r){return s((pt[t]&&pt[t].get||a)(i,t,e,r))}:i},quickSetter:function quickSetter(r,e,i){if(1<(r=Mt(r)).length){var n=r.map(function(t){return Pe.quickSetter(t,e,i)}),a=n.length;return function(t){for(var e=a;e--;)n[e](t)}}r=r[0]||{};var s=pt[e],o=fa(r),u=o.harness&&(o.harness.aliases||{})[e]||e,h=s?function(t){var e=new s;c._pt=0,e.init(r,i?t+i:t,c,0,[r]),e.render(1,e),c._pt&&fe(1,c)}:o.set(r,u);return s?h:function(t){return h(r,u,i?t+i:t,o,1)}},quickTo:function quickTo(t,i,e){function Vx(t,e,r){return n.resetTo(i,t,e,r)}var r,n=Pe.to(t,yt(((r={})[i]="+=0.1",r.paused=!0,r),e||{}));return Vx.tween=n,Vx},isTweening:function isTweening(t){return 0<L.getTweensOf(t,!0).length},defaults:function defaults(t){return t&&t.ease&&(t.ease=jt(t.ease,q.ease)),ta(q,t||{})},config:function config(t){return ta(V,t||{})},registerEffect:function registerEffect(t){var i=t.name,n=t.effect,e=t.plugins,a=t.defaults,r=t.extendTimeline;(e||"").split(",").forEach(function(t){return t&&!pt[t]&&!ot[t]&&R(i+" effect requires "+t+" plugin.")}),_t[i]=function(t,e,r){return n(Mt(t),qa(e||{},a),r)},r&&(Xt.prototype[i]=function(t,e,r){return this.add(_t[i](t,v(e)?e:(r=e)&&{},this),r)})},registerEase:function registerEase(t,e){It[t]=jt(e)},parseEase:function parseEase(t,e){return arguments.length?jt(t,e):It},getById:function getById(t){return L.getById(t)},exportRoot:function exportRoot(t,e){void 0===t&&(t={});var r,i,n=new Xt(t);for(n.smoothChildTiming=w(t.smoothChildTiming),L.remove(n),n._dp=0,n._time=n._tTime=L._time,r=L._first;r;)i=r._next,!e&&!r._dur&&r instanceof Jt&&r.vars.onComplete===r._targets[0]||Ka(n,r,r._start-r._delay),r=i;return Ka(L,n,0),n},context:function context(t,e){return t?new Me(t,e):l},matchMedia:function matchMedia(t){return new Se(t)},matchMediaRefresh:function matchMediaRefresh(){return Te.forEach(function(t){var e,r,i=t.conditions;for(r in i)i[r]&&(i[r]=!1,e=1);e&&t.revert()})||Ec()},addEventListener:function addEventListener(t,e){var r=be[t]||(be[t]=[]);~r.indexOf(e)||r.push(e)},removeEventListener:function removeEventListener(t,e){var r=be[t],i=r&&r.indexOf(e);0<=i&&r.splice(i,1)},utils:{wrap:function wrap(e,t,r){var i=t-e;return Z(e)?lb(e,wrap(0,e.length),t):Wa(r,function(t){return(i+(t-e)%i)%i+e})},wrapYoyo:function wrapYoyo(e,t,r){var i=t-e,n=2*i;return Z(e)?lb(e,wrapYoyo(0,e.length-1),t):Wa(r,function(t){return e+(i<(t=(n+(t-e)%n)%n||0)?n-t:t)})},distribute:eb,random:hb,snap:gb,normalize:function normalize(t,e,r){return At(t,e,0,1,r)},getUnit:Ya,clamp:function clamp(e,r,t){return Wa(t,function(t){return Ot(e,r,t)})},splitColor:Ab,toArray:Mt,selector:cb,mapRange:At,pipe:function pipe(){for(var t=arguments.length,e=new Array(t),r=0;r<t;r++)e[r]=arguments[r];return function(t){return e.reduce(function(t,e){return e(t)},t)}},unitize:function unitize(e,r){return function(t){return e(parseFloat(t))+(r||Ya(t))}},interpolate:function interpolate(e,i,t,n){var a=isNaN(e+i)?0:function(t){return(1-t)*e+t*i};if(!a){var s,o,u,h,l,f=r(e),c={};if(!0===t&&(n=1)&&(t=null),f)e={p:e},i={p:i};else if(Z(e)&&!Z(i)){for(u=[],h=e.length,l=h-2,o=1;o<h;o++)u.push(interpolate(e[o-1],e[o]));h--,a=function func(t){t*=h;var e=Math.min(l,~~t);return u[e](t-e)},t=i}else n||(e=yt(Z(e)?[]:{},e));if(!u){for(s in i)Qt.call(c,e,s,"get",i[s]);a=function func(t){return fe(t,c)||(f?e.p:e)}}}return Wa(t,a)},shuffle:db},install:P,effects:_t,ticker:Rt,updateRoot:Xt.updateRoot,plugins:pt,globalTimeline:L,core:{PropTween:ge,globals:S,Tween:Jt,Timeline:Xt,Animation:Ut,getCache:fa,_removeLinkedListItem:ya,reverting:function reverting(){return B},context:function context(t){return t&&l&&(l.data.push(t),t._ctx=l),l},suppressOverwrites:function suppressOverwrites(t){return I=t}}};ha("to,from,fromTo,delayedCall,set,killTweensOf",function(t){return Ce[t]=Jt[t]}),Rt.add(Xt.updateRoot),c=Ce.to({},{duration:0});function Ic(t,e){for(var r=t._pt;r&&r.p!==e&&r.op!==e&&r.fp!==e;)r=r._next;return r}function Kc(t,a){return{name:t,rawVars:1,init:function init(t,n,e){e._onInit=function(t){var e,i;if(r(n)&&(e={},ha(n,function(t){return e[t]=1}),n=e),a){for(i in e={},n)e[i]=a(n[i]);n=e}!function _addModifiers(t,e){var r,i,n,a=t._targets;for(r in e)for(i=a.length;i--;)(n=(n=t._ptLookup[i][r])&&n.d)&&(n._pt&&(n=Ic(n,r)),n&&n.modifier&&n.modifier(e[r],t,a[i],r))}(t,n)}}}}var Pe=Ce.registerPlugin({name:"attr",init:function init(t,e,r,i,n){var a,s,o;for(a in this.tween=r,e)o=t.getAttribute(a)||"",(s=this.add(t,"setAttribute",(o||0)+"",e[a],i,n,0,0,a)).op=a,s.b=o,this._props.push(a)},render:function render(t,e){for(var r=e._pt;r;)B?r.set(r.t,r.p,r.b,r):r.r(t,r.d),r=r._next}},{name:"endArray",init:function init(t,e){for(var r=e.length;r--;)this.add(t,r,t[r]||0,e[r],0,0,0,0,0,1)}},Kc("roundProps",fb),Kc("modifiers"),Kc("snap",gb))||Ce;Jt.version=Xt.version=Pe.version="3.11.5",o=1,x()&&Ft();function ud(t,e){return e.set(e.t,e.p,Math.round(1e4*(e.s+e.c*t))/1e4+e.u,e)}function vd(t,e){return e.set(e.t,e.p,1===t?e.e:Math.round(1e4*(e.s+e.c*t))/1e4+e.u,e)}function wd(t,e){return e.set(e.t,e.p,t?Math.round(1e4*(e.s+e.c*t))/1e4+e.u:e.b,e)}function xd(t,e){var r=e.s+e.c*t;e.set(e.t,e.p,~~(r+(r<0?-.5:.5))+e.u,e)}function yd(t,e){return e.set(e.t,e.p,t?e.e:e.b,e)}function zd(t,e){return e.set(e.t,e.p,1!==t?e.b:e.e,e)}function Ad(t,e,r){return t.style[e]=r}function Bd(t,e,r){return t.style.setProperty(e,r)}function Cd(t,e,r){return t._gsap[e]=r}function Dd(t,e,r){return t._gsap.scaleX=t._gsap.scaleY=r}function Ed(t,e,r,i,n){var a=t._gsap;a.scaleX=a.scaleY=r,a.renderTransform(n,a)}function Fd(t,e,r,i,n){var a=t._gsap;a[e]=r,a.renderTransform(n,a)}function Id(t,e){var r=this,i=this.target,n=i.style;if(t in nr){if(this.tfm=this.tfm||{},"transform"===t)return fr.transform.split(",").forEach(function(t){return Id.call(r,t,e)});if(~(t=fr[t]||t).indexOf(",")?t.split(",").forEach(function(t){return r.tfm[t]=vr(i,t)}):this.tfm[t]=i._gsap.x?i._gsap[t]:vr(i,t),0<=this.props.indexOf(cr))return;i._gsap.svg&&(this.svgo=i.getAttribute("data-svg-origin"),this.props.push(dr,e,"")),t=cr}(n||e)&&this.props.push(t,e,n[t])}function Jd(t){t.translate&&(t.removeProperty("translate"),t.removeProperty("scale"),t.removeProperty("rotate"))}function Kd(){var t,e,r=this.props,i=this.target,n=i.style,a=i._gsap;for(t=0;t<r.length;t+=3)r[t+1]?i[r[t]]=r[t+2]:r[t+2]?n[r[t]]=r[t+2]:n.removeProperty("--"===r[t].substr(0,2)?r[t]:r[t].replace(ur,"-$1").toLowerCase());if(this.tfm){for(e in this.tfm)a[e]=this.tfm[e];a.svg&&(a.renderTransform(),i.setAttribute("data-svg-origin",this.svgo||"")),(t=Be())&&t.isStart||n[cr]||(Jd(n),a.uncache=1)}}function Ld(t,e){var r={target:t,props:[],revert:Kd,save:Id};return t._gsap||Pe.core.getCache(t),e&&e.split(",").forEach(function(t){return r.save(t)}),r}function Nd(t,e){var r=Ee.createElementNS?Ee.createElementNS((e||"http://www.w3.org/1999/xhtml").replace(/^https/,"http"),t):Ee.createElement(t);return r.style?r:Ee.createElement(t)}function Od(t,e,r){var i=getComputedStyle(t);return i[e]||i.getPropertyValue(e.replace(ur,"-$1").toLowerCase())||i.getPropertyValue(e)||!r&&Od(t,_r(e)||e,1)||""}function Rd(){(function _windowExists(){return"undefined"!=typeof window})()&&window.document&&(De=window,Ee=De.document,ze=Ee.documentElement,Fe=Nd("div")||{style:{}},Nd("div"),cr=_r(cr),dr=cr+"Origin",Fe.style.cssText="border-width:0;line-height:0;position:absolute;padding:0",Le=!!_r("perspective"),Be=Pe.core.reverting,Re=1)}function Sd(t){var e,r=Nd("svg",this.ownerSVGElement&&this.ownerSVGElement.getAttribute("xmlns")||"http://www.w3.org/2000/svg"),i=this.parentNode,n=this.nextSibling,a=this.style.cssText;if(ze.appendChild(r),r.appendChild(this),this.style.display="block",t)try{e=this.getBBox(),this._gsapBBox=this.getBBox,this.getBBox=Sd}catch(t){}else this._gsapBBox&&(e=this._gsapBBox());return i&&(n?i.insertBefore(this,n):i.appendChild(this)),ze.removeChild(r),this.style.cssText=a,e}function Td(t,e){for(var r=e.length;r--;)if(t.hasAttribute(e[r]))return t.getAttribute(e[r])}function Ud(e){var r;try{r=e.getBBox()}catch(t){r=Sd.call(e,!0)}return r&&(r.width||r.height)||e.getBBox===Sd||(r=Sd.call(e,!0)),!r||r.width||r.x||r.y?r:{x:+Td(e,["x","cx","x1"])||0,y:+Td(e,["y","cy","y1"])||0,width:0,height:0}}function Vd(t){return!(!t.getCTM||t.parentNode&&!t.ownerSVGElement||!Ud(t))}function Wd(t,e){if(e){var r=t.style;e in nr&&e!==dr&&(e=cr),r.removeProperty?("ms"!==e.substr(0,2)&&"webkit"!==e.substr(0,6)||(e="-"+e),r.removeProperty(e.replace(ur,"-$1").toLowerCase())):r.removeAttribute(e)}}function Xd(t,e,r,i,n,a){var s=new ge(t._pt,e,r,0,1,a?zd:yd);return(t._pt=s).b=i,s.e=n,t._props.push(r),s}function $d(t,e,r,i){var n,a,s,o,u=parseFloat(r)||0,h=(r+"").trim().substr((u+"").length)||"px",l=Fe.style,f=hr.test(e),c="svg"===t.tagName.toLowerCase(),d=(c?"client":"offset")+(f?"Width":"Height"),p="px"===i,_="%"===i;return i===h||!u||mr[i]||mr[h]?u:("px"===h||p||(u=$d(t,e,r,"px")),o=t.getCTM&&Vd(t),!_&&"%"!==h||!nr[e]&&!~e.indexOf("adius")?(l[f?"width":"height"]=100+(p?h:i),a=~e.indexOf("adius")||"em"===i&&t.appendChild&&!c?t:t.parentNode,o&&(a=(t.ownerSVGElement||{}).parentNode),a&&a!==Ee&&a.appendChild||(a=Ee.body),(s=a._gsap)&&_&&s.width&&f&&s.time===Rt.time&&!s.uncache?ia(u/s.width*100):(!_&&"%"!==h||gr[Od(a,"display")]||(l.position=Od(t,"position")),a===t&&(l.position="static"),a.appendChild(Fe),n=Fe[d],a.removeChild(Fe),l.position="absolute",f&&_&&((s=fa(a)).time=Rt.time,s.width=a[d]),ia(p?n*u/100:n&&u?100/n*u:0))):(n=o?t.getBBox()[f?"width":"height"]:t[d],ia(_?u/n*100:u/100*n)))}function ae(t,e,r,i){if(!r||"none"===r){var n=_r(e,t,1),a=n&&Od(t,n,1);a&&a!==r?(e=n,r=a):"borderColor"===e&&(r=Od(t,"borderTopColor"))}var s,o,u,h,l,f,c,d,p,_,m,g=new ge(this._pt,t.style,e,0,1,le),v=0,y=0;if(g.b=r,g.e=i,r+="","auto"===(i+="")&&(t.style[e]=i,i=Od(t,e)||i,t.style[e]=r),Fb(s=[r,i]),i=s[1],u=(r=s[0]).match(rt)||[],(i.match(rt)||[]).length){for(;o=rt.exec(i);)c=o[0],p=i.substring(v,o.index),l?l=(l+1)%5:"rgba("!==p.substr(-5)&&"hsla("!==p.substr(-5)||(l=1),c!==(f=u[y++]||"")&&(h=parseFloat(f)||0,m=f.substr((h+"").length),"="===c.charAt(1)&&(c=ka(h,c)+m),d=parseFloat(c),_=c.substr((d+"").length),v=rt.lastIndex-_.length,_||(_=_||V.units[e]||m,v===i.length&&(i+=_,g.e+=_)),m!==_&&(h=$d(t,e,f,_)||0),g._pt={_next:g._pt,p:p||1===y?p:",",s:h,c:d-h,m:l&&l<4||"zIndex"===e?Math.round:0});g.c=v<i.length?i.substring(v,i.length):""}else g.r="display"===e&&"none"===i?zd:yd;return nt.test(i)&&(g.e=0),this._pt=g}function ce(t){var e=t.split(" "),r=e[0],i=e[1]||"50%";return"top"!==r&&"bottom"!==r&&"left"!==i&&"right"!==i||(t=r,r=i,i=t),e[0]=yr[r]||r,e[1]=yr[i]||i,e.join(" ")}function de(t,e){if(e.tween&&e.tween._time===e.tween._dur){var r,i,n,a=e.t,s=a.style,o=e.u,u=a._gsap;if("all"===o||!0===o)s.cssText="",i=1;else for(n=(o=o.split(",")).length;-1<--n;)r=o[n],nr[r]&&(i=1,r="transformOrigin"===r?dr:cr),Wd(a,r);i&&(Wd(a,cr),u&&(u.svg&&a.removeAttribute("transform"),xr(a,1),u.uncache=1,Jd(s)))}}function he(t){return"matrix(1, 0, 0, 1, 0, 0)"===t||"none"===t||!t}function ie(t){var e=Od(t,cr);return he(e)?br:e.substr(7).match(et).map(ia)}function je(t,e){var r,i,n,a,s=t._gsap||fa(t),o=t.style,u=ie(t);return s.svg&&t.getAttribute("transform")?"1,0,0,1,0,0"===(u=[(n=t.transform.baseVal.consolidate().matrix).a,n.b,n.c,n.d,n.e,n.f]).join(",")?br:u:(u!==br||t.offsetParent||t===ze||s.svg||(n=o.display,o.display="block",(r=t.parentNode)&&t.offsetParent||(a=1,i=t.nextElementSibling,ze.appendChild(t)),u=ie(t),n?o.display=n:Wd(t,"display"),a&&(i?r.insertBefore(t,i):r?r.appendChild(t):ze.removeChild(t))),e&&6<u.length?[u[0],u[1],u[4],u[5],u[12],u[13]]:u)}function ke(t,e,r,i,n,a){var s,o,u,h=t._gsap,l=n||je(t,!0),f=h.xOrigin||0,c=h.yOrigin||0,d=h.xOffset||0,p=h.yOffset||0,_=l[0],m=l[1],g=l[2],v=l[3],y=l[4],T=l[5],b=e.split(" "),w=parseFloat(b[0])||0,x=parseFloat(b[1])||0;r?l!==br&&(o=_*v-m*g)&&(u=w*(-m/o)+x*(_/o)-(_*T-m*y)/o,w=w*(v/o)+x*(-g/o)+(g*T-v*y)/o,x=u):(w=(s=Ud(t)).x+(~b[0].indexOf("%")?w/100*s.width:w),x=s.y+(~(b[1]||b[0]).indexOf("%")?x/100*s.height:x)),i||!1!==i&&h.smooth?(y=w-f,T=x-c,h.xOffset=d+(y*_+T*g)-y,h.yOffset=p+(y*m+T*v)-T):h.xOffset=h.yOffset=0,h.xOrigin=w,h.yOrigin=x,h.smooth=!!i,h.origin=e,h.originIsAbsolute=!!r,t.style[dr]="0px 0px",a&&(Xd(a,h,"xOrigin",f,w),Xd(a,h,"yOrigin",c,x),Xd(a,h,"xOffset",d,h.xOffset),Xd(a,h,"yOffset",p,h.yOffset)),t.setAttribute("data-svg-origin",w+" "+x)}function ne(t,e,r){var i=Ya(e);return ia(parseFloat(e)+parseFloat($d(t,"x",r+"px",i)))+i}function ue(t,e,i,n,a){var s,o,u=360,h=r(a),l=parseFloat(a)*(h&&~a.indexOf("rad")?ar:1)-n,f=n+l+"deg";return h&&("short"===(s=a.split("_")[1])&&(l%=u)!==l%180&&(l+=l<0?u:-u),"cw"===s&&l<0?l=(l+36e9)%u-~~(l/u)*u:"ccw"===s&&0<l&&(l=(l-36e9)%u-~~(l/u)*u)),t._pt=o=new ge(t._pt,e,i,n,l,vd),o.e=f,o.u="deg",t._props.push(i),o}function ve(t,e){for(var r in e)t[r]=e[r];return t}function we(t,e,r){var i,n,a,s,o,u,h,l=ve({},r._gsap),f=r.style;for(n in l.svg?(a=r.getAttribute("transform"),r.setAttribute("transform",""),f[cr]=e,i=xr(r,1),Wd(r,cr),r.setAttribute("transform",a)):(a=getComputedStyle(r)[cr],f[cr]=e,i=xr(r,1),f[cr]=a),nr)(a=l[n])!==(s=i[n])&&"perspective,force3D,transformOrigin,svgOrigin".indexOf(n)<0&&(o=Ya(a)!==(h=Ya(s))?$d(r,n,a,h):parseFloat(a),u=parseFloat(s),t._pt=new ge(t._pt,i,n,o,u-o,ud),t._pt.u=h||0,t._props.push(n));ve(i,l)}var De,Ee,ze,Re,Fe,Ie,Be,Le,Ye=It.Power0,Ve=It.Power1,qe=It.Power2,Ue=It.Power3,Xe=It.Power4,Ne=It.Linear,We=It.Quad,Qe=It.Cubic,Ke=It.Quart,Ge=It.Quint,$e=It.Strong,He=It.Elastic,Je=It.Back,Ze=It.SteppedEase,tr=It.Bounce,er=It.Sine,rr=It.Expo,ir=It.Circ,nr={},ar=180/Math.PI,sr=Math.PI/180,or=Math.atan2,ur=/([A-Z])/g,hr=/(left|right|width|margin|padding|x)/i,lr=/[\s,\(]\S/,fr={autoAlpha:"opacity,visibility",scale:"scaleX,scaleY",alpha:"opacity"},cr="transform",dr=cr+"Origin",pr="O,Moz,ms,Ms,Webkit".split(","),_r=function _checkPropPrefix(t,e,r){var i=(e||Fe).style,n=5;if(t in i&&!r)return t;for(t=t.charAt(0).toUpperCase()+t.substr(1);n--&&!(pr[n]+t in i););return n<0?null:(3===n?"ms":0<=n?pr[n]:"")+t},mr={deg:1,rad:1,turn:1},gr={grid:1,flex:1},vr=function _get(t,e,r,i){var n;return Re||Rd(),e in fr&&"transform"!==e&&~(e=fr[e]).indexOf(",")&&(e=e.split(",")[0]),nr[e]&&"transform"!==e?(n=xr(t,i),n="transformOrigin"!==e?n[e]:n.svg?n.origin:Or(Od(t,dr))+" "+n.zOrigin+"px"):(n=t.style[e])&&"auto"!==n&&!i&&!~(n+"").indexOf("calc(")||(n=Tr[e]&&Tr[e](t,e,r)||Od(t,e)||ga(t,e)||("opacity"===e?1:0)),r&&!~(n+"").trim().indexOf(" ")?$d(t,e,n,r)+r:n},yr={top:"0%",bottom:"100%",left:"0%",right:"100%",center:"50%"},Tr={clearProps:function clearProps(t,e,r,i,n){if("isFromStart"!==n.data){var a=t._pt=new ge(t._pt,e,r,0,0,de);return a.u=i,a.pr=-10,a.tween=n,t._props.push(r),1}}},br=[1,0,0,1,0,0],wr={},xr=function _parseTransform(t,e){var r=t._gsap||new qt(t);if("x"in r&&!e&&!r.uncache)return r;var i,n,a,s,o,u,h,l,f,c,d,p,_,m,g,v,y,T,b,w,x,O,k,M,A,S,C,P,D,E,z,R,F=t.style,I=r.scaleX<0,B="deg",L=getComputedStyle(t),Y=Od(t,dr)||"0";return i=n=a=u=h=l=f=c=d=0,s=o=1,r.svg=!(!t.getCTM||!Vd(t)),L.translate&&("none"===L.translate&&"none"===L.scale&&"none"===L.rotate||(F[cr]=("none"!==L.translate?"translate3d("+(L.translate+" 0 0").split(" ").slice(0,3).join(", ")+") ":"")+("none"!==L.rotate?"rotate("+L.rotate+") ":"")+("none"!==L.scale?"scale("+L.scale.split(" ").join(",")+") ":"")+("none"!==L[cr]?L[cr]:"")),F.scale=F.rotate=F.translate="none"),m=je(t,r.svg),r.svg&&(M=r.uncache?(A=t.getBBox(),Y=r.xOrigin-A.x+"px "+(r.yOrigin-A.y)+"px",""):!e&&t.getAttribute("data-svg-origin"),ke(t,M||Y,!!M||r.originIsAbsolute,!1!==r.smooth,m)),p=r.xOrigin||0,_=r.yOrigin||0,m!==br&&(T=m[0],b=m[1],w=m[2],x=m[3],i=O=m[4],n=k=m[5],6===m.length?(s=Math.sqrt(T*T+b*b),o=Math.sqrt(x*x+w*w),u=T||b?or(b,T)*ar:0,(f=w||x?or(w,x)*ar+u:0)&&(o*=Math.abs(Math.cos(f*sr))),r.svg&&(i-=p-(p*T+_*w),n-=_-(p*b+_*x))):(R=m[6],E=m[7],C=m[8],P=m[9],D=m[10],z=m[11],i=m[12],n=m[13],a=m[14],h=(g=or(R,D))*ar,g&&(M=O*(v=Math.cos(-g))+C*(y=Math.sin(-g)),A=k*v+P*y,S=R*v+D*y,C=O*-y+C*v,P=k*-y+P*v,D=R*-y+D*v,z=E*-y+z*v,O=M,k=A,R=S),l=(g=or(-w,D))*ar,g&&(v=Math.cos(-g),z=x*(y=Math.sin(-g))+z*v,T=M=T*v-C*y,b=A=b*v-P*y,w=S=w*v-D*y),u=(g=or(b,T))*ar,g&&(M=T*(v=Math.cos(g))+b*(y=Math.sin(g)),A=O*v+k*y,b=b*v-T*y,k=k*v-O*y,T=M,O=A),h&&359.9<Math.abs(h)+Math.abs(u)&&(h=u=0,l=180-l),s=ia(Math.sqrt(T*T+b*b+w*w)),o=ia(Math.sqrt(k*k+R*R)),g=or(O,k),f=2e-4<Math.abs(g)?g*ar:0,d=z?1/(z<0?-z:z):0),r.svg&&(M=t.getAttribute("transform"),r.forceCSS=t.setAttribute("transform","")||!he(Od(t,cr)),M&&t.setAttribute("transform",M))),90<Math.abs(f)&&Math.abs(f)<270&&(I?(s*=-1,f+=u<=0?180:-180,u+=u<=0?180:-180):(o*=-1,f+=f<=0?180:-180)),e=e||r.uncache,r.x=i-((r.xPercent=i&&(!e&&r.xPercent||(Math.round(t.offsetWidth/2)===Math.round(-i)?-50:0)))?t.offsetWidth*r.xPercent/100:0)+"px",r.y=n-((r.yPercent=n&&(!e&&r.yPercent||(Math.round(t.offsetHeight/2)===Math.round(-n)?-50:0)))?t.offsetHeight*r.yPercent/100:0)+"px",r.z=a+"px",r.scaleX=ia(s),r.scaleY=ia(o),r.rotation=ia(u)+B,r.rotationX=ia(h)+B,r.rotationY=ia(l)+B,r.skewX=f+B,r.skewY=c+B,r.transformPerspective=d+"px",(r.zOrigin=parseFloat(Y.split(" ")[2])||0)&&(F[dr]=Or(Y)),r.xOffset=r.yOffset=0,r.force3D=V.force3D,r.renderTransform=r.svg?Pr:Le?Cr:kr,r.uncache=0,r},Or=function _firstTwoOnly(t){return(t=t.split(" "))[0]+" "+t[1]},kr=function _renderNon3DTransforms(t,e){e.z="0px",e.rotationY=e.rotationX="0deg",e.force3D=0,Cr(t,e)},Mr="0deg",Ar="0px",Sr=") ",Cr=function _renderCSSTransforms(t,e){var r=e||this,i=r.xPercent,n=r.yPercent,a=r.x,s=r.y,o=r.z,u=r.rotation,h=r.rotationY,l=r.rotationX,f=r.skewX,c=r.skewY,d=r.scaleX,p=r.scaleY,_=r.transformPerspective,m=r.force3D,g=r.target,v=r.zOrigin,y="",T="auto"===m&&t&&1!==t||!0===m;if(v&&(l!==Mr||h!==Mr)){var b,w=parseFloat(h)*sr,x=Math.sin(w),O=Math.cos(w);w=parseFloat(l)*sr,b=Math.cos(w),a=ne(g,a,x*b*-v),s=ne(g,s,-Math.sin(w)*-v),o=ne(g,o,O*b*-v+v)}_!==Ar&&(y+="perspective("+_+Sr),(i||n)&&(y+="translate("+i+"%, "+n+"%) "),!T&&a===Ar&&s===Ar&&o===Ar||(y+=o!==Ar||T?"translate3d("+a+", "+s+", "+o+") ":"translate("+a+", "+s+Sr),u!==Mr&&(y+="rotate("+u+Sr),h!==Mr&&(y+="rotateY("+h+Sr),l!==Mr&&(y+="rotateX("+l+Sr),f===Mr&&c===Mr||(y+="skew("+f+", "+c+Sr),1===d&&1===p||(y+="scale("+d+", "+p+Sr),g.style[cr]=y||"translate(0, 0)"},Pr=function _renderSVGTransforms(t,e){var r,i,n,a,s,o=e||this,u=o.xPercent,h=o.yPercent,l=o.x,f=o.y,c=o.rotation,d=o.skewX,p=o.skewY,_=o.scaleX,m=o.scaleY,g=o.target,v=o.xOrigin,y=o.yOrigin,T=o.xOffset,b=o.yOffset,w=o.forceCSS,x=parseFloat(l),O=parseFloat(f);c=parseFloat(c),d=parseFloat(d),(p=parseFloat(p))&&(d+=p=parseFloat(p),c+=p),c||d?(c*=sr,d*=sr,r=Math.cos(c)*_,i=Math.sin(c)*_,n=Math.sin(c-d)*-m,a=Math.cos(c-d)*m,d&&(p*=sr,s=Math.tan(d-p),n*=s=Math.sqrt(1+s*s),a*=s,p&&(s=Math.tan(p),r*=s=Math.sqrt(1+s*s),i*=s)),r=ia(r),i=ia(i),n=ia(n),a=ia(a)):(r=_,a=m,i=n=0),(x&&!~(l+"").indexOf("px")||O&&!~(f+"").indexOf("px"))&&(x=$d(g,"x",l,"px"),O=$d(g,"y",f,"px")),(v||y||T||b)&&(x=ia(x+v-(v*r+y*n)+T),O=ia(O+y-(v*i+y*a)+b)),(u||h)&&(s=g.getBBox(),x=ia(x+u/100*s.width),O=ia(O+h/100*s.height)),s="matrix("+r+","+i+","+n+","+a+","+x+","+O+")",g.setAttribute("transform",s),w&&(g.style[cr]=s)};ha("padding,margin,Width,Radius",function(e,r){var t="Right",i="Bottom",n="Left",o=(r<3?["Top",t,i,n]:["Top"+n,"Top"+t,i+t,i+n]).map(function(t){return r<2?e+t:"border"+t+e});Tr[1<r?"border"+e:e]=function(e,t,r,i,n){var a,s;if(arguments.length<4)return a=o.map(function(t){return vr(e,t,r)}),5===(s=a.join(" ")).split(a[0]).length?a[0]:s;a=(i+"").split(" "),s={},o.forEach(function(t,e){return s[t]=a[e]=a[e]||a[(e-1)/2|0]}),e.init(t,s,n)}});var Dr,Er,zr,Rr={name:"css",register:Rd,targetTest:function targetTest(t){return t.style&&t.nodeType},init:function init(t,e,i,n,a){var s,o,u,h,l,f,c,d,p,_,m,g,v,y,T,b,w=this._props,x=t.style,O=i.vars.startAt;for(c in Re||Rd(),this.styles=this.styles||Ld(t),b=this.styles.props,this.tween=i,e)if("autoRound"!==c&&(o=e[c],!pt[c]||!ac(c,e,i,n,t,a)))if(l=typeof o,f=Tr[c],"function"===l&&(l=typeof(o=o.call(i,n,t,a))),"string"===l&&~o.indexOf("random(")&&(o=ob(o)),f)f(this,t,c,o,i)&&(T=1);else if("--"===c.substr(0,2))s=(getComputedStyle(t).getPropertyValue(c)+"").trim(),o+="",Et.lastIndex=0,Et.test(s)||(d=Ya(s),p=Ya(o)),p?d!==p&&(s=$d(t,c,s,p)+p):d&&(o+=d),this.add(x,"setProperty",s,o,n,a,0,0,c),w.push(c),b.push(c,0,x[c]);else if("undefined"!==l){if(O&&c in O?(s="function"==typeof O[c]?O[c].call(i,n,t,a):O[c],r(s)&&~s.indexOf("random(")&&(s=ob(s)),Ya(s+"")||(s+=V.units[c]||Ya(vr(t,c))||""),"="===(s+"").charAt(1)&&(s=vr(t,c))):s=vr(t,c),h=parseFloat(s),(_="string"===l&&"="===o.charAt(1)&&o.substr(0,2))&&(o=o.substr(2)),u=parseFloat(o),c in fr&&("autoAlpha"===c&&(1===h&&"hidden"===vr(t,"visibility")&&u&&(h=0),b.push("visibility",0,x.visibility),Xd(this,x,"visibility",h?"inherit":"hidden",u?"inherit":"hidden",!u)),"scale"!==c&&"transform"!==c&&~(c=fr[c]).indexOf(",")&&(c=c.split(",")[0])),m=c in nr)if(this.styles.save(c),g||((v=t._gsap).renderTransform&&!e.parseTransform||xr(t,e.parseTransform),y=!1!==e.smoothOrigin&&v.smooth,(g=this._pt=new ge(this._pt,x,cr,0,1,v.renderTransform,v,0,-1)).dep=1),"scale"===c)this._pt=new ge(this._pt,v,"scaleY",v.scaleY,(_?ka(v.scaleY,_+u):u)-v.scaleY||0,ud),this._pt.u=0,w.push("scaleY",c),c+="X";else{if("transformOrigin"===c){b.push(dr,0,x[dr]),o=ce(o),v.svg?ke(t,o,0,y,0,this):((p=parseFloat(o.split(" ")[2])||0)!==v.zOrigin&&Xd(this,v,"zOrigin",v.zOrigin,p),Xd(this,x,c,Or(s),Or(o)));continue}if("svgOrigin"===c){ke(t,o,1,y,0,this);continue}if(c in wr){ue(this,v,c,h,_?ka(h,_+o):o);continue}if("smoothOrigin"===c){Xd(this,v,"smooth",v.smooth,o);continue}if("force3D"===c){v[c]=o;continue}if("transform"===c){we(this,o,t);continue}}else c in x||(c=_r(c)||c);if(m||(u||0===u)&&(h||0===h)&&!lr.test(o)&&c in x)u=u||0,(d=(s+"").substr((h+"").length))!==(p=Ya(o)||(c in V.units?V.units[c]:d))&&(h=$d(t,c,s,p)),this._pt=new ge(this._pt,m?v:x,c,h,(_?ka(h,_+u):u)-h,m||"px"!==p&&"zIndex"!==c||!1===e.autoRound?ud:xd),this._pt.u=p||0,d!==p&&"%"!==p&&(this._pt.b=s,this._pt.r=wd);else if(c in x)ae.call(this,t,c,s,_?_+o:o);else if(c in t)this.add(t,c,s||t[c],_?_+o:o,n,a);else if("parseTransform"!==c){Q(c,o);continue}m||(c in x?b.push(c,0,x[c]):b.push(c,1,s||t[c])),w.push(c)}T&&me(this)},render:function render(t,e){if(e.tween._time||!Be())for(var r=e._pt;r;)r.r(t,r.d),r=r._next;else e.styles.revert()},get:vr,aliases:fr,getSetter:function getSetter(t,e,r){var i=fr[e];return i&&i.indexOf(",")<0&&(e=i),e in nr&&e!==dr&&(t._gsap.x||vr(t,"x"))?r&&Ie===r?"scale"===e?Dd:Cd:(Ie=r||{})&&("scale"===e?Ed:Fd):t.style&&!u(t.style[e])?Ad:~e.indexOf("-")?Bd:re(t,e)},core:{_removeProperty:Wd,_getMatrix:je}};Pe.utils.checkPrefix=_r,Pe.core.getStyleSaver=Ld,zr=ha((Dr="x,y,z,scale,scaleX,scaleY,xPercent,yPercent")+","+(Er="rotation,rotationX,rotationY,skewX,skewY")+",transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective",function(t){nr[t]=1}),ha(Er,function(t){V.units[t]="deg",wr[t]=1}),fr[zr[13]]=Dr+","+Er,ha("0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY",function(t){var e=t.split(":");fr[e[1]]=zr[e[0]]}),ha("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective",function(t){V.units[t]="px"}),Pe.registerPlugin(Rr);var Fr=Pe.registerPlugin(Rr)||Pe,Ir=Fr.core.Tween;e.Back=Je,e.Bounce=tr,e.CSSPlugin=Rr,e.Circ=ir,e.Cubic=Qe,e.Elastic=He,e.Expo=rr,e.Linear=Ne,e.Power0=Ye,e.Power1=Ve,e.Power2=qe,e.Power3=Ue,e.Power4=Xe,e.Quad=We,e.Quart=Ke,e.Quint=Ge,e.Sine=er,e.SteppedEase=Ze,e.Strong=$e,e.TimelineLite=Xt,e.TimelineMax=Xt,e.TweenLite=Jt,e.TweenMax=Ir,e.default=Fr,e.gsap=Fr;if (typeof(window)==="undefined"||window!==e){Object.defineProperty(e,"__esModule",{value:!0})} else {delete e.default}});

LineTypeEffect/js/index.js
파일 저장

const wrapElements = (elems, wrapType, wrapClass) => {
    elems.forEach(char => {
        const wrapEl = document.createElement(wrapType);
        wrapEl.classList = wrapClass;
        char.parentNode.appendChild(wrapEl);
        wrapEl.appendChild(char);
    });
}

// Initialize Splitting js
Splitting();

const timelines = [
    // effect 1
    (chars, line) => {
        return gsap.timeline({
            defaults: {
                duration: 0.7,
                ease: 'expo',
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            transformOrigin: '0% 50%',
            filter: 'brightness(100%) blur(30px)',
        }, {
            duration: 0.2,
            ease: 'power3.in',
            scaleX: 1,
            filter: 'brightness(600%) blur(6px)',
        }, 'start')
        .to(line, {
            duration: 0.5,
            startAt: {transformOrigin: '100% 50%'},
            scaleX: 0,
            scaleY: 0.1,
            filter: 'brightness(100%) blur(0px)',
        }, 'start+=0.2')
        .to(chars, {
            stagger: 0.03,
            xPercent: () => gsap.utils.random(-150,150),
            yPercent: () => gsap.utils.random(-150,150),
            rotation: () => gsap.utils.random(-25,25),
            scale: () => gsap.utils.random(1,1.5),
        }, 'start+=0.1');
    },
    // effect 2
    (chars, line) => {
        return gsap.timeline({
            defaults: {
                duration: 0.7,
                ease: 'power3.inOut'
            },
            paused: true
        })
        .addLabel('start', 0)
        .to(line, {
            scaleX: 1
        }, 'start')
        .to(chars, {
            duration: 0.3,
            ease: 'back',
            stagger: {
                amount: 0.4,
                from: 0
            },
            xPercent: () => gsap.utils.random(-10,10),
            yPercent: () => gsap.utils.random(-60,-30),
            rotation: () => gsap.utils.random(-15,15)
        }, 'start');
    },
    // effect 3
    (chars, line) => {
        return gsap.timeline({
            defaults: {
                duration: 0.7,
                ease: 'expo'
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            transformOrigin: '0% 50%'
        }, {
            duration: 0.2,
            ease: 'power3.in',
            scaleX: 1
        }, 'start')
        .to(line, {
            duration: 0.5,
            startAt: {transformOrigin: '100% 50%'},
            scaleX: 0
        }, 'start+=0.2')
        .to(chars, {
            stagger: {
                each: 0.025,
                from: '0'
            },
            x: (_, target) => {
                const left = target.getBoundingClientRect()['left'];
                const windowWidth = window.innerWidth;
                return (windowWidth-left) - (windowWidth-left)*0.5
            },
            yPercent: () => gsap.utils.random(-100,100),
            rotation: () => gsap.utils.random(-180,180),
        }, 'start');
    },
    // effect 4
    (chars, line) => {
        return gsap.timeline({
            defaults: {
                duration: 0.9,
                ease: 'expo'
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            transformOrigin: '0% 50%'
        }, {
            duration: 0.2,
            ease: 'power3.in',
            scaleX: 1
        }, 'start')
        .to(line, {
            duration: 0.3,
            startAt: {transformOrigin: '100% 50%'},
            scaleX: 0
        }, 'start+=0.2')
        .fromTo(chars, {
            transformOrigin: '50% 300%'
        }, {
            stagger: {
                each: 0.025,
                from: 'start'
            },
            //yPercent: () => gsap.utils.random(-150,150),
            rotation: () => gsap.utils.random(40,90),
        }, 'start');
    },
    // effect 5
    (chars, line) => {
        return gsap.timeline({
            onStart: () => gsap.set(chars[0].parentNode, {perspective: 300}),
            defaults: {
                duration: 1,
                ease: 'power4'
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            transformOrigin: '0% 50%'
        }, {
            duration: 0.1,
            ease: 'power1.in',
            scaleX: 1
        }, 'start')
        .to(line, {
            duration: 0.5,
            startAt: {transformOrigin: '100% 50%'},
            scaleX: 0,
            scaleY: 3.5
        }, 'start+=0.1')
        .to(chars, {
            stagger: 0.015,
            rotationX: () => gsap.utils.random(-200,200),
            xPercent: () => gsap.utils.random(-70,70),
            yPercent: () => gsap.utils.random(-200,200),
            z: () => gsap.utils.random(-800,-100),
        }, 'start');
    },
    // effect 6
    (chars, line) => {
        return gsap.timeline({
            onStart: () => gsap.set(chars[0].parentNode, {perspective: 1000}),
            defaults: {
                duration: 1,
                ease: 'power3'
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            transformOrigin: '0% 50%'
        }, {
            duration: 0.2,
            ease: 'power1.in',
            scaleX: 1
        }, 'start')
        .to(line, {
            startAt: {transformOrigin: '100% 50%'},
            duration: 0.5,
            scaleX: 0
        }, 'start+=0.3')
        .to(chars, {
            duration: 0.8,
            stagger: 0.035,
            rotationY: 360,
            filter: 'brightness(400%) hue-rotate(90deg)'
        }, 'start');
    },
    // effect 7
    (chars, line) => {
        return gsap.timeline({
            defaults: {
                duration: 0.7,
                ease: 'power3.inOut'
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            skewX: -9,
            skewY: -2
        }, {
            scaleX: 1
        }, 'start')
        .fromTo(chars, {
            transformOrigin: '50% 100%'
        }, {
            duration: 0.2,
            ease: 'power1.in',
            stagger: {
                amount: 0.4
            },
            scaleX: 1.4,
            scaleY: 0.05
        }, 'start')
        .to(chars, {
            duration: 0.3,
            ease: 'back',
            stagger: {
                amount: 0.4
            },
            scaleX: 1,
            scaleY: 1
        }, 'start+=0.2');
    },
    // effect 8
    (chars, line, charWraps) => {
        return gsap.timeline({
            defaults: {
                duration: 0.4,
                ease: 'back.inOut',
            },
            paused: true
        })
        .addLabel('start', 0)
        .fromTo(line, {
            transformOrigin: '0% 50%'
        }, {
            duration: 0.2,
            ease: 'power2.in',
            scaleX: 1
        }, 'start')
        .to(line, {
            duration: 0.5,
            ease: 'power2',
            startAt: {transformOrigin: '100% 50%'},
            scaleX: 0,
            scaleY: 0.2
        }, 'start+=0.2')
        
        .to(charWraps, {
            stagger: 0.025,
            yPercent: () => gsap.utils.random(-120,-50),
            rotation: () => gsap.utils.random(-20,20),
        }, 'start')
        .to(chars, {
            stagger: 0.025,
            yPercent: -100
        }, 'start+=0.1')

        .to(charWraps, {
            startAt: {
                yPercent: () => gsap.utils.random(50,120),
                rotation: () => gsap.utils.random(-20,20),
            },
            stagger: 0.025,
            yPercent: 0,
            rotation: 0,
        }, 'start+=0.5')
        .to(chars, {
            stagger: 0.025,
            startAt: {yPercent: 100},
            yPercent: 0
        }, 'start+=0.4')
    },
];

const lineTypeElems = [...document.querySelectorAll('.linetype')];
lineTypeElems.forEach((lineTypeEl, position) => {
    const chars = lineTypeEl.querySelectorAll('.linetype__text .char');
    const line = lineTypeEl.querySelector('.linetype__line');
    
    let charWraps = null;
    if ( 'charwrap' in lineTypeEl.dataset ) {
        wrapElements(chars, 'span', 'char-wrap');
        charWraps = [...chars].map(char => char.parentNode);
    }

    lineTypeEl.addEventListener('mouseenter', () => {
        if ( lineTypeEl.timeline ) {
            lineTypeEl.timeline.progress(0).kill();
        }
        lineTypeEl.timeline = timelines[position](chars, line, charWraps);
        lineTypeEl.timeline.play();
    });
    lineTypeEl.addEventListener('mouseleave', () => {
        if ( lineTypeEl.timeline ) {
            lineTypeEl.timeline.reverse();
        }
    });
});


LineTypeEffect/js/splitting.min.js
파일 저장

!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):n.Splitting=t()}(this,function(){"use strict"
var o=document,l=o.createTextNode.bind(o)
function d(n,t,e){n.style.setProperty(t,e)}function f(n,t){return n.appendChild(t)}function p(n,t,e,r){var i=o.createElement("span")
return t&&(i.className=t),e&&(!r&&i.setAttribute("data-"+t,e),i.textContent=e),n&&f(n,i)||i}function h(n,t){return n.getAttribute("data-"+t)}function m(n,t){return n&&0!=n.length?n.nodeName?[n]:[].slice.call(n[0].nodeName?n:(t||o).querySelectorAll(n)):[]}function u(n){for(var t=[];n--;)t[n]=[]
return t}function v(n,t){n&&n.some(t)}function c(t){return function(n){return t[n]}}var a={}
function n(n,t,e,r){return{by:n,depends:t,key:e,split:r}}function r(n){return function t(e,n,r){var i=r.indexOf(e)
if(-1==i){r.unshift(e)
var o=a[e]
if(!o)throw new Error("plugin not loaded: "+e)
v(o.depends,function(n){t(n,e,r)})}else{var u=r.indexOf(n)
r.splice(i,1),r.splice(u,0,e)}return r}(n,0,[]).map(c(a))}function t(n){a[n.by]=n}function g(n,r,i,o,u){n.normalize()
var c=[],a=document.createDocumentFragment()
o&&c.push(n.previousSibling)
var s=[]
return m(n.childNodes).some(function(n){if(!n.tagName||n.hasChildNodes()){if(n.childNodes&&n.childNodes.length)return s.push(n),void c.push.apply(c,g(n,r,i,o,u))
var t=n.wholeText||"",e=t.trim()
e.length&&(" "===t[0]&&s.push(l(" ")),v(e.split(i),function(n,t){t&&u&&s.push(p(a,"whitespace"," ",u))
var e=p(a,r,n)
c.push(e),s.push(e)})," "===t[t.length-1]&&s.push(l(" ")))}else s.push(n)}),v(s,function(n){f(a,n)}),n.innerHTML="",f(n,a),c}var s=0
var i="words",e=n(i,s,"word",function(n){return g(n,"word",/\s+/,0,1)}),y="chars",w=n(y,[i],"char",function(n,e,t){var r=[]
return v(t[i],function(n,t){r.push.apply(r,g(n,"char","",e.whitespace&&t))}),r})
function b(e){var f=(e=e||{}).key
return m(e.target||"[data-splitting]").map(function(a){var s=a["🍌"]
if(!e.force&&s)return s
s=a["🍌"]={el:a}
var n=e.by||h(a,"splitting")
n&&"true"!=n||(n=y)
var t=r(n),l=function(n,t){for(var e in t)n[e]=t[e]
return n}({},e)
return v(t,function(n){if(n.split){var t=n.by,e=(f?"-"+f:"")+n.key,r=n.split(a,l,s)
e&&(i=a,c=(u="--"+e)+"-index",v(o=r,function(n,t){Array.isArray(n)?v(n,function(n){d(n,c,t)}):d(n,c,t)}),d(i,u+"-total",o.length)),s[t]=r,a.classList.add(t)}var i,o,u,c}),a.classList.add("splitting"),s})}function N(n,t,e){var r=m(t.matching||n.children,n),i={}
return v(r,function(n){var t=Math.round(n[e]);(i[t]||(i[t]=[])).push(n)}),Object.keys(i).map(Number).sort(x).map(c(i))}function x(n,t){return n-t}b.html=function(n){var t=(n=n||{}).target=p()
return t.innerHTML=n.content,b(n),t.outerHTML},b.add=t
var T=n("lines",[i],"line",function(n,t,e){return N(n,{matching:e[i]},"offsetTop")}),L=n("items",s,"item",function(n,t){return m(t.matching||n.children,n)}),k=n("rows",s,"row",function(n,t){return N(n,t,"offsetTop")}),A=n("cols",s,"col",function(n,t){return N(n,t,"offsetLeft")}),C=n("grid",["rows","cols"]),M="layout",S=n(M,s,s,function(n,t){var e=t.rows=+(t.rows||h(n,"rows")||1),r=t.columns=+(t.columns||h(n,"columns")||1)
if(t.image=t.image||h(n,"image")||n.currentSrc||n.src,t.image){var i=m("img",n)[0]
t.image=i&&(i.currentSrc||i.src)}t.image&&d(n,"background-image","url("+t.image+")")
for(var o=e*r,u=[],c=p(s,"cell-grid");o--;){var a=p(c,"cell")
p(a,"cell-inner"),u.push(a)}return f(n,c),u}),H=n("cellRows",[M],"row",function(n,t,e){var r=t.rows,i=u(r)
return v(e[M],function(n,t,e){i[Math.floor(t/(e.length/r))].push(n)}),i}),O=n("cellColumns",[M],"col",function(n,t,e){var r=t.columns,i=u(r)
return v(e[M],function(n,t){i[t%r].push(n)}),i}),j=n("cells",["cellRows","cellColumns"],"cell",function(n,t,e){return e[M]})
return t(e),t(w),t(T),t(L),t(k),t(A),t(C),t(S),t(H),t(O),t(j),b})
LICENSE실행 안내·자료
파일 저장

MIT License

Copyright (c) 2009 - 2022 [Codrops](https://tympanus.net/codrops)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
css/base.css
파일 저장

*,
*::after,
*::before {
	box-sizing: border-box;
}

:root {
	font-size: 18px;
	--color-text: #fff;
	--color-bg: #000;
	--color-link: #fff;
	--color-link-hover: #fff;
}

body {
	margin: 0;
	color: var(--color-text);
	background-color: var(--color-bg);
	font-family: area-normal,-apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial, sans-serif;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	width: 100%;
	height: 100vh;
	overflow: hidden;
	touch-action: none;
}

/* Page Loader */
.js .loading::before,
.js .loading::after {
	content: '';
	position: fixed;
	z-index: 1000;
}

.js .loading::before {
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: #f0f0f0;
}

.js .loading::after {
	top: 50%;
	left: 50%;
	width: 20vw;
	aspect-ratio: 0.75;
	transform: translate3d(-50%,-50%,0);
	background-color: #f0f0f0;
	animation: loaderAnim 1s linear infinite alternate forwards;

}

@keyframes loaderAnim {
	to {
		background-color: #ccc;
	}
}

a {
	text-decoration: none;
	color: var(--color-link);
	outline: none;
	cursor: pointer;
}

a:hover {
	color: var(--color-link-hover);
	outline: none;
}

/* Better focus styles from https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible */
a:focus {
	/* Provide a fallback style for browsers
	 that don't support :focus-visible */
	outline: none;
	background: lightgrey;
}

a:focus:not(:focus-visible) {
	/* Remove the focus indicator on mouse-focus for browsers
	 that do support :focus-visible */
	background: transparent;
}

a:focus-visible {
	/* Draw a very noticeable focus style for
	 keyboard-focus on browsers that do support
	 :focus-visible */
	outline: 2px solid red;
	background: transparent;
}

.unbutton {
	background: none;
	border: 0;
	padding: 0;
	margin: 0;
	font: inherit;
	color: inherit;
	cursor: pointer;
}

.unbutton:focus {
	outline: none;
}

main {
	display: grid;
	grid-template-areas: 'main';
	position: relative;
	width: 100%;
	height: 100vh;
	overflow: hidden;
	place-items: center;
}

.frame {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	color: var(--color-title);
	padding: 1rem;
	font-size: 13px;
	font-weight: 600;
	display: grid;
	grid-template-columns: 100%;
	grid-template-areas: 'title' 'demos' 'credits' 'sponsor';
	justify-content: start;
	align-content: space-between;
	align-items: start;
	z-index: 100;
	pointer-events: none;
	grid-gap: 0.5rem;
}

.frame a {
	pointer-events: auto;
}

.frame a:not(.frame__demo) {
	white-space: nowrap;
	overflow: hidden;
	position: relative;
}

.frame a:not(.frame__demo)::before {
	content: '';
	height: 1px;
	width: 100%;
	background: currentColor;
	position: absolute;
	top: 90%;
	transition: transform 0.3s;
	transform-origin: 0% 50%;
}

.frame a:not(.frame__demo):hover::before {
	transform: scaleX(0);
	transform-origin: 100% 50%;
}

.frame__title {
	grid-area: title;
	display: flex;
	align-items: flex-end;
}

.frame strong {
	font-weight: 800;
}

.frame__title-main {
	font-size: inherit;
	margin: 0;
	font-weight: inherit;
}

.frame__demos {
	grid-area: demos;
}

a.frame__demo {
	margin: 0 0 0 1rem;
	text-decoration: none;
}

.frame__demo--current {
	font-weight: bold;
	color: var(--color-link-hover);
}

.frame__credits {
	grid-area: credits;
	display: flex;
	gap: 1rem;
}

.type {
	grid-area: main;
	display: grid;
	place-items: center;
	pointer-events: none;
	z-index: 100;
}

.type__item {
	text-align: center;
	font-size: clamp(2rem, 14vw, 7rem);
	grid-area: 1 / 1 / -1 / -1;
	opacity: 0;
	line-height: 1.5;
}

.type__item--current {
	opacity: 1;
}

.char-wrap {
	display: inline-block;
	position: relative;
	overflow: hidden;
	display: inline-flex;
}

.type__item.splitting .char {
	line-height: 1.5;
	padding-bottom: 0.3em;
}

.slider {
	grid-area: main;
	position: relative;
	overflow: hidden;
	display: grid;
	place-items: center;
	width: 100%;
	height: 100vh;
}

.slider__item {
	grid-area: 1 / 1 / -1 / -1;
	position: relative;
	width: 100%;
	height: 100%;
	overflow: hidden;
	display: grid;
	place-items: center;
	opacity: 0;
	pointer-events: none;
}

.slider__item--current {
	opacity: 1;
	pointer-events: auto;
	z-index: 50;
}

.slider__item-inner {
	position: relative;
	width: 120%;
	height: 120%;
	display: grid;
	place-items: center;
	grid-area: 1 / 1 / -1 / -1;
	background-size: cover;
	background-position: 50% 50%;
}

.slider--bg {
	z-index: 1;
}

.demo-2 .slider--bg {
	-webkit-filter: contrast(0.6) saturate(2);
	filter: contrast(0.6) saturate(2);
}

.slider--fg {
	position: absolute;
	width: 20vw;
	min-width: 200px;
	aspect-ratio: 0.75;
	height: auto;
	z-index: 2;
}

.content {
	width: 100vw;
	height: 100vh;
	overflow: hidden;
	position: relative;
} 

.content-open .content {
	overflow: auto;
}

.content__inner {
	position: relative;
	display: grid;
	gap: 4vh;
	padding: 8rem 10vw 0;
	max-width: 1200px;
}

.content__title {
	font-size: clamp(3rem,9vw,20rem);
	font-weight: 600;
	margin: 0;
	line-height: 1;
}

.content__subtitle {
	font-size: 1rem;
	font-weight: 600;
	margin: 0;
}

.content__text {
	margin-top: 10vh;
	max-width: 500px;
}

.slider-nav {
	position: fixed;
	padding: 1rem;
	width: 100%;
	line-height: 1;
	display: grid;
	grid-template-areas: 'prev next';
	bottom: 0;
	right: 0;
	z-index: 2;
	justify-content: space-between;
}

.slider-nav__item {
	line-height: 1.5;
	position: relative;
	text-transform: lowercase;
	display: block;
	font-size: clamp(1rem,6vw,3rem);
	transition: opacity 0.3s;
}

.slider-nav__item span {
	display: inline-block;
	pointer-events: none;
}

.slider-nav__item:hover {
	opacity: 0.5;
}

.slider-nav__item--prev {
	grid-area: prev;
}

.slider-nav__item--next {
	grid-area: next;
}

.content-open .slider-nav__item--next,
.content-open .slider-nav__item--prev,
.slider-nav__item--back {
	opacity: 0;
	pointer-events: none;
}

.slider-nav__item--back {
	grid-area: next;
}

.content-open .slider-nav__item--back {
	pointer-events: auto;
	opacity: 1;
}

@media screen and (min-width: 53em) {
	.frame { 
		height: 100vh; 
		grid-gap: 2rem;
		grid-template-columns: auto auto 1fr;
		grid-template-rows: auto auto;
		grid-template-areas: 'title demos sponsor' 'credits ... ... ';
	}
	.frame__demos {
		justify-self: end;
	}
	.slider-nav {
		justify-content: end;
		width: auto;
		padding: 2rem;
		grid-template-areas: 'prev' 'next';
		justify-items: end;
	}
	.slider-nav__item {
		line-height: 1;
	}
	.slider-nav__item--prev {
		margin-right: 5vw;
	}
}
index.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Double Slideshow | Demo 1 | Codrops</title>
		<meta name="author" content="Codrops" />
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="stylesheet" href="https://use.typekit.net/hsc1xzg.css">
		<link rel="stylesheet" type="text/css" href="css/base.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting-cells.css" />
		<script>document.documentElement.className="js";</script>
		<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
	</head>
	<body class="demo-1 loading">
		<main>
			<div class="frame">
				<div class="frame__title"> 
					<h1 class="frame__title-main"><strong>Zoom Slideshow</strong> inspired by <a href="https://dribbble.com/shots/18201219-Exo-Ape-Case-Hero-Header">Exo Ape Case Hero</a></h1> 
				</div>
				<nav class="frame__demos">
					<span>Demos: </span>
					<a href="index.html" class="frame__demo frame__demo--current">1</a>
					<a href="index2.html" class="frame__demo">2</a>
				</nav>
				<span class="frame__credits">
					<a href="http://tympanus.net/Development/GooeyCursor/">Previous demo</a>
					<a href="https://tympanus.net/codrops/?p=72565">Article</a>
				</span>
			</div>
			<div class="slider slider--bg">
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/1.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/2.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/3.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/4.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/5.jpg)"></div></div>
			</div>
			<div class="slider slider--fg">
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/1-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/2-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/3-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/4-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/5-small.jpg)"></div>
				</div>
			</div>
			<div class="type">
				<div class="type__item">Kai Taigu</div>
				<div class="type__item">Sibel Çetin</div>
				<div class="type__item">Aoife Kelly</div>
				<div class="type__item">Kwame Appiah</div>
				<div class="type__item">Marta Sobczak</div>
			</div>
			<nav class="slider-nav">
				<button class="unbutton slider-nav__item slider-nav__item--prev"><span>Prev</span></button>
				<button class="unbutton slider-nav__item slider-nav__item--next"><span>Next</span></button>
				<button class="unbutton slider-nav__item slider-nav__item--back"><span>Back</span></button>
			</nav>
		</main>
		<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/Observer.min.js"></script>
		<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
		<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
		<script type="module" src="js/index.js"></script>
	</body>
</html>
index2.html
파일 저장

<!DOCTYPE html>
<html lang="en" class="no-js">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Double Slideshow | Demo 2 | Codrops</title>
		<meta name="author" content="Codrops" />
		<link rel="shortcut icon" href="favicon.ico">
		<link rel="stylesheet" href="https://use.typekit.net/hsc1xzg.css">
		<link rel="stylesheet" type="text/css" href="css/base.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting.css" />
		<link rel="stylesheet" href="https://unpkg.com/splitting/dist/splitting-cells.css" />
		<script>document.documentElement.className="js";</script>
		<script src="//tympanus.net/codrops/adpacks/analytics.js"></script>
	</head>
	<body class="demo-2 loading">
		<main>
			<div class="frame">
				<div class="frame__title"> 
					<h1 class="frame__title-main"><strong>Double Slideshow</strong> inspired by <a href="https://dribbble.com/shots/18201219-Exo-Ape-Case-Hero-Header">Exo Ape Case Hero</a></h1> 
				</div>
				<nav class="frame__demos">
					<span>Demos: </span>
					<a href="index.html" class="frame__demo">1</a>
					<a href="index2.html" class="frame__demo frame__demo--current">2</a>
				</nav>
				<span class="frame__credits">
					<a href="http://tympanus.net/Development/GooeyCursor/">Previous demo</a>
					<a href="https://tympanus.net/codrops/?p=72565">Article</a>
				</span>
			</div>
			<div class="slider slider--bg">
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/6.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/7.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/8.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/9.jpg)"></div></div>
				<div class="slider__item"><div class="slider__item-inner" style="background-image:url(img/10.jpg)"></div></div>
			</div>
			<div class="slider slider--fg">
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/6-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/7-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/8-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/9-small.jpg)"></div>
				</div>
				<div class="slider__item">
					<div class="slider__item-inner" style="background-image:url(img/10-small.jpg)"></div>
				</div>
			</div>
			<div class="type">
				<div class="type__item">Sophie Dupont</div>
				<div class="type__item">Jean Gomez</div>
				<div class="type__item">Katia Ivanova</div>
				<div class="type__item">Adaora Musa</div>
				<div class="type__item">Mia Petković</div>
			</div>
			<nav class="slider-nav">
				<button class="unbutton slider-nav__item slider-nav__item--prev"><span>Prev</span></button>
				<button class="unbutton slider-nav__item slider-nav__item--next"><span>Next</span></button>
				<button class="unbutton slider-nav__item slider-nav__item--back"><span>Back</span></button>
			</nav>
		</main>
		<script src="https://tympanus.net/codrops/adpacks/cda_sponsor.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
		<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/Observer.min.js"></script>
		<script src="https://unpkg.com/imagesloaded@5/imagesloaded.pkgd.min.js"></script>
		<script src="https://unpkg.com/splitting/dist/splitting.min.js"></script>
		<script src="js/index2.js"></script>
	</body>
</html>
js/index.js
파일 저장


// Helpers
const wrapElements = (elems, wrapType, wrapClass) => {
    elems.forEach(char => {
        const wrapEl = document.createElement(wrapType);
        wrapEl.classList = wrapClass;
        char.parentNode.appendChild(wrapEl);
        wrapEl.appendChild(char);
    });
}

// Slideshow class
class Slider {
    #current = 0;
    constructor(element, reverseDirection = false) {
        this.element = element;
        // Reverse direction
        this.reverseDirection = reverseDirection;
        this.items = [...this.element.querySelectorAll('.slider__item')];
        this.itemsInner = this.items.map(item => item.querySelector('.slider__item-inner'));
        // Set current
        this.items[this.current].classList.add('slider__item--current');
        // Total items
        this.itemsTotal = this.items.length;
        gsap.set([this.items, this.itemsInner], {'will-change': 'transform'});
    }
    next() {
        this.navigate(1);
    }
    prev() {
        this.navigate(-1);
    }
    get current() {
        return this.#current;
    }
    set current(value) {
        this.#current = value;
    }
    // direction: 1 || -1 (next || prev)
    navigate(direction) {
        
        if ( this.isAnimating ) return false;
        this.isAnimating = true;
        
        const previous = this.current;
        this.current = direction === 1 ? 
                            this.current < this.itemsTotal - 1 ? ++this.current : 0 :
                            this.current > 0 ? --this.current : this.itemsTotal - 1

        const currentItem = this.items[previous];
        const currentInner = this.itemsInner[previous];
        const upcomingItem = this.items[this.current];
        const upcomingInner = this.itemsInner[this.current];
        
        gsap
        .timeline({
            defaults: {duration: 1.1, ease: 'power3.inOut'},
            onComplete: () => {
                this.items[previous].classList.remove('slider__item--current');
                this.items[this.current].classList.add('slider__item--current');

                this.isAnimating = false;
            }
        })
       
        .to(currentItem, {
            yPercent: this.reverseDirection ? direction*100 : -direction*100,
            onComplete: () => gsap.set(currentItem, {opacity: 0})
        })
        .to(currentInner, {
            yPercent: this.reverseDirection ? -direction*30 : direction*30,
            startAt: {
                rotation: 0
            },
            rotation: -direction*15,
            scaleY: 2.8
        }, 0)
        .to(upcomingItem, {
            startAt: { 
                opacity: 1, 
                yPercent: this.reverseDirection ? -direction*80 : direction*80 
            },
            yPercent: 0
        }, 0)
        .to(upcomingInner, {
            startAt: {
                yPercent: this.reverseDirection ? direction*30 : -direction*30, 
                scaleY: 2.8, 
                rotation: direction*15
            },
            yPercent: 0,
            scaleY: 1,
            rotation: 0
        }, 0);

    }
}

// navigation controls
const navigation = {
    'next': document.querySelector('.slider-nav > .slider-nav__item--next'),
    'prev': document.querySelector('.slider-nav > .slider-nav__item--prev'),
    'back': document.querySelector('.slider-nav > .slider-nav__item--back')
};

// Background slider
const sliderBG = new Slider(document.querySelector('.slider--bg'));

// Foreground slider (passing true as the second argument to reverse the animation)
const sliderFG = new Slider(document.querySelector('.slider--fg'), true);

// Titles
const titles = [...document.querySelectorAll('.type > .type__item')];

// Set current title
titles[0].classList.add('type__item--current');

// Apply Splitting (https://splitting.js.org/)
titles.forEach(title => title.dataset.splitting = '');
Splitting();

// All chars
const chars = titles.map(title => {
    const titleChars = title.querySelectorAll('.char');
    // Wrap each char in a overflow hidden wrapper
    wrapElements(titleChars, 'span', 'char-wrap');
    return titleChars;
});
gsap.set([titles, chars], {'will-change': 'transform'});

// Navigation
const navigate = action => {
    toggleTitle(action);
    sliderBG[action]();
    sliderFG[action]();
}; 

// Switch titles
const toggleTitle = action => {
    
    if ( sliderBG.isAnimating ) return false;
    
    const current = sliderBG.current;
    const titleCurrentLetters = chars[current];

    const upcoming = action === 'next' ? 
        current < sliderBG.itemsTotal - 1 ? current+1 : 0 :
        current > 0 ? current-1 : sliderBG.itemsTotal - 1;

    const titleUpcomingLetters = chars[upcoming];

    // change title
    const duration = 1.1;
    // reverse logic for the previous action
    const reverse = action === 'next' ? -1 : 1;
    
    gsap
    .timeline({
        defaults: {duration: duration, ease: 'power3.inOut'},
        onStart: () => {
            titles[upcoming].classList.add('type__item--current');
        },
        onComplete: () => {
            titles[current].classList.remove('type__item--current');
        }
    })
    .to(titles[current], {
        startAt: {
            transformOrigin: action === 'next' ? '-50% 100%' : '-50% 0%'
        },
        yPercent: reverse*10,
        rotate: reverse*25
    })
    .to(titleCurrentLetters, {
        duration: duration/2,
        ease: 'power3.in',
        startAt: {
            transformOrigin: action === 'next' ? '50% 100%' : '50% 0%'
        },
        yPercent: reverse*50,
        scaleY: 2
    }, 0)
    .to(titleCurrentLetters, {
        duration: duration/2,
        ease: 'expo',
        yPercent: reverse*100,
        scaleY: 1
    }, duration/2)

    .to(titles[upcoming], {
        startAt: {
            transformOrigin: action === 'next' ? '-50% 0%' : '-50% 100%', 
            yPercent: reverse*-10, 
            rotate: reverse*-25
        },
        yPercent: 0,
        rotate: 0
    }, 0)
    .to(titleUpcomingLetters, {
        duration: duration/2,
        ease: 'power3.in',
        startAt: {
            transformOrigin: action === 'next' ? '50% 0%' : '50% 100%', 
            yPercent: reverse*-100, 
            scaleY: 1
        },
        yPercent: reverse*-50,
        scaleY: 2
    }, 0)
    .to(titleUpcomingLetters, {
        duration: duration/2,
        ease: 'expo',
        yPercent: 0,
        scaleY: 1
    }, duration/2);

}
navigation.next.addEventListener('click', () => navigate('next'));
navigation.prev.addEventListener('click', () => navigate('prev'));

Observer.create({
    target: window,         // can be any element (selector text is fine)
    type: "wheel,touch,scroll,pointer",    // comma-delimited list of what to listen for ("wheel,touch,scroll,pointer")
    onUp : () => navigate('next'), 
    onDown : () => navigate('prev'),
    wheelSpeed: -1
});

// Preload images
imagesLoaded(document.querySelectorAll('.slider__item-inner'), {background: true}, () => document.body.classList.remove('loading'));
js/index2.js
파일 저장


// Helpers
const wrapElements = (elems, wrapType, wrapClass) => {
    elems.forEach(char => {
        const wrapEl = document.createElement(wrapType);
        wrapEl.classList = wrapClass;
        char.parentNode.appendChild(wrapEl);
        wrapEl.appendChild(char);
    });
}

// Slideshow class
class Slider {
    #current = 0;
    constructor(element, reverseDirection = false) {
        this.element = element;
        // Reverse direction
        this.reverseDirection = reverseDirection;
        this.items = [...this.element.querySelectorAll('.slider__item')];
        this.itemsInner = this.items.map(item => item.querySelector('.slider__item-inner'));
        // Set current
        this.items[this.current].classList.add('slider__item--current');
        // Total items
        this.itemsTotal = this.items.length;
        gsap.set([this.items, this.itemsInner], {'will-change': 'transform'});
    }
    next() {
        this.navigate(1);
    }
    prev() {
        this.navigate(-1);
    }
    get current() {
        return this.#current;
    }
    set current(value) {
        this.#current = value;
    }
    // direction: 1 || -1 (next || prev)
    navigate(direction) {
        
        if ( this.isAnimating ) return false;
        this.isAnimating = true;
        
        const previous = this.current;
        this.current = direction === 1 ? 
                            this.current < this.itemsTotal - 1 ? ++this.current : 0 :
                            this.current > 0 ? --this.current : this.itemsTotal - 1

        const currentItem = this.items[previous];
        const currentInner = this.itemsInner[previous];
        const upcomingItem = this.items[this.current];
        const upcomingInner = this.itemsInner[this.current];
        
        gsap
        .timeline({
            defaults: {duration: 1.1, ease: 'power3.inOut'},
            onComplete: () => {
                this.items[previous].classList.remove('slider__item--current');
                this.items[this.current].classList.add('slider__item--current');

                this.isAnimating = false;
            }
        })
       
        .to(currentItem, {
            xPercent: this.reverseDirection ? direction*100 : -direction*100,
            onComplete: () => gsap.set(currentItem, {opacity: 0})
        })
        .to(currentInner, {
            xPercent: this.reverseDirection ? -direction*30 : direction*30,
            startAt: {
                rotation: 0
            },
            rotation: -direction*20,
            scaleX: 2.8
        }, 0)
        .to(upcomingItem, {
            startAt: { 
                opacity: 1, 
                xPercent: this.reverseDirection ? -direction*80 : direction*80 
            },
            xPercent: 0
        }, 0)
        .to(upcomingInner, {
            startAt: {
                xPercent: this.reverseDirection ? direction*30 : -direction*30, 
                scaleX: 2.8, 
                rotation: direction*20
            },
            xPercent: 0,
            scaleX: 1,
            rotation: 0
        }, 0);

    }
}

// navigation controls
const navigation = {
    'next': document.querySelector('.slider-nav > .slider-nav__item--next'),
    'prev': document.querySelector('.slider-nav > .slider-nav__item--prev'),
    'back': document.querySelector('.slider-nav > .slider-nav__item--back')
};

// Background slider
const sliderBG = new Slider(document.querySelector('.slider--bg'));

// Foreground slider (passing true as the second argument to reverse the animation)
const sliderFG = new Slider(document.querySelector('.slider--fg'), true);

// Titles
const titles = [...document.querySelectorAll('.type > .type__item')];

// Set current title
titles[0].classList.add('type__item--current');

// Apply Splitting (https://splitting.js.org/)
titles.forEach(title => title.dataset.splitting = '');
Splitting();

// All chars
const chars = titles.map(title => {
    const titleChars = title.querySelectorAll('.char');
    // Wrap each char in a overflow hidden wrapper
    wrapElements(titleChars, 'span', 'char-wrap');
    return titleChars;
});
gsap.set([titles, chars], {'will-change': 'transform'});

// Navigation
const navigate = action => {
    toggleTitle(action);
    sliderBG[action]();
    sliderFG[action]();
}; 

// Switch titles
const toggleTitle = action => {
    
    if ( sliderBG.isAnimating ) return false;

    const current = sliderBG.current;
    const titleCurrentLetters = chars[current];

    const upcoming = action === 'next' ? 
        current < sliderBG.itemsTotal - 1 ? current+1 : 0 :
        current > 0 ? current-1 : sliderBG.itemsTotal - 1;

    const titleUpcomingLetters = chars[upcoming];

    // change title
    const duration = 1.1;
    // reverse logic for the previous action
    const reverse = action === 'next' ? -1 : 1;
    
    gsap
    .timeline({
        defaults: {duration: duration, ease: 'power4.inOut'},
        onStart: () => {
            titles[upcoming].classList.add('type__item--current');
        },
        onComplete: () => {
            gsap.set(titles[current], {opacity: 0})
            titles[current].classList.remove('type__item--current');
        }
    })
    .set(titles[upcoming], {opacity: 0}, 0)
    .to(titles[current], {
        xPercent: reverse*40
    })
    .to(titleCurrentLetters, {
        xPercent: reverse*103,
    }, 0)
    .addLabel('in', duration*.15, 0)
    .set(titles[upcoming], {opacity: 1}, 'in')
    .to(titles[upcoming], {
        startAt: {
            xPercent: reverse*-40
        },
        xPercent: 0
    }, 'in')
    .to(titleUpcomingLetters, {
        startAt: {
            xPercent: reverse*-103, 
        },
        xPercent: 0
    }, 'in');

}
navigation.next.addEventListener('click', () => navigate('next'));
navigation.prev.addEventListener('click', () => navigate('prev'));

Observer.create({
    target: window,         // can be any element (selector text is fine)
    type: "wheel,touch,scroll,pointer",    // comma-delimited list of what to listen for ("wheel,touch,scroll,pointer")
    onUp : () => navigate('next'), 
    onDown : () => navigate('prev'),
    wheelSpeed: -1
});

// Preload images
imagesLoaded(document.querySelectorAll('.slider__item-inner'), {background: true}, () => document.body.classList.remove('loading'));
Media credits and license evidence실행 안내·자료
파일 저장

README.md
## Credits

- Images from [Unsplash](https://unsplash.com/)


## License

[MIT](LICENSE)

Made with :blue_heart:  by [Codrops](http://www.codrops.com)
LICENSE실행 안내·자료
파일 저장

MIT License

Copyright (c) 2009 - 2022 [Codrops](https://tympanus.net/codrops)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Bundled dependency licenses실행 안내·자료
파일 저장

https://cdn.jsdelivr.net/npm/splitting@1.1.0/LICENSE.md
MIT License

Copyright (c) 2018 Stephen Shaw

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


https://cdn.jsdelivr.net/npm/imagesloaded@5.0.0/LICENSE.md
Copyright (c) 2011-2022 [David DeSandro](https://desandro.com) and [contributors](https://github.com/desandro/imagesloaded/graphs/contributors)

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


GSAP standard license snapshot
Source: https://gsap.com/community/standard-license/
Retrieved: 2026-09-22T04:22:49.089Z
Original distribution copyright and version headers remain in the runtime code.

Standard "No Charge" GSAP License

 I. DEFINITIONS

 “GSAP License” means the terms and conditions of this GSAP Software License Agreement.

 "GSAP Products" means any Software made available at gsap.com (https://gsap.com) or any successor sites, including but not limited to the GSAP animation library and related plugins, tools, or extensions.

 "Permitted Uses" means the implementation and/or use of GSAP Products on any website, web application, or digital interface by any person or entity (which may include, for clarity, those of companies that compete with Webflow in other areas of business).

 "Prohibited Uses" means any implementation and/or use of GSAP Products in tools that allow users to build visual animations without code that encourages, induces, or materially assists in creating a solution that competes with Webflow’s visual animation building capabilities.

 "Competitive Products" means any software, tool, or service that enables users to create, edit, or manage animations through a visual interface or builder similar to Webflow (https://webflow.com).

 II. GRANT OF LICENSE

 Subject to the terms and conditions of this GSAP License, Webflow grants you a non-exclusive, worldwide license to use, reproduce, display, and implement GSAP Products solely for Permitted Uses.

 III. RESTRICTIONS

 You may not:

 Use any GSAP Products for any Prohibited Uses without prior written consent;

 Reverse engineer any GSAP Products for the purpose of creating Competitive Products;

 Remove or alter any proprietary notices or branding from GSAP Products.

 IV. OWNERSHIP AND INTELLECTUAL PROPERTY

 All intellectual property rights in GSAP Products, including but not limited to copyright, patents, trademarks, and trade secrets, remain the exclusive property of Webflow. This GSAP License does not transfer any ownership rights in GSAP Products to you.

 V. TERMINATION

 Webflow may terminate this GSAP License and revoke your access in its discretion if you fail to comply with any of these terms and conditions. Upon termination, you must cease all use of GSAP Products and destroy all copies in your possession.

 VI. MISCELLANEOUS PROVISIONS

 General: This GSAP License is incorporated into and subject to Webflow’s Terms of Service available here (https://webflow.com/legal/terms) ("Terms of Service"). In the event of any conflict or inconsistency between this GSAP License and the Terms of Service, the terms of this GSAP License shall govern in relation to your use of any GSAP Products.

 Amendments: Webflow reserves the right to update or modify this GSAP License at any time by posting the revised terms on this website, provided that any such updates or modifications shall not result in any material degradation to the security, integrity, or functionality of any GSAP Products. You understand and agree that your continued use of any GSAP Products after such revisions to this GSAP License constitutes your acceptance of this GSAP License as revised. If you do not accept the revised GSAP License, you are prohibited from using versions of the GSAP Products released after the effective date of the revised GSAP License (as well as any updates made to previous versions). Notwithstanding, you may continue using previous versions of GSAP Products under the applicable terms licensed to you prior to the effective date of the revised GSAP License (for clarity, excluding any updates made thereto).

 No Waiver: Failure of Webflow to enforce any provision of this GSAP License shall not constitute a waiver of future enforcement of that or any other provision.

 FAQ

 Is it acceptable for AI tools like ChatGPT, Cursor, Lovable, Webstudio, etc. to generate GSAP code?
 Absolutely! AI-generated code is not a "Prohibited Use".

 What if a WordPress plugin or theme or other niche tool allows users to create GSAP-driven effects through a visual interface? Is that prohibited?
 We want to encourage developers to build on top of GSAP, including visual tools that don't directly compete with Webflow's rich animation-building capabilities. If you are not sure if your product might be considered a "Prohibited Use", feel free to contact us (https://gsap.com/contact) so we can talk through it!

 Can I really use GSAP in commercial projects without paying anything?
 Yes, really! Commercial usage is covered under the standard license. All of GSAP including the plugins that were formerly "members-only" like SplitText (https://gsap.com/docs/v3/Plugins/SplitText/) and MorphSVG (https://gsap.com/docs/v3/Plugins/MorphSVGPlugin) can be used in commercial projects at no charge. Enjoy! 💚

 Effective date: April 30, 2025

 Last modified date: May 30, 2025

 Copyright (©) 2025, Webflow