Skip to content

Instantly share code, notes, and snippets.

@Tr3yWay996
Created April 5, 2024 05:19
Show Gist options
  • Save Tr3yWay996/1b03f9c5689f4601cf60fc9b08346eb0 to your computer and use it in GitHub Desktop.
Save Tr3yWay996/1b03f9c5689f4601cf60fc9b08346eb0 to your computer and use it in GitHub Desktop.
Mario UI
<div id="app">
<div id="star-container">
<div id="star-pattern"></div>
<div id="star-gradient-overlay"></div>
</div>
<div id="stripe-container">
<div id="stripe-pattern"></div>
</div>
<div id="modal-wrapper">
<div id="modal">
<div id="modal-background"></div>
<div id="modal-content">
<div id="modal-message">
<p class="sixty-four-font">Save progress?</p>
</div>
<div id="modal-actions">
<button type="button" class="modal-action">
<div class="modal-action-pattern"></div>
<div class="modal-action-fade"></div>
<span class="modal-action-text inter-font">Back</span>
</button>
<button type="button" class="modal-action">
<div class="modal-action-pattern"></div>
<div class="modal-action-fade"></div>
<span class="modal-action-text inter-font">OK</span>
</button>
</div>
</div>
</div>
</div>
</div>
<div id="magic-mouse-container"></div>
<div id="cursor">
<img
src="https://assets.codepen.io/1468070/Arrow+-+Cursor.png"
alt="Arrow Cursor"
/>
<div id="cursor-eyes">
<div class="cursor-eye"></div>
<div class="cursor-eye"></div>
</div>
</div>
for(const text of document.querySelectorAll(".modal-action-text")) {
const letters = text.textContent.split("");
text.innerHTML = "";
letters.forEach((letter, index) => {
const span = document.createElement("span");
span.className = "modal-action-text-letter";
span.style.animationDelay = `${index * 300}ms`;
span.style.animationDuration = `${(letters.length * 300) + 1000}ms`;
span.innerHTML = letter;
text.appendChild(span);
});
}
/* --- Magic mouse effect --- */
let start = new Date().getTime();
const originPosition = { x: 0, y: 0 };
const container = document.getElementById("magic-mouse-container"),
cursor = document.getElementById("cursor");
const last = {
starTimestamp: start,
starPosition: originPosition,
mousePosition: originPosition
}
const config = {
starAnimationDuration: 1500,
minimumTimeBetweenStars: 250,
minimumDistanceBetweenStars: 75,
glowDuration: 75,
maximumGlowPointSpacing: 10,
colors: ["245 245 245", "59 130 246"],
sizes: ["1.4rem", "1rem", "0.6rem"],
animations: ["fall-1", "fall-2", "fall-3"]
}
let count = 0;
const rand = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min,
selectRandom = items => items[rand(0, items.length - 1)];
const withUnit = (value, unit) => `${value}${unit}`,
px = value => withUnit(value, "px"),
ms = value => withUnit(value, "ms");
const calcDistance = (a, b) => {
const diffX = b.x - a.x,
diffY = b.y - a.y;
return Math.sqrt(Math.pow(diffX, 2) + Math.pow(diffY, 2));
}
const calcElapsedTime = (start, end) => end - start;
const appendElement = element => container.appendChild(element),
removeElement = (element, delay) => setTimeout(() => container.removeChild(element), delay);
const createStar = position => {
const star = document.createElement("span"),
color = selectRandom(config.colors);
star.className = "item fa-solid fa-block-question";
star.style.left = px(position.x);
star.style.top = px(position.y);
star.style.fontSize = selectRandom(config.sizes);
star.style.color = `rgb(${color})`;
star.style.textShadow = `0px 0px 1.5rem rgb(${color} / 0.5)`;
star.style.animationName = config.animations[count++ % 3];
star.style.starAnimationDuration = ms(config.starAnimationDuration);
appendElement(star);
removeElement(star, config.starAnimationDuration);
}
const createGlowPoint = position => {
const glow = document.createElement("div");
glow.className = "glow-point";
glow.style.left = px(position.x);
glow.style.top = px(position.y);
appendElement(glow)
removeElement(glow, config.glowDuration);
}
const determinePointQuantity = distance => Math.max(
Math.floor(distance / config.maximumGlowPointSpacing),
1
);
const createGlow = (last, current) => {
const distance = calcDistance(last, current),
quantity = determinePointQuantity(distance);
const dx = (current.x - last.x) / quantity,
dy = (current.y - last.y) / quantity;
Array.from(Array(quantity)).forEach((_, index) => {
const x = last.x + dx * index,
y = last.y + dy * index;
createGlowPoint({ x, y });
});
}
const updateLastStar = position => {
last.starTimestamp = new Date().getTime();
last.starPosition = position;
}
const updateLastMousePosition = position => last.mousePosition = position;
const adjustLastMousePosition = position => {
if(last.mousePosition.x === 0 && last.mousePosition.y === 0) {
last.mousePosition = position;
}
};
const moveCursor = e => {
cursor.style.left = `${e.clientX}px`;
cursor.style.top = `${e.clientY}px`;
}
const handleOnMove = e => {
const mousePosition = { x: e.clientX, y: e.clientY }
moveCursor(e);
adjustLastMousePosition(mousePosition);
const now = new Date().getTime(),
hasMovedFarEnough = calcDistance(last.starPosition, mousePosition) >= config.minimumDistanceBetweenStars,
hasBeenLongEnough = calcElapsedTime(last.starTimestamp, now) > config.minimumTimeBetweenStars;
if(hasMovedFarEnough || hasBeenLongEnough) {
createStar(mousePosition);
updateLastStar(mousePosition);
}
createGlow(last.mousePosition, mousePosition);
updateLastMousePosition(mousePosition);
}
window.onmousemove = e => handleOnMove(e);
window.ontouchmove = e => handleOnMove(e.touches[0]);
document.body.onmouseleave = () => updateLastMousePosition(originPosition);
<script src="https://codepen.io/Hyperplexed/pen/xxYJYjM/54407644e24173ad6019b766443bf2a6.js"></script>
:root {
--glow-rgb: 245 245 245;
--light-gold-rgb: 249 181 51;
--dark-gold-rgb: 215 147 23;
--primary-stripe-rgb: 230 230 230;
--secondary-stripe-rgb: 240 240 240;
}
body {
background-color: black;
cursor: none;
overflow: hidden;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
@keyframes pan {
0% {
background-position: 0% 0%;
}
100% {
background-position: 100% 0%;
}
}
#app {
height: 100vh;
overflow: hidden;
position: relative;
}
#star-container {
background: radial-gradient(rgb(var(--light-gold-rgb)), rgb(var(--dark-gold-rgb)));
height: 100%;
overflow: hidden;
position: relative;
}
#star-pattern {
background-image: url("https://assets.codepen.io/1468070/Star+Pattern+3.svg");
background-size: 10%;
position: absolute;
left: 50%;
top: 0px;
translate: -50% 0%;
z-index: 1;
height: 100%;
width: 100%;
min-width: 1200px;
opacity: 0.10;
animation: pan 180s linear infinite;
will-change: background-position;
}
#star-gradient-overlay {
background: radial-gradient(circle, transparent 75%, rgb(var(--dark-gold-rgb)));
position: absolute;
left: 0px;
top: 0px;
width: 100%;
height: 100%;
opacity: 0.9;
z-index: 2;
}
#stripe-container {
position: absolute;
z-index: 3;
left: 50%;
bottom: 0px;
translate: -50% 0%;
height: 28vh;
min-height: 240px;
width: 100%;
min-width: 2000px;
background-color: rgb(var(--stripe-primary-rgb));
clip-path: polygon(
0% 5%, 1.25% 0%, 2.5% 5%,
3.75% 0%, 5% 5%, 6.25% 0%,
7.5% 5%, 8.75% 0%, 10% 5%,
11.25% 0%, 12.5% 5%, 13.75% 0%,
15% 5%, 16.25% 0%, 17.5% 5%,
18.75% 0%, 20% 5%, 21.25% 0%,
22.5% 5%, 23.75% 0%, 25% 5%,
26.25% 0%, 27.5% 5%, 28.75% 0%,
30% 5%, 31.25% 0%, 32.5% 5%,
33.75% 0%, 35% 5%, 36.25% 0%,
37.5% 5%, 38.75% 0%, 40% 5%,
41.25% 0%, 42.5% 5%, 43.75% 0%,
45% 5%, 46.25% 0%, 47.5% 5%,
48.75% 0%, 50% 5%, 51.25% 0%,
52.5% 5%, 53.75% 0%, 55% 5%,
56.25% 0%, 57.5% 5%, 58.75% 0%,
60% 5%, 61.25% 0%, 62.5% 5%,
63.75% 0%, 65% 5%, 66.25% 0%,
67.5% 5%, 68.75% 0%, 70% 5%,
71.25% 0%, 72.5% 5%, 73.75% 0%,
75% 5%, 76.25% 0%, 77.5% 5%,
78.75% 0%, 80% 5%, 81.25% 0%,
82.5% 5%, 83.75% 0%, 85% 5%,
86.25% 0%, 87.5% 5%, 88.75% 0%,
90% 5%, 91.25% 0%, 92.5% 5%,
93.75% 0%, 95% 5%, 96.25% 0%,
97.5% 5%, 98.75% 0%, 100% 5%,
100% 100%, 0% 100%
);
}
#stripe-pattern {
height: 100%;
width: 100%;
background-size: 18px 18px;
background-image: linear-gradient(
-45deg,
rgb(var(--primary-stripe-rgb)) 25%,
rgb(var(--secondary-stripe-rgb)) 25%,
rgb(var(--secondary-stripe-rgb)) 50%,
rgb(var(--primary-stripe-rgb)) 50%,
rgb(var(--primary-stripe-rgb)) 75%,
rgb(var(--secondary-stripe-rgb)) 75%,
rgb(var(--secondary-stripe-rgb)) 100%
);
box-shadow: inset 0rem 0.5rem 2rem 0.25rem rgb(0 0 0 / 40%);
animation: pan 360s linear infinite;
}
/* -- Modal -- */
.sixty-four-font {
font-family: "Sixtyfour", sans-serif;
font-optical-sizing: auto;
font-weight: 400;
font-style: normal;
font-variation-settings:
"BLED" 0,
"SCAN" 0;
}
.inter-font {
font-family: "Inter", sans-serif;
font-optical-sizing: auto;
font-weight: 600;
font-style: normal;
font-variation-settings:
"slnt" 0;
}
#modal-wrapper {
width: 100%;
height: 72vh;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
left: 0px;
top: 0px;
z-index: 10;
padding: 2rem;
}
@media(max-height: 800px) {
#modal-wrapper {
height: 100vh;
}
}
#modal {
display: flex;
width: 50rem;
aspect-ratio: 5 / 3;
position: relative;
background-color: rgb(50 50 50);
border: 0.5rem solid rgb(30 30 30);
border-top-right-radius: 5rem;
border-bottom-left-radius: 5rem;
overflow: hidden;
box-shadow: 12px 25px 50px 12px rgb(0 0 0 / 0.5);
}
@media(max-width: 1024px) {
#modal {
aspect-ratio: auto;
min-height: 500px;
width: 100%;
border-top-right-radius: 3rem;
border-bottom-left-radius: 3rem;
}
}
@media(max-width: 728px) {
#modal {
min-height: 400px;
}
}
#modal-background {
position: absolute;
left: 0px;
top: 0px;
z-index: 1;
height: 100%;
width: 100%;
background-image: url("https://assets.codepen.io/1468070/Repeatable+Pattern+-+Wavy+Lines.png?format=auto&quality=80");
background-size: 200%;
opacity: 0.3;
animation: move-background 50s linear infinite;
}
#modal-content {
display: flex;
flex-direction: column;
flex-grow: 1;
padding: 3rem;
position: relative;
z-index: 2;
}
#modal-message {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
#modal-message p {
color: white;
font-size: 1.5rem;
text-align: center;
text-shadow: 0px 0px 8px rgb(0 0 0 / 50%);
}
#modal-actions {
display: flex;
justify-content: center;
gap: 2rem;
}
@media(max-width: 1024px) {
#modal-actions {
align-items: center;
flex-direction: column-reverse;
}
}
.modal-action {
width: 16rem;
padding: 0.85rem;
position: relative;
font-size: 1.25rem;
border: none;
border-radius: 0.75rem;
outline: 0.2rem solid white;
outline-offset: 0.2rem;
overflow: hidden;
cursor: none;
}
@media(max-width: 1024px) {
.modal-action {
width: 100%;
max-width: 400px;
}
}
.modal-action:is(:hover, :focus-visible) {
background-color: rgb(253, 224, 71);
}
.modal-action:is(:hover, :focus-visible) .modal-action-fade,
.modal-action:is(:hover, :focus-visible) .modal-action-pattern {
display: block;
}
.modal-action:is(:hover, :focus-visible) .modal-action-text-letter {
animation: bounce infinite;
}
.modal-action-fade,
.modal-action-pattern {
display: none;
width: 100%;
height: 100%;
position: absolute;
left: 0px;
top: 0px;
}
.modal-action-fade {
z-index: 1;
background: linear-gradient(to left, rgb(253, 224, 71), transparent 60%);
}
.modal-action-pattern {
background-image: radial-gradient(
rgb(255 255 255 / 0.6) 30%,
transparent 30%
);
background-position: 0% 0%;
background-size: 10px 10px;
animation: move-background 50s linear infinite;
transform: skew(-15deg, 0deg);
}
.modal-action-text {
position: relative;
z-index: 2;
color: black;
font-size: 1.25rem;
}
.modal-action-text-letter {
display: inline-flex;
position: relative;
}
@keyframes move-background {
0% {
background-position: 0% 0%;
}
100% {
background-position: -100% 0%;
}
}
@keyframes bounce {
0%, 20%, 100% {
translate: 0% 0%;
}
10% {
translate: 0% -12%;
}
}
@keyframes blink {
0%, 3%, 100% {
scale: 1 1;
}
1.5% {
scale: 1 0;
}
}
/* -- Cursor -- */
#cursor {
height: 2rem;
position: absolute;
z-index: 100;
pointer-events: none;
}
#cursor > img {
height: 100%;
width: 100%;
}
#cursor-eyes {
height: 90%;
width: 90%;
display: flex;
align-items: center;
justify-content: center;
gap: 0.18rem;
position: absolute;
z-index: 2;
left: 0px;
top: 0px;
}
.cursor-eye {
background-color: rgb(255 255 255 / 0.5);
height: 0.48rem;
width: 0.18rem;
shrink: 0;
border-radius: 1rem;
animation: blink 10s infinite;
}
/* --- Magic Mouse Effect --- */
#magic-mouse-container {
height: 100vh;
width: 100vw;
position: fixed;
left: 0px;
top: 0px;
overflow: hidden;
pointer-events: none;
z-index: 100;
}
.glow-point {
position: absolute;
box-shadow: 0rem 0rem 1.2rem 0.6rem rgb(var(--glow-rgb));
pointer-events: none;
}
.item {
position: absolute;
z-index: 2;
color: white;
font-size: 1rem;
animation-duration: 1500ms;
animation-fill-mode: forwards;
pointer-events: none;
}
@keyframes fall-1 {
0% {
transform: translate(0px, 0px) rotateX(45deg) rotateY(30deg) rotateZ(0deg) scale(0.25);
opacity: 0;
}
5% {
transform: translate(10px, -10px) rotateX(45deg) rotateY(30deg) rotateZ(0deg) scale(1);
opacity: 1;
}
100% {
transform: translate(25px, 200px) rotateX(180deg) rotateY(270deg) rotateZ(90deg) scale(1);
opacity: 0;
}
}
@keyframes fall-2 {
0% {
transform: translate(0px, 0px) rotateX(-20deg) rotateY(10deg) scale(0.25);
opacity: 0;
}
10% {
transform: translate(-10px, -5px) rotateX(-20deg) rotateY(10deg) scale(1);
opacity: 1;
}
100% {
transform: translate(-10px, 160px) rotateX(-90deg) rotateY(45deg) scale(0.25);
opacity: 0;
}
}
@keyframes fall-3 {
0% {
transform: translate(0px, 0px) rotateX(0deg) rotateY(45deg) scale(0.5);
opacity: 0;
}
15% {
transform: translate(7px, 5px) rotateX(0deg) rotateY(45deg) scale(1);
opacity: 1;
}
100% {
transform: translate(20px, 120px) rotateX(-180deg) rotateY(-90deg) scale(0.5);
opacity: 0;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment