Preloader and first screen animation (GSAP3)
in
Front-end | May 4, 2020

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&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&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; &: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&cs=tinysrgb&dpr=2&h=750&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.