| 1 | <template id="intro-template"> |
| 2 | <div |
| 3 | id="intro-comp" |
| 4 | data-composition-id="intro" |
| 5 | data-start="0" |
| 6 | data-duration="__VIDEO_DURATION__" |
| 7 | data-width="1920" |
| 8 | data-height="1080" |
| 9 | > |
| 10 | <div class="intro-container"> |
| 11 | <h1 class="title">HYPERFRAMES</h1> |
| 12 | </div> |
| 13 | |
| 14 | <style> |
| 15 | @import url("https://fonts.googleapis.com/css2?family=Nunito:wght@900&display=swap"); |
| 16 | |
| 17 | [data-composition-id="intro"] .intro-container { |
| 18 | width: 100%; |
| 19 | height: 100%; |
| 20 | display: flex; |
| 21 | justify-content: center; |
| 22 | align-items: center; |
| 23 | pointer-events: none; |
| 24 | } |
| 25 | |
| 26 | [data-composition-id="intro"] .title { |
| 27 | font-family: "Nunito", sans-serif; |
| 28 | font-weight: 900; |
| 29 | font-size: 180px; |
| 30 | color: #ff2d8a; /* Hot Pink */ |
| 31 | text-transform: uppercase; |
| 32 | transform: rotate(-5deg); /* Tilted 5 degrees */ |
| 33 | margin: 0; |
| 34 | padding: 20px; |
| 35 | /* Layered offset shadow for depth without suffocating letterforms */ |
| 36 | filter: drop-shadow(8px 8px 0 #ffffff) drop-shadow(15px 15px 0 rgba(0, 0, 0, 0.1)); |
| 37 | opacity: 0; |
| 38 | scale: 0; |
| 39 | } |
| 40 | </style> |
| 41 | |
| 42 | <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script> |
| 43 | <script> |
| 44 | (function () { |
| 45 | const tl = gsap.timeline({ paused: true }); |
| 46 | |
| 47 | // --- INTRO SEQUENCE --- |
| 48 | // Animation: Scale-up bounce (0% to 110% to 100%) with elastic overshoot |
| 49 | // Starts at 0.5s, lasts until 3s |
| 50 | tl.to('[data-composition-id="intro"] .title', { |
| 51 | opacity: 1, |
| 52 | scale: 1.1, |
| 53 | duration: 0.6, |
| 54 | ease: "back.out(1.7)", |
| 55 | delay: 0.5, |
| 56 | }) |
| 57 | .to('[data-composition-id="intro"] .title', { |
| 58 | scale: 1, |
| 59 | duration: 0.4, |
| 60 | ease: "elastic.out(1, 0.3)", |
| 61 | }) |
| 62 | // Ambient motion |
| 63 | .to( |
| 64 | '[data-composition-id="intro"] .title', |
| 65 | { |
| 66 | rotation: "-3deg", |
| 67 | duration: 1, |
| 68 | repeat: 1, |
| 69 | yoyo: true, |
| 70 | ease: "sine.inOut", |
| 71 | }, |
| 72 | "-=0.5", |
| 73 | ) |
| 74 | // Exit intro |
| 75 | .to( |
| 76 | '[data-composition-id="intro"] .title', |
| 77 | { |
| 78 | opacity: 0, |
| 79 | scale: 0.5, |
| 80 | duration: 0.3, |
| 81 | ease: "power2.in", |
| 82 | }, |
| 83 | 1.4, |
| 84 | ); |
| 85 | |
| 86 | // --- END CARD SEQUENCE --- |
| 87 | // Appears at 14.619s (after Moment 3 finishes exiting at 14.239 + 0.3) |
| 88 | tl.to( |
| 89 | '[data-composition-id="intro"] .title', |
| 90 | { |
| 91 | opacity: 1, |
| 92 | scale: 1.1, |
| 93 | duration: 0.6, |
| 94 | ease: "back.out(1.7)", |
| 95 | }, |
| 96 | 14.619, |
| 97 | ).to('[data-composition-id="intro"] .title', { |
| 98 | scale: 1, |
| 99 | duration: 0.4, |
| 100 | ease: "elastic.out(1, 0.3)", |
| 101 | }); |
| 102 | |
| 103 | window.__timelines = window.__timelines || {}; |
| 104 | window.__timelines["intro"] = tl; |
| 105 | })(); |
| 106 | </script> |
| 107 | </div> |
| 108 | </template> |
| 109 |