Preloader and first screen animation (GSAP3)

in Front-end | May 4, 2020
How to create preloader with animation

Very often web developers face the task of creating a good preloader with animation. Today we will consider creating a small preloader animation and the first screen using GSAP3.

See the Pen Preloader and first screen animation (GSAP3) by Nikolay (@nikolay-gavrilov) on CodePen.dark

1.HTML structure

Add our structure. Previously, we prepared SVG for the preloader.

//Preloader
<div class="preloader">
  <div class="preloader_in">
    <svg id="a91af5f1-6059-4ab1-85eb-29d58781dfe4" data-name="Слой 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 143.44 162.51">
      <defs>
        <clippath id="bfe2ff6e-c323-4a8d-9051-2ac791407a11">
          <polygon id="fc94644d-1f28-4664-9935-99f7ce2a44cf" data-name="mask" points="106.26 0 4.26 0 6.32 96.85 18.69 149 94.93 149 104.14 78.09 106.26 0" style="fill:none"></polygon>
        </clippath>
      </defs>
      <g id="ea6db375-6f9f-4a0e-8b2c-90a9d3a6b43f" data-name="beer_group">
        <g style="clip-path:url(#bfe2ff6e-c323-4a8d-9051-2ac791407a11)">
          <g class="beer_body" data-name="beer">
            <path d="M55.26,161c-21.46,0-33.28-3-35.91-4.28-2.05-4.21-6.79-16.21-10.29-51.07C6.24,77.59,5.51,51.57,7.11,39H103.4a169.83,169.83,0,0,1,.83,22.25L104.15,66,104,70.72a610,610,0,0,1-6.07,63.53L97,139.92l-.11.56-.73,4c-2.5,13.81-4.41,10.71-5.11,12.24C88.38,158.08,76.57,161,55.26,161Z" style="fill:#ff9000"></path>
            <g id="f3e95bb7-16df-4d29-b524-1e2e79cd4f04" data-name="top_beer">
              <path d="M80.06,5.65H32.37a22.9,22.9,0,0,0-22.8,23V39.41a10.38,10.38,0,0,0,.77,4c2.06,5.06,9.56,3.51,9.56-2h0A12.7,12.7,0,0,1,32.55,28.65h70.31A22.9,22.9,0,0,0,80.06,5.65Z" style="fill:#fff"></path>
            </g>
            <path d="M68.58,80.29c-13.52,0-26-5.4-37-10.16a43,43,0,0,0-17.08-3.81,32.31,32.31,0,0,0-7.55.88c-.93-17.08-.86-31,.2-39.2H103.4a169.83,169.83,0,0,1,.83,22.25L104.15,55,104,59.72c-.1,2.57-.24,5.22-.39,7.91A115,115,0,0,0,91.1,73.09c-7.58,3.68-14.75,7.15-22.18,7.2Z" style="fill:#ffac00"></path>
            <path d="M49.33,115.36c-.59-.41-.07-1,.48-.9,1,.11,1-1.55,0-1.66a2.16,2.16,0,0,0-1.3,4C49.37,117.4,50.2,116,49.33,115.36Z" style="fill:#ff7a00"></path>
            <path d="M59.6,96.86c-.42-.3-.05-.69.35-.65.76.08.75-1.12,0-1.2A1.56,1.56,0,0,0,59,97.89C59.63,98.33,60.23,97.29,59.6,96.86Z" style="fill:#ff7a00"></path>
            <path d="M71.32,142.75c-.43-.29-.06-.68.34-.64.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C71.34,144.23,71.94,143.19,71.32,142.75Z" style="fill:#ff7a00"></path>
            <path d="M23.4,94.85c-.42-.3,0-.68.34-.64.76.07.75-1.13,0-1.2a1.55,1.55,0,0,0-.94,2.87C23.43,96.32,24,95.29,23.4,94.85Z" style="fill:#ff7a00"></path>
            <path d="M48.65,138.29c-.43-.29,0-.68.34-.64.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-1,2.88C48.68,139.77,49.28,138.73,48.65,138.29Z" style="fill:#ff7a00"></path>
            <path d="M88.43,127.46c-.43-.29-.05-.68.34-.64.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C88.46,128.93,89.06,127.9,88.43,127.46Z" style="fill:#ff7a00"></path>
            <path d="M79.53,114.08c-.42-.3,0-.68.34-.64.77.07.76-1.13,0-1.2a1.55,1.55,0,0,0-.94,2.87C79.56,115.55,80.16,114.52,79.53,114.08Z" style="fill:#ff7a00"></path>
            <path d="M30.3,110.55c-.43-.29-.05-.68.34-.64.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C30.33,112,30.93,111,30.3,110.55Z" style="fill:#ff7a00"></path>
            <path d="M50,92c-.42-.3,0-.69.35-.65.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C50,93.5,50.63,92.46,50,92Z" style="fill:#ff7a00"></path>
            <path d="M65.07,110.54c1,.14,1.48-1.47.43-1.61a2.1,2.1,0,0,0-2.33,2.75c.4,1,2,.55,1.6-.44C64.69,111.05,64.69,110.49,65.07,110.54Z" style="fill:#ff7a00"></path>
            <path d="M65.15,125.36a2,2,0,0,0-2.25,2.4.82.82,0,0,0,1.59-.43c0-.12.05-.39.23-.37C65.75,127.11,66.2,125.51,65.15,125.36Z" style="fill:#ff7a00"></path>
            <path d="M40.31,95.42a1.32,1.32,0,0,1-.4-.54c0-.16,0-.31,0-.34a.83.83,0,0,0,.84-1.43,1.67,1.67,0,0,0-2.33.74,2.47,2.47,0,0,0,.76,2.74C39.88,97.36,41.05,96.19,40.31,95.42Z" style="fill:#ff7a00"></path>
            <path d="M90.25,101.75a1.69,1.69,0,0,0-2,2.7c.78.71,2-.45,1.17-1.17,0,0-.24-.23,0-.1C90.34,103.7,91.18,102.27,90.25,101.75Z" style="fill:#ff7a00"></path>
            <path d="M40.22,63.51c-.59-.4-.08-.94.47-.89,1.05.11,1-1.55,0-1.66a2.16,2.16,0,0,0-1.3,4C40.25,65.55,41.09,64.12,40.22,63.51Z" style="fill:#ff7a00"></path>
            <path d="M95.91,36.84c-.42-.3,0-.69.34-.65.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C95.94,38.31,96.54,37.27,95.91,36.84Z" style="fill:#ff7a00"></path>
            <path d="M71.93,84.37c-.42-.3-.05-.68.34-.64.76.07.75-1.13,0-1.2a1.55,1.55,0,0,0-.94,2.87C72,85.84,72.56,84.8,71.93,84.37Z" style="fill:#ff7a00"></path>
            <path d="M24,74.53c-.43-.3-.05-.68.34-.64.76.07.75-1.13,0-1.2a1.55,1.55,0,0,0-.94,2.87C24.05,76,24.65,75,24,74.53Z" style="fill:#ff7a00"></path>
            <path d="M49.27,79.91c-.43-.3-.05-.68.34-.64.76.08.75-1.13,0-1.2a1.55,1.55,0,0,0-.94,2.87C49.29,81.38,49.89,80.35,49.27,79.91Z" style="fill:#ff7a00"></path>
            <path d="M95.54,67.44c-.43-.29-.06-.68.34-.64.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C95.56,68.91,96.16,67.88,95.54,67.44Z" style="fill:#ff7a00"></path>
            <path d="M80.15,55.7c-.43-.3-.05-.69.34-.65.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C80.18,57.17,80.78,56.13,80.15,55.7Z" style="fill:#ff7a00"></path>
            <path d="M30.92,52.17c-.43-.3-.05-.69.34-.65.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C31,53.64,31.55,52.6,30.92,52.17Z" style="fill:#ff7a00"></path>
            <path d="M75,40.19c-.43-.3-.06-.69.34-.65.76.08.75-1.12,0-1.2a1.56,1.56,0,0,0-.94,2.88C75,41.66,75.58,40.62,75,40.19Z" style="fill:#ff7a00"></path>
            <path d="M59.2,57.06c1,.14,1.48-1.46.43-1.6A2.1,2.1,0,0,0,57.3,58.2c.4,1,2,.55,1.59-.43C58.82,57.57,58.82,57,59.2,57.06Z" style="fill:#ff7a00"></path>
            <path d="M65.76,67a2,2,0,0,0-2.24,2.41.83.83,0,0,0,1.59-.44c0-.11,0-.39.22-.36C66.37,68.72,66.81,67.12,65.76,67Z" style="fill:#ff7a00"></path>
            <path d="M40.93,37a1.35,1.35,0,0,1-.4-.55c0-.15,0-.3,0-.33a.83.83,0,0,0,.84-1.43,1.67,1.67,0,0,0-2.33.74,2.42,2.42,0,0,0,.76,2.73C40.5,39,41.67,37.8,40.93,37Z" style="fill:#ff7a00"></path>
            <path d="M85.2,90.94a1.69,1.69,0,0,0-2,2.7c.79.72,2-.44,1.18-1.16,0,0-.25-.24,0-.11A.83.83,0,0,0,85.2,90.94Z" style="fill:#ff7a00"></path>
          </g>
        </g>
      </g>
      <g id="bd73dfd1-8d8a-4ac2-8739-3dd4e50aed18" data-name="glass">
        <path d="M137.87,64.28c-4.29-6.21-9.85-9.94-16.53-11.08a29.16,29.16,0,0,0-11.45.46c.18-11.61-.32-21.28-1.74-26.86a4.22,4.22,0,0,0-4.1-3.15H5.88a4.21,4.21,0,0,0-4.1,3.15c-6,23.66,4.45,120.46,13,129,9,9,71.45,9,80.43,0,2.34-2.34,4.83-11.36,7.08-23.69,17.68-5.62,31.54-17.63,37.87-33.2C145.23,86.36,144.4,73.74,137.87,64.28Zm-5.72,31.37c-4.85,11.92-15.06,21.4-28.25,26.69a570.59,570.59,0,0,0,5.74-59.7,22.11,22.11,0,0,1,10.27-.94c4.36.76,7.91,3.2,10.87,7.48C135.63,76.2,136.13,85.85,132.15,95.65ZM55,148.58c-21.1,0-32.73-2.89-35.31-4.17-2-4.11-6.68-15.81-10.12-49.8C6.76,67.24,6,41.87,7.61,29.61h94.7a163.71,163.71,0,0,1,.81,21.69l-.07,4.61-.18,4.63a591,591,0,0,1-6,62L96.05,128l-.11.54-.71,3.94c-2.47,13.46-4.34,10.44-5,11.94C87.54,145.73,75.92,148.58,55,148.58Z" style="fill:#fff"></path>
      </g>
    </svg>
  </div>
</div>
<section class="section">
//Background image
  <div class="section_bg_w">
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
    <div class="section_bg_item"></div>
  </div>
//Content
  <div class="section_content_col">
    <div class="hero_logo"><img class="logo" src="https://previews.dropbox.com/p/orig/AAwv4nabpjD9p7tk6wPCf9y7r9hObRF9Tszpw9tMpiXWVIfuivTcvJ7DjAIY_CWcOLcU2tUlk_uJhbCMCBBL6-mPbzWmcvvGE5C3sDE1Y569q9W2RwWs96VSVGUeeEJKwkTC9OwlVO4jSyVZS-PTxPn8sZYkTyu64exOrJk_-ZoQ49_CF4YhYwYUMvyZ7q0apBWHT-ugb32VZkUloBxV4xrnThOoGwFdrT48c0RXStuWiO312NiQPY5x7VAZFVG0T6lKazXU67HG9B2GrozUG_YQ69FLAEJQsqR7PBmxjXh9WrazwwI3NtSC_DqSy0C1igYSnII_Bt-OA3pReXwiQNvn/p.svg?fv_content=true&amp;size_mode=5" alt=""/></div>
  </div>
  <div class="section_content_col">
    <div class="section_contetn_w">
      <h1 class="section_title">12 сортов крафтового пива</h1>
      <div class="section_descr">
        <p>Все началось с мечты…. а теперь мы творим историю крафтового пива!</p>
      </div>
    </div>
  </div>
</section>

2.SCSS

Now add the styles.

@import url("https://fonts.googleapis.com/css2?family=Oswald:wght@300;700&amp;display=swap");

// vars
$font_1: "Oswald", sans-serif;
$point_t: 1024px;
$point_m: 768px;
$black: #000;
$white: #fff;
$body_bg: $black;

// mixins
@mixin bp($width, $direction: max) {
	@if $direction == min {
		@media screen and (min-width: $width) {
			@content;
		}
	} @else {
		@media screen and (max-width: $width) {
			@content;
		}
	}
}

@mixin flex_block(
	$flex-direction: row,
	$flex-wrap: wrap,
	$content: space-between,
	$align-items: flex-start,
	$align-content: flex-start
) {
	display: flex;
	flex-direction: $flex-direction;
	flex-wrap: $flex-wrap;
	justify-content: $content;
	align-content: $align-content;
	align-items: $align-items;
}

// base

* {
	box-sizing: border-box;
}

html {
	height: 100%;
	font: 400 calc(100vw / 1920 * 10) / 1.33 $font_1;

	overflow: hidden;

	@include bp($point_t) {
		font-size: 10px;
	}
}

body {
	position: relative;

	height: 100%;

	-webkit-text-size-adjust: none;
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;

	background: $body_bg;

	overflow: hidden;
}

//preloader
.preloader {
	z-index: 100;

	position: fixed;
	top: 0;
	left: 0;

	width: 100%;
	height: 100%;

	background-color: $body_bg;

	overflow: hidden;

	font-size: 1rem;
}

.preloader_in {
	position: absolute;
	top: 50%;
	left: 50%;

	width: 28em;
	height: 32em;
	margin: (-32em/2) 0 0 (-28em/2);

	opacity: 0;

	@include bp($point_t) {
		font-size: 0.7vh;
	}
}

.preloader_svg {
	position: absolute;
	top: 0;
	left: 0;

	width: 100%;
	height: 100%;
}

.beer_body {
	transform: translateY(16em);
}

// content
.section {
	position: relative;

	width: 100%;
	height: 100%;

	font-size: 1rem;

	@include flex_block(row, wrap, flex-start);
}

.section_bg_w {
	z-index: -1;

	position: absolute;
	top: 0;
	left: 0;

	width: 100%;
	height: 100%;

	overflow: hidden;

	&amp;:before {
		z-index: 1;

		position: absolute;
		top: 0;
		left: 0;

		content: "";

		width: 100%;
		height: 100%;

		background-color: $black;

		opacity: 0.4;
	}

	@include flex_block(row, wrap, flex-start);
}

.section_bg_item {
	position: relative;

	overflow: hidden;

	width: 20%;
	height: 25%;
	background-image: url(https://images.pexels.com/photos/3465604/pexels-photo-3465604.jpeg?auto=compress&amp;cs=tinysrgb&amp;dpr=2&amp;h=750&amp;w=1260);
	background-attachment: fixed;
	background-size: cover;
	background-position: center;
}

.section_content_col {
	position: relative;
	padding: 2em;

	overflow: hidden;

	@include flex_block(row, wrap, flex-start, center, center);

	@include bp($point_t, min) {
		width: 50%;
		height: 100%;
	}

	@media (max-width: $point_t) and (max-height: 1366px) {
		width: 100%;
		height: 50%;
		justify-content: center;
	}

	@include bp($point_t - 1) {
		width: 100%;
		height: 50%;
		justify-content: center;
	}
}

.hero_logo {
	width: 68em;
	height: 48em;
	margin: 0 auto;

	@media (min-width: $point_m) and (max-width: $point_t) {
		font-size: 0.8vw;
	}

	@include bp($point_m - 1) {
		font-size: 1vw;
	}

	@media (max-height: $point_m) {
		font-size: 0.7vh;
	}
}

.logo {
	display: block;
	width: 100%;
	height: 100%;

	object-fit: contain;
}

.section_contetn_w {
	width: 100%;
	margin: auto 0;

	@include bp($point_t + 1, min) {
		max-width: 68em;
	}

	@include bp($point_t - 1) {
		max-width: 80em;
	}
}

.section_title {
	margin: 0 0 (4em/8);

	width: 100%;
	color: $white;
	font-weight: 700;

	@include bp($point_t + 1, min) {
		font-size: 9.2em;
	}

	@include bp($point_t) {
		font-size: 5vh;
	}
}

.section_descr {
	width: 100%;

	color: $white;
	font-weight: 300;

	@include bp($point_t + 1, min) {
		font-size: 3em;
	}

	@include bp($point_t) {
		font-size: 4vh;
	}
}

3.JavaScript

Well, add our animation.

let p1 = false;

document.addEventListener("DOMContentLoaded", ready);

function ready() {
	// animation
	let tlBg = gsap.timeline({
		paused: p1,
		// delay: 1,
		defaults: { ease: "power4.out", duration: 0.6 }
	});

	tlBg
		.to(".preloader_in", {
			opacity: 1
		})
		.to(".beer_body", {
			duration: 1.2,
			y: 0
		})
		.addLabel("loader")
		.to(
			".preloader",
			{
				opacity: 0,
				pointerEvents: "none"
			},
			"loader"
		)
		.addLabel("start")
		.fromTo(
			".section_bg_item",
			{
				scale: 0,
				y: 60
			},
			{
				scale: 1,
				y: 0,
				stagger: {
					grid: [4, 6],
					from: "center",
					amount: 0.3
				}
			},
			"start-=.4"
		)
		.fromTo(
			".section_contetn_w",
			{
				x: "-60em",
				opacity: 0
			},
			{
				x: 0,
				opacity: 1
			},
			"start+=.2"
		)
		.fromTo(
			".hero_logo",
			{
				opacity: 0
			},
			{
				duration: 1,
				opacity: 1
			},
			"start+=.2"
		);
}

You can see the finished result here.