<div class="container">
<div class="text-container" data-text="HELLO" data-text-count="5">
</div>
<div class="text-container shadow-container" data-text="HELLO" data-text-count="5">
</div>
</div>
<svg class="icons">
<symbol id="star" viewBox="0 0 296.789 296.789">
<path
d="m 128.07699,246.6702 16.62278,44.87778 c 0.62488,1.68958 2.24042,2.81007 4.04647,2.81007 1.80605,0 3.42159,-1.12049 4.04646,-2.81007 l 16.62278,-44.87778 c 13.45522,-36.3312 42.2174,-64.97071 78.70166,-78.36601 l 45.06998,-16.55188 c 1.69428,-0.62221 2.81958,-2.23087 2.81958,-4.02922 0,-1.79835 -1.1253,-3.40699 -2.81958,-4.0292 l -45.07253,-16.5519 C 211.63034,113.74417 182.86815,85.107178 169.41548,48.778514 L 152.7927,3.900743 c -0.62487,-1.6870583 -2.24041,-2.8075483 -4.04646,-2.8075483 -1.80605,0 -3.42159,1.12049 -4.04647,2.8075483 L 128.07699,48.778514 C 114.62179,85.107178 85.862143,113.74417 49.375346,127.14199 l -45.0725171,16.5519 c -1.694284,0.62221 -2.819573,2.23085 -2.819573,4.0292 0,1.79835 1.125289,3.40701 2.819573,4.02922 l 45.0699771,16.55188 c 36.486798,13.3953 65.248984,42.03228 78.704184,78.36601 z" />
</symbol>
</svg>
<div class="support">
<a href="https://twitter.com/DevLoop01" target="_blank"><i class="fab fa-twitter-square"></i></a>
<a href="https://dribbble.com/devloop01" target="_blank"><i class="fab fa-dribbble"></i></a>
</div>
:root {
--size: 400px;
--word-length: 6;
--animation-duration: 2800ms;
--animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1.275);
--animation-iteration-count: infinite;
--font-size: 8rem;
--background: #afafaf;
--shadow-color: #9a9a9a;
--icon-size: 16px;
--icon-animation-duration: 1800ms;
--icon-animation-iteration-count: infinite;
--icon-animation-timing-function: ease;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
width: 100%;
height: 100vh;
background-color: var(--background);
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
.icons {
display: none;
}
.container {
position: relative;
width: var(--size);
height: var(--size);
.text-container,
.shadow-container {
position: relative;
width: 100%;
height: 100%;
display: grid;
place-items: center;
}
.text {
position: absolute;
height: 100%;
width: 60%;
display: flex;
flex-direction: column;
justify-content: center;
font-size: var(--font-size);
font-family: "Montserrat";
font-weight: 900;
user-select: none;
pointer-events: none;
.char {
text-transform: uppercase;
margin: 0 4px;
}
}
.text-container {
&:not(.shadow-container) {
.char {
-webkit-text-stroke: 1px #000;
}
}
.text {
.char-container {
$word-length: 5;
$delay: var(--delay);
position: relative;
color: var(--color);
width: 100%;
width: 100%;
animation-name: text-animation;
animation-duration: var(--animation-duration);
animation-iteration-count: var(--animation-iteration-count);
animation-timing-function: var(--animation-timing-function);
transform-origin: left bottom;
margin: -1.5rem 0;
@for $i from 1 through $word-length {
&:nth-child(#{$i}) {
animation-delay: calc(#{$delay} + (0.1s * #{$i}));
}
}
svg.icon {
position: absolute;
width: var(--icon-size);
height: var(--icon-size);
fill: #fff;
stroke: #000;
stroke-width: 15px;
transform: translate(-50%, -50%);
animation-name: scale-up-down;
animation-duration: var(--icon-animation-duration);
animation-iteration-count: var(--icon-animation-iteration-count);
animation-timing-function: var(--icon-animation-timing-function);
animation-delay: var(--icon-animation-delay);
z-index: 10;
}
&:nth-child(1) {
svg.icon {
left: 5%;
top: 40%;
}
}
&:nth-child(3) {
svg.icon {
left: 33%;
top: 65%;
}
}
&:nth-child(5) {
svg.icon {
left: 5%;
top: 50%;
}
}
}
}
}
.shadow-container {
margin-top: calc(-1 * (var(--size) - 8px));
margin-left: 8px;
z-index: -1;
.text {
color: var(--shadow-color);
.char-container {
svg.icon {
fill: var(--shadow-color);
stroke: transparent;
}
}
}
}
}
@keyframes text-animation {
0%,
20% {
transform: translateX(0%) rotate(0deg);
}
50%,
52% {
transform: translateX(100%) rotate(15deg);
}
80% {
transform: translateX(-10%) rotate(-5deg);
}
100% {
transform: translateX(0%) rotate(0deg);
}
}
@keyframes scale-up-down {
0% {
transform: translate(-50%, -50%) scale(1) rotate(0);
}
50% {
transform: translate(-50%, -50%) scale(1.5) rotate(90deg);
}
100% {
transform: translate(-50%, -50%) scale(1) rotate(180deg);
}
}
.support{
position: absolute;
right: 10px;
bottom: 10px;
padding: 10px;
display: flex;
a{
margin: 0 10px;
color: #333333;
font-size: 1.8rem;
backface-visibility: hidden;
transition: all 150ms ease;
&:hover{
transform: scale3d(1.1);
}
}
}
View Compiled
console.clear();
const textContainers = document.querySelectorAll(".text-container");
textContainers.forEach((textContainer) => {
let delay = 200; // in millisecond
let totalTextCount = textContainer.getAttribute("data-text-count");
let elText = textContainer.getAttribute("data-text");
for (let i = 0; i < totalTextCount; i++) {
let textEl = document.createElement("span");
textEl.className = "text";
for (let j = 0; j < elText.length; j++) {
let charContainerEl = document.createElement("span");
charContainerEl.className = "char-container";
charContainerEl.setAttribute("style", `--delay: ${delay - i * 50}ms`);
let charEl = document.createElement("span");
charEl.className = "char";
charEl.innerHTML = elText[j];
if (j % 2 == 0 && i == totalTextCount - 1) {
let iconContainierEl = document.createElement("span");
iconContainierEl.classList.add("icon-container");
let SVGEl = document.createElementNS("http://www.w3.org/2000/svg", "svg");
SVGEl.classList.add("icon", "star");
let SVGUseEl = document.createElementNS("http://www.w3.org/2000/svg", "use");
SVGUseEl.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#star");
SVGEl.setAttribute("style", `--icon-animation-delay: ${Math.random() * j * 200}ms`);
SVGEl.appendChild(SVGUseEl);
iconContainierEl.appendChild(SVGEl);
charContainerEl.appendChild(iconContainierEl);
}
charContainerEl.append(charEl);
textEl.append(charContainerEl);
}
textContainer.append(textEl);
}
});
const textArr = document.querySelectorAll(".text");
const colorArr = ["#fff", "#086BE2", "#E4002B", "#F5BA1C", "#000"];
textArr.forEach((text, index) => {
text.style.setProperty("--color", `${colorArr[colorArr.length - 1 - index]}`);
});