- const word = 'No Stress • No Worry •'

div.rotate
	div.circular.circular--solid(style='--shadow-color: #ababab; filter: blur(1px); opacity: 0.7;')
		each char, i in word.split('')
			span.text(data-idx=i)= char

div.rotate
	div.circular
		each char, i in word.split('')
			span.text(data-idx=i)= char



View Compiled
// todo: heavy refactoring

body {
	display: grid;
	justify-content: center;
	align-content: center;
	height: 100vh;
	
	overflow: hidden;
	background: #dadada;
	
	@media screen and (max-width: 1000px) {
		transform: scale(0.9);
	}
	
	@media screen and (max-width: 600px) {
		transform: scale(0.6);
	}
}

@function ease($t, $b, $c, $d) {
	// https://spicyyoghurt.com/tools/easing-functions
	// sine ease-out
	@return (-1 * $c) / 2 * (cos($PI * $t / $d) - 1) + $b;
}

@mixin rotated-text($num-letters: 14, $angle-span: 360deg, $kern: ()) {
	$angle-per-char: $angle-span / $num-letters;
	@for $i from 0 through $num-letters {
		$angle: $angle-per-char * $i;
		@if (map-has-key($kern, $i)) { $angle: map-get($kern, $i); }
		
		& > *[data-idx='#{$i}'] {
			height: 245px;
			transform: rotate($angle) scaleX(0.95);
			transform-origin: bottom center;
			line-height: 0;
		}
	}
}

.text {
	font-size: 6.5rem;
	font-family: Kanit, sans-serif;
	text-transform: uppercase;

	color: white;
	text-stroke: 2px var(--shadow-color, #282828);
	-webkit-text-stroke: 2px var(--shadow-color, #282828);
	letter-spacing: 3px;
	transform: scaleX(0.5);
	
	$shadows: 30;
	$steps: 25;
	animation: stagger 2.5s steps($steps) alternate infinite;

	@keyframes stagger {
		// for each time-step ($i/$step) of the animation...
		@for $i from 0 through $steps {
			$timestep: $i / $steps;
			
			// generate the layer of text shadows for each step of
			// the anim, placing each layer at some x-position using
			// an easing fn for the current time-step
			$text-shadow: null;
			@for $j from 1 through $shadows {
				$shadowstep: $j / $shadows;
				
				$text-shadow: (
					$text-shadow 
					#{ease($timestep, (-10px*$shadowstep), (20px*$shadowstep), 1)} (0.3px*$j) var(--shadow-color, #282828)
					#{if($j != $shadows, ',', '')}
				)
			}
			
			#{$timestep * 100}% {
				text-shadow: $text-shadow;
			}
		}
	}
}

.circular {
	width: 240px;
	height: 240px;
	border-radius: 100%;
	
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%) scale(var(--scale, 1));
	& > * {
		position: absolute;
		top: -50%; left: 33%;
	}
	
	@include rotated-text(22, 360deg, (
		1: 19deg,
		5: 81deg,
		6: 99deg,
		7: 117deg,
		8: 134deg,
		10: 154deg,
		12: 185deg,
		13: 205deg,
		15: 238deg,
		16: 257deg,
		17: 276deg,
		21: 337deg
	));
	
	&--solid {
		--scale: 0.9;
		--shadow-color: #d5d5d5;

		.text { color: var(--shadow-color); 	}
	}
}

.rotate {
	--delay: 0;
	
	animation: rotate 5s ease-in-out alternate infinite;
	animation-delay: var(--delay);
	@keyframes rotate {
		100% { transform: rotate(360deg); }
	}
}
View Compiled

External CSS

  1. https://fonts.googleapis.com/css2?family=Kanit:wght@900&family=Source+Sans+Pro:wght@400;600&display=swap
  2. https://github.com/terkel/mathsass/raw/master/dist/_constants.scss
  3. https://github.com/terkel/mathsass/raw/master/dist/helpers/_unitless-rad.scss
  4. https://github.com/terkel/mathsass/raw/master/dist/functions/_cos.scss

External JavaScript

This Pen doesn't use any external JavaScript resources.