- const randomInRange = (min, max) => Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min) + 1) + Math.ceil(min));
-
const getHue = input => {
if (input > 0 && input <= 25) return 18
if (input > 25 && input <= 50) return 130
if (input > 50 && input <= 75) return 44
if (input > 75 && input <= 100) return 215
}
mixin section
section
if block
block
main
h1 Tap to replay
- const PARTICLE_COUNT = 14;
- const PARTICLES_PER_PEN = 30;
+section
.sling-ring.sling-ring--particles.sling-ring--particles-real(
style=`--particle-count: ${PARTICLE_COUNT}`
)
.sling-ring__ring.sling-ring__ring--particles
- let e = 0;
while e < PARTICLE_COUNT
.sling-ring__particle-pen(
style=`--index: ${e}; --base-delay: ${e / 5};`
)
.sling-ring__particle-start
- let pe = 0;
while pe < PARTICLES_PER_PEN
- const SIZE = randomInRange(10, 80);
- const DISTANCE = randomInRange(3, 7);
- const X = randomInRange(0, 100);
- const Y = randomInRange(0, 100);
- const ROTATION = randomInRange(-30, 0);
- const RADIUS = randomInRange(0, 50);
- const DELAY = randomInRange(0, 100) / 100;
- const HUE = getHue(Math.round((e / PARTICLE_COUNT) * 100));
- const LIGHTNESS = randomInRange(20, 90);
.sling-ring__particle(
style=`--radius: ${RADIUS}; --hue: ${HUE}; --lightness: ${LIGHTNESS}; --size: ${SIZE}; --distance: ${DISTANCE}; --x: ${X}; --y: ${Y}; --delay: ${DELAY}; --rotation: ${ROTATION};`
)
- pe++;
- e++;
img(src="https://assets.codepen.io/605876/come-see--square.gif")
View Compiled
@property --ring-reveal {
inherits: true;
initial-value: 0%;
syntax: '<percentage>';
}
:root {
--size: 35vmin;
--ring-thickness: calc(var(--size) * 0.2);
--red: #ff4d00;
--green: #38b24d;
--yellow: #ebb624;
--blue: #0f73ff;
--base-speed: 1;
}
*,
*:after,
*:before {
box-sizing: border-box;
}
body {
background: hsl(32 61% 94%);
display: grid;
place-items: center;
min-height: 100vh;
font-family: 'Google Sans', sans-serif, system-ui;
padding: 10vmin;
}
main {
width: 100%;
display: grid;
place-items: center;
}
h1 {
color: hsl(32 64% 66%);
position: fixed;
margin: 0;
font-family: 'Google Sans', sans-serif, system-ui;
bottom: 1rem;
right: 1rem;
}
section {
width: var(--size);
aspect-ratio: 1;
position: relative;
animation: scale-in calc(var(--base-speed) * 4s) both;
}
@keyframes scale-in {
0% {
transform: scale(0);
}
}
.sling-ring {
height: 100%;
aspect-ratio: 1;
position: relative;
}
.sling-ring__ring {
--base-rotation: -120deg;
--starting-point: calc(360 * -0.125deg);
--ring-reveal: 0%;
height: 100%;
width: 100%;
border-radius: 50%;
position: absolute;
transform: rotate(0deg);
border-color: var(--red) var(--green) var(--yellow) var(--blue);
mask: conic-gradient(from var(--starting-point), #000 var(--ring-reveal), transparent var(--ring-reveal));
-webkit-mask: conic-gradient(from var(--starting-point), #000 var(--ring-reveal), transparent var(--ring-reveal));
animation: reveal calc(var(--base-speed) * 1s) both ease-in, rotate 10s infinite linear;
z-index: 2;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
animation: fade-in calc(var(--base-speed) * 1s) calc(var(--base-speed) * 0.25s) ease-in both;
}
.sling-ring__ring--particles {
border: none;
-webkit-mask: none;
}
.sling-ring__particle-pen {
aspect-ratio: 1;
position: absolute;
inset: calc(var(--ring-thickness) * -1);
transform-origin: center;
transform: rotate(calc(((360 / var(--particle-count)) * var(--index)) * 1deg));
}
.sling-ring__particle-start {
position: absolute;
height: calc(var(--ring-thickness) * 1);
aspect-ratio: 1;
top: 0;
left: 50%;
transform: translate(-50%, 50%) rotate(-90deg);
background: rgba(255,0,0,0.2);
}
.sling-ring__particle {
height: calc(var(--size, 100) * 1%);
aspect-ratio: 1;
background: hsl(var(--hue, 280), 100%, calc(var(--lightness, 50) * 1%));
position: absolute;
top: calc(var(--x, 50) * 1%);
left: calc(var(--y, 50) * 1%);
animation: blast 0.85s infinite both ease-out, fade-away 0.85s infinite both;
animation-delay: calc((var(--base-delay, 0) + var(--delay, 0)) * 1s);
}
.sling-ring--particles-real .sling-ring__particle {
border-radius: calc(var(--radius, 50) * 1%);
}
.sling-ring--particles-real .sling-ring__particle-start {
background: none;
}
.sling-ring--particles-real img {
animation-delay: calc((var(--particle-count) / 5) * 0.75s);
}
@keyframes reveal {
to {
--ring-reveal: 100%;
}
}
@keyframes rotate-in {
from {
transform: rotate(var(--base-rotation, 0deg));
}
}
@keyframes fade-in {
from {
opacity: 0;
}
}
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
@keyframes blast {
from {
transform: rotate(calc(var(--rotation, 0) * 1deg)) scale(0) translate(0, 0);
}
to {
transform: rotate(calc(var(--rotation, 0) * 1deg)) scale(1.2) translate(0, calc((var(--ring-thickness) * var(--distance, 5)) * -1));
}
}
@keyframes fade-away {
0%, 75% {
opacity: 1;
}
100% {
opacity: 0;
}
}
const REPLAY = () => {
const MARKUP = document.body.innerHTML
document.body.innerHTML = ''
requestAnimationFrame(() => document.body.innerHTML = MARKUP)
}
document.body.addEventListener('click', REPLAY)
View Compiled
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.