<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>起飞咯!</title>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"
/>
<style>
* {
box-sizing: border-box;
}
body {
--hue: 12;
--star: #f7c655;
--bg: #262626;
--strap: #212121;
--red: #ed685e;
--orange: #ed975e;
--lime: #e4ed5e;
--green: #84ed5e;
--turquoise: #5ee4ed;
--purple: #685eed;
--indigo: #975eed;
--violet: #ed5eb4;
--tail: hsl(var(--hue), 27%, 62%);
--stroke: #1a1a1a;
--muzzle: hsl(var(--hue), 43%, 89%);
--dark: hsl(var(--hue), 33%, 67%);
--light: hsl(var(--hue), 65%, 79%);
--strap: #333;
background: var(--bg);
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
overflow: hidden;
}
svg {
height: 100vmin;
display: none;
}
.stars path {
fill: var(--star);
}
.kitty__light {
fill: var(--light);
}
.kitty__dark {
fill: var(--dark);
}
.kitty__dark-stroke {
stroke: var(--dark);
}
.kitty__stroke {
stroke: var(--stroke);
}
.kitty__fill {
fill: var(--stroke);
}
.kitty__muzzle {
fill: var(--muzzle);
}
.kitty__tail {
stroke: var(--tail);
}
.rocket__strap {
fill: var(--strap);
}
.rocket__body path:nth-of-type(1) {
fill: #a6a6a6;
}
.rocket__body path:nth-of-type(2) {
fill: #333;
}
.rocket__body path:nth-of-type(3) {
fill: #d9d9d9;
}
.rocket__body path:nth-of-type(4) {
fill: #4d4d4d;
}
.rocket__stream path:nth-of-type(1),
.rocket__bubbles path:nth-of-type(1),
.rocket__stream path:nth-of-type(8),
.rocket__bubbles path:nth-of-type(8) {
fill: var(--red);
}
.rocket__stream path:nth-of-type(2),
.rocket__bubbles path:nth-of-type(2),
.rocket__stream path:nth-of-type(9),
.rocket__bubbles path:nth-of-type(9) {
fill: var(--orange);
}
.rocket__stream path:nth-of-type(3),
.rocket__bubbles path:nth-of-type(3),
.rocket__stream path:nth-of-type(10),
.rocket__bubbles path:nth-of-type(10) {
fill: var(--lime);
}
.rocket__stream path:nth-of-type(4),
.rocket__bubbles path:nth-of-type(4),
.rocket__stream path:nth-of-type(11),
.rocket__bubbles path:nth-of-type(11) {
fill: var(--green);
}
.rocket__stream path:nth-of-type(5),
.rocket__bubbles path:nth-of-type(5),
.rocket__stream path:nth-of-type(12),
.rocket__bubbles path:nth-of-type(12) {
fill: var(--turquoise);
}
.rocket__stream path:nth-of-type(6),
.rocket__bubbles path:nth-of-type(6),
.rocket__stream path:nth-of-type(13),
.rocket__bubbles path:nth-of-type(13) {
fill: var(--purple);
}
.rocket__stream path:nth-of-type(7),
.rocket__bubbles path:nth-of-type(7),
.rocket__stream path:nth-of-type(14),
.rocket__bubbles path:nth-of-type(14) {
fill: var(--indigo);
}
.rocket__stream path:nth-of-type(8),
.rocket__bubbles path:nth-of-type(8),
.rocket__stream path:nth-of-type(15),
.rocket__bubbles path:nth-of-type(15) {
fill: var(--violet);
}
</style>
</head>
<body>
<svg
class="scene"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 1258 1186"
clip-rule="evenodd"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
>
<g class="rocket">
<g class="rocket__stream">
<path d="M745 608h6v263h-6z" />
<path d="M761 608h6v263h-6z" />
<path d="M755 608h6v263h-6z" />
<path d="M749 608h6v263h-6z" />
<path d="M778 608h6v263h-6z" />
<path d="M772 608h6v263h-6z" />
<path d="M767 608h6v263h-6z" />
</g>
<g class="rocket__bubbles">
<path d="M717 869a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M704 873a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M736 863a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M774 865a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M720 884a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M719 876a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M765 879a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M738 884a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M721 851a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M716 876a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M747 881a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M764 882a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M766 852a25 25 0 1150 0 25 25 0 01-50 0z" />
<path d="M735 847a25 25 0 1150 0 25 25 0 01-50 0z" />
</g>
<g class="rocket__body">
<path d="M743 602h43v9h-43z" />
<path d="M776 601h10v10h-10z" />
<path d="M764 442c-17 0-31 15-31 33v129h63V475c0-18-14-33-32-33z" />
<path
d="M764 442c18 0 32 15 32 33v129h-8V475c0-16-12-30-27-32l3-1z"
/>
</g>
</g>
<g class="kitty">
<g class="kitty__tails">
<path
class="kitty__tail"
d="M698 618c-2 16-9 38-6 53 3 12 14 22 15 35 1 16-6 32-8 46"
fill="none"
stroke-width="20"
/>
<path
class="kitty__tail"
d="M701 619c2 16 9 38 5 53-2 12-13 21-14 34-2 17 6 33 7 47"
fill="none"
stroke-width="20"
/>
</g>
<g class="kitty__leg kitty__leg--right">
<path
class="kitty__light"
d="M670 588c8 0 15 7 15 15v93c0 8-7 15-15 15s-14-7-14-15v-93c0-8 6-15 14-15z"
/>
<path
class="kitty__dark"
d="M677 590l2 7v94c0 8-6 14-14 14l-7-2c2 5 7 8 12 8 8 0 15-7 15-15v-93c0-6-3-10-8-13z"
/>
</g>
<g class="kitty__leg kitty__leg--left">
<path
class="kitty__light"
d="M730 591c8 0 14 6 14 14v94c0 8-6 14-14 14s-15-6-15-14v-94c0-8 7-14 15-14z"
/>
<path
class="kitty__dark"
d="M737 593l2 6v94c0 8-7 15-15 15-3 0-5-1-7-3 2 5 7 8 13 8 8 0 14-6 14-14v-94c0-5-3-10-7-12z"
/>
</g>
<g class="kitty__body">
<path
class="kitty__light"
d="M699 446c27 0 49 22 49 48v97c0 27-22 48-49 48s-49-21-49-48v-97c0-26 22-48 49-48z"
/>
<path
class="kitty__dark"
d="M699 639c27 0 49-22 49-48l1-98c-1-15-10-28-21-37 5 8 9 17 9 27v97c1 27-21 48-48 49-12 0-22-4-30-10 9 12 24 20 40 20z"
/>
</g>
<path
class="rocket__strap"
d="M652 509l91-11c5-1 9 3 10 7v1c0 5-3 9-8 10l-91 11c-5 0-9-3-10-8v-1c0-5 3-9 8-9z"
/>
<g class="kitty__arm kitty__arm--right">
<path
class="kitty__light"
d="M734 468c8 2 13 10 11 18l-20 91c-2 8-10 13-18 11s-13-10-11-17l21-92c2-8 9-13 17-11z"
/>
<path
class="kitty__dark"
d="M741 471v8l-21 91c-1 8-9 13-17 11l-7-4c2 5 6 10 11 11 8 2 16-3 18-11l21-92c1-5-1-10-5-14z"
/>
</g>
<g class="kitty__arm kitty__arm--left">
<path
class="kitty__light"
d="M659 475c8 2 13 10 11 18l-22 91c-2 8-10 13-18 11s-13-10-11-18l23-91c1-8 9-13 17-11z"
/>
<path
class="kitty__dark"
d="M665 479l1 7-23 91c-1 8-9 13-17 11l-7-4c2 5 6 9 11 11 8 2 16-3 18-11l22-91c1-5-1-10-5-14z"
/>
</g>
<g class="kitty__head">
<g class="kitty__stroke" fill="none" stroke-width="5">
<path d="M548 467c-18 10-38 13-54 26" />
<path d="M560 485l-48 31" />
<path d="M574 495c-9 7-14 19-17 30" />
<path d="M745 351c7-13 31-22 43-30" />
<path d="M757 374c11-8 24-19 38-12" />
<path d="M760 390c10-6 38 4 47 9" />
</g>
<path
class="kitty__light"
d="M652 326c4-107 90-53 73 8 48 34 64 104-5 155-94 71-188 9-181-68-37-57-22-143 46-67"
/>
<path
class="kitty__muzzle"
d="M616 454c-7-14 5-34 28-46 22-11 46-9 53 5s-5 35-27 46c-23 12-47 9-54-5z"
/>
<g class="kitty__eye kitty__eye--left">
<path
class="kitty__stroke kitty__fill"
d="M565 444a7 7 0 1112-8 7 7 0 01-12 8z"
stroke-width="5"
/>
</g>
<g class="kitty__eye kitty__eye--right">
<path
class="kitty__stroke kitty__fill"
d="M712 377a7 7 0 1112-7 7 7 0 01-12 7z"
stroke-width="5"
/>
</g>
<path
class="kitty__light"
d="M570 369c9-8 15-20 25-27 22-15 47-18 72-16"
/>
<path
class="kitty__dark-stroke"
d="M690 287c-18-22-28 18-25 30v3"
fill="none"
stroke-width="4"
/>
<path
class="kitty__dark-stroke"
d="M536 352c-6-8 2-21 11-15 6 5 12 9 17 15 1 2 7 10 8 9"
fill="none"
stroke-width="4"
/>
<path
class="kitty__stroke"
d="M631 451c19 7 15-12 26-15 4-2 10 3 16 0 2-2 14-11 11-13"
fill="none"
stroke-width="4"
/>
<path
class="kitty__stroke"
d="M644 426c-1-3 1-5 4-7 3-1 7-1 8 1s-1 5-4 7c-4 1-7 1-8-1z"
stroke-width="2"
/>
<path
class="kitty__dark"
d="M695 267c14 12 23 35 17 59 47 34 63 104-6 155-47 36-94 38-129 21 35 25 89 28 143-13 69-51 53-121 5-155 9-31-10-61-30-67z"
/>
</g>
</g>
<g class="stars">
<path
d="M908 657l-10-9-13 4 5-12-8-11h13l8-10 4 13 13 4-11 7z"
fill-rule="nonzero"
/>
<path
d="M1128 89l-10-8-13 3 5-12-8-11 13 1 8-11 4 13 13 4-11 8z"
fill-rule="nonzero"
/>
<path
d="M296 287l-10-9-13 4 5-12-8-11h13l8-10 4 13 12 4-11 7z"
fill-rule="nonzero"
/>
<path
d="M188 991l-10-8-13 4 5-13-8-11 13 1 8-11 4 13 13 4-11 8z"
fill-rule="nonzero"
/>
<path
d="M1227 1137l-10-9-13 4 5-12-8-11h13l8-10 4 13 12 4-11 7z"
fill-rule="nonzero"
/>
</g>
</svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.3/gsap.min.js"></script>
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin3.min.js"></script>
<script>
const {
gsap: {
set,
to,
timeline,
utils: { random },
},
} = window;
const TAILS = [...document.querySelectorAll('.kitty__tail')];
const STARS = [...document.querySelectorAll('.stars path')];
const BUBBLES = [...document.querySelectorAll('.rocket__bubbles path')];
const EYES = [...document.querySelectorAll('.kitty__eye')];
set('.scene', { display: 'block' });
set(TAILS[1], { display: 'none' });
to(TAILS[0], {
duration: 0.1,
ease: 'none',
yoyo: true,
repeat: -1,
morphSVG: TAILS[1],
});
set('.stars path', {
y: -1185,
transformOrigin: '50% 50%',
rotation: 'random(0, 360)',
scale: 'random(0.2, 1.2)',
});
STARS.forEach((star) =>
to(star, {
repeat: -1,
duration: 'random(4, 10)',
delay: () => 'random(-10, -5)',
y: 1185,
ease: 'none',
})
);
set(BUBBLES, { scale: 0, transformOrigin: '50% 50%' });
BUBBLES.forEach((bubble) =>
timeline({ repeat: -1, yoyo: true })
.to(bubble, {
duration: 0.5,
scale: 2.5,
})
.to(
bubble,
{
duration: 0.2,
opacity: 0,
},
'>-0.2'
)
.seek(Math.random())
);
set(EYES, { transformOrigin: '50% 50%', rotate: -25 });
const blink = () => {
const delay = random(2, 5);
to(EYES, {
delay,
duration: 0.1,
repeat: 1,
yoyo: true,
scaleY: 0,
onComplete: () => blink(),
});
};
blink();
to('.kitty__head', {
repeat: -1,
yoyo: true,
rotate: 2,
duration: 0.1,
transformOrigin: '75% 75%',
});
to('.kitty__arm', {
repeat: -1,
yoyo: true,
rotate: 2,
duration: 0.1,
transformOrigin: '75% 15%',
});
to('.kitty__leg--left', {
repeat: -1,
yoyo: true,
rotate: 2,
duration: 0.1,
transformOrigin: '50% 5%',
});
to('.kitty__leg--right', {
repeat: -1,
yoyo: true,
rotate: -2,
duration: 0.1,
transformOrigin: '50% 5%',
});
const PARTY = timeline({
paused: true,
}).fromTo(
document.body,
{
'--hue': 0,
},
{
'--hue': 360,
repeat: 10,
ease: 'none',
}
);
const keys = [];
const shouldWeParty = (e) => {
keys.push(e.key);
if (
keys
.slice(keys.length - 5, keys.length)
.join('')
.toLowerCase() === 'party'
) {
keys.length = 0;
PARTY.restart();
}
};
window.addEventListener('keyup', shouldWeParty);
</script>
</body>
</html>