<div id="screen" class="loading-screen">
<svg
width="100%"
height="100vh"
viewBox="0 0 415 1261"
fill="none"
xmlns="http://www.w3.org/2000/svg"
id="mjb-logo-ani"
>
<path
id="keystone"
d="M234.07 15.29L224.77 31.99L215.46 48.71C214.626 50.2488 213.392 51.5338 211.888 52.4292C210.384 53.3247 208.666 53.7973 206.915 53.7973C205.165 53.7973 203.447 53.3247 201.943 52.4292C200.439 51.5338 199.204 50.2488 198.37 48.71L189.07 31.99L179.76 15.27C178.888 13.7119 178.43 11.9558 178.43 10.17C178.32 4.82998 182.87 -0.140026 188.31 -0.0200262H225.63C227.364 -0.002113 229.062 0.480466 230.547 1.37744C232.031 2.27442 233.248 3.55298 234.07 5.07997C234.949 6.63787 235.411 8.39628 235.411 10.185C235.411 11.9737 234.949 13.7321 234.07 15.29V15.29Z"
fill="#7A35BC"
/>
<!-- PURPLE OUTLINE -->
<path
class="purple-stroke"
id="outer-right-purple"
d="M253 25.78C336.18 44.54 399.52 123.11 402.52 208.1C402.52 228.95 402.52 536.22 402.52 548.9"
stroke-width="23"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="purple-stroke"
id="outer-left-purple"
d="M11.52 548.9V210.04C13.61 124.31 77.15 44.63 161 25.72"
stroke-width="23"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="purple-stroke"
id="outer-bottom-purple"
d="M18.52 526.99H395.51"
stroke-width="23"
stroke-miterlimit="10"
/>
<path
class="inner-purple purple-stroke"
id="inner-left-purple"
d="M48.4199 211.64C50.5199 136.35 107.87 70.49 182.13 59.3"
stroke-width="20"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="inner-purple purple-stroke"
id="inner-right-purple"
d="M364.62 211.64C362.52 136.35 305.17 70.49 230.91 59.3"
stroke-width="20"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="purple-stroke"
id="dome-purple"
fill-rule="evenodd"
clip-rule="evenodd"
d="M206.62 87.41C136.2 86.41 76.9901 148.8 79.9901 218.99H333.28C335.73 147.99 277.91 86.99 206.62 87.41Z"
stroke-width="5"
stroke-linejoin="round"
/>
<!-- WHITE OUTLINE -->
<path
class="white-stroke"
id="outer-bottom-white"
d="M18.52 526.99H395.51"
stroke-width="23"
stroke-miterlimit="10"
/>
<path
class="white-stroke"
id="dome-white"
fill-rule="evenodd"
clip-rule="evenodd"
d="M206.62 87.41C136.2 86.41 76.9901 148.8 79.9901 218.99H333.28C335.73 147.99 277.91 86.99 206.62 87.41Z"
stroke-width="5"
stroke-linejoin="round"
/>
<path
class="white-stroke"
id="outer-right-white"
d="M253 25.78C336.18 44.54 399.52 123.11 402.52 208.1C402.52 228.95 402.52 536.22 402.52 548.9"
stroke-width="23"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="white-stroke"
id="outer-left-white"
d="M11.52 548.9V210.04C13.61 124.31 77.15 44.63 161 25.72"
stroke-width="23"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="inner-white white-stroke"
id="inner-left-white"
d="M48.4199 211.64C50.5199 136.35 107.87 70.49 182.13 59.3"
stroke-width="20"
stroke-miterlimit="10"
stroke-linecap="round"
/>
<path
class="inner-white white-stroke"
id="inner-right-white"
d="M364.62 211.64C362.52 136.35 305.17 70.49 230.91 59.3"
stroke-width="20"
stroke-miterlimit="10"
stroke-linecap="round"
/>
</svg>
</div>
h1 {
color: white;
font-family: sans-serif;
text-align: center;
position: fixed;
top: 0;
width: 100%;
margin: 0 auto;
}
.white-stroke {
stroke: #fdfdfd;
}
.purple-stroke {
stroke: #7a35bc;
}
svg.static {
margin-top: 10vh;
}
body {
min-height: 100vh;
width: 100%;
background-color: #2a183c;
color: #fff;
margin:0;
}
Vue.createApp({
name: "LogoLoader",
props: {
onLoaded: Function,
},
data() {
return {
loaded: true,
viewBox: { x: 200, y: 0, width: 415, height: 561 + 700 },
viewBoxString: `-${415 / 2} ${0} ${415 + 0} ${561 + 700}`,
reduceMotion: window.matchMedia("(prefers-reduced-motion: reduce)")
.matches,
};
},
watch: {
loaded(val) {
if (val && this.reduceMotion) setTimeout(this.onLoaded, 1000);
},
},
mounted() {
if (!this.reduceMotion) {
var firstRepeat = false;
const timeline = gsap.timeline({
delay: 0.5,
defaults: {
y: this.viewBox.height * 0.05,
transformOrigin: "50% 50%",
},
onComplete: () => {
if (this.loaded && firstRepeat) {
finish.play();
} else {
firstRepeat = true;
gsap.delayedCall(0, () => timeline.play("loading"));
}
},
});
timeline
// Scale and Move the keystone into place
.from("#keystone", { scale: 50 }, "opening")
.fromTo(
"#keystone",
{ opacity: 0, y: this.viewBox.height },
{
opacity: 1,
duration: 1.2,
ease: "elastic.out(0.9, 0.5)",
},
"<"
)
// Make the keystone "glow"
.to(
"#keystone",
{ fill: "#CF9DFF", duration: 0.4, ease: "power2.in" },
">-0.25"
)
// Fade in the purple outline of the jukebox
.fromTo(
".purple-stroke",
{ opacity: 0 },
{ opacity: 1, duration: 0.85, ease: "power2.out" },
">-0.5"
)
// Begin "loading animation"
.addLabel("loading", ">")
// Stroke the outers white
.fromTo(
"#outer-right-white",
{ drawSVG: "0%" },
{ drawSVG: "35% 75%", duration: 0.5, ease: "power3.in" },
"loading"
)
.to(
"#outer-right-white",
{ drawSVG: "100% 100%", ease: "sine.out" },
">"
)
.fromTo(
"#outer-left-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "75% 35%", duration: 0.5, ease: "power3.in" },
"loading+=0.2"
)
.to("#outer-left-white", { drawSVG: "0", ease: "sine.out" }, ">")
// Stroke the inners white
.fromTo(
"#inner-left-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "85% 25%", duration: 0.5, ease: "power3.in" },
"loading+=0.6"
)
.to("#inner-left-white", { drawSVG: "0", ease: "sine.out" }, ">")
.fromTo(
"#inner-right-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "85% 25%", duration: 0.5, ease: "power3.in" },
"loading+=0.4"
)
.to("#inner-right-white", { drawSVG: "0", ease: "sine.out" }, ">")
// Stroke bottom and dome
.fromTo(
"#dome-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "85% 25%", duration: 0.5, ease: "power3.in" },
"loading+=0.7"
)
.to("#dome-white", { drawSVG: "0", ease: "sine.out" }, ">")
.fromTo(
"#outer-bottom-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "85% 25%", duration: 0.5, ease: "power3.in" },
"loading+=0.4"
)
.to("#outer-bottom-white", { drawSVG: "0", ease: "sine.out" }, ">");
const finish = gsap
.timeline({
paused: true,
onComplete: this.onLoaded,
})
.fromTo(
"#outer-right-white",
{ drawSVG: "0" },
{ drawSVG: "100%", duration: 1.5, ease: "power3.inOut" },
">-0.25"
)
.fromTo(
"#outer-left-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "100%", duration: 1.5, ease: "power3.inOut" },
"<"
)
.fromTo(
".inner-white",
{ drawSVG: "100% 100%" },
{ drawSVG: "100%", duration: 1, ease: "power3.inOut" },
">-0.85"
)
.fromTo(
"#outer-bottom-white",
{ drawSVG: "50% 50%" },
{ drawSVG: "100%", duration: 1, ease: "power3.inOut" },
"<"
)
.fromTo(
"#dome-white",
{ drawSVG: "50% 50%" },
{ drawSVG: "100%", duration: 0.75, ease: "power3.inOut" },
">-0.75"
)
.to(
"#keystone",
{ fill: "#7A35BC", duration: 0.8, ease: "power2.out" },
">-0.1"
);
} else {
document.getElementById("mjb-logo-ani").classList += "static";
}
}
}).mount("#screen")
This Pen doesn't use any external CSS resources.