Skater timeline
Animation of a skateboarder going from one end to another on a line, there is a title above
<div id="skateboarding-timeline-container">
<style>
#skateboarding-timeline-container {
display: flex;
<div id="skateboarding-timeline-container">
<style>
#skateboarding-timeline-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 50vh;
margin: 0;
background-color: transparent;
font-family: Arial, sans-serif;
}
#skateboarding-timeline-container h2 {
font-size: 6rem;
margin-bottom: 1rem;
font-family: 'Bayon', sans-serif;
color: #fff200;
}
#timeline {
width: 80%;
height: 75px;
}
</style>
<h2><strong>TIMELINE</strong></h2>
<svg id="timeline" viewBox="0 0 1000 100">
<line x1="0" y1="90" x2="1000" y2="90" stroke="#fff200" stroke-width="4"/>
<g id="skateboarder">
<g id="skateboard">
<line x1="-40" y1="78" x2="40" y2="78" stroke="#fff200" stroke-width="6"/>
<circle cx="-30" cy="85" r="5" fill="gray"/>
<circle cx="30" cy="85" r="5" fill="gray"/>
</g>
<g id="figure">
<g id="cap">
<path d="M-10 -13 Q0 -20 10 -13 L12 -5 Q6 -8 0 -8 Q-6 -8 -12 -5 Z" fill="#F7B526"/>
<path d="M-12 -5 Q-6 -3 0 -3 Q6 -3 12 -5 L10 0 H-12 Z" fill="white"/>
</g>
<circle cx="0" cy="-5" r="8" fill="#fff200"/> <!-- Head -->
<line x1="0" y1="3" x2="0" y2="35" stroke="#fff200" stroke-width="2"/> <!-- Body -->
<g id="legs">
<g id="leg1">
<line x1="0" y1="35" x2="0" y2="55" stroke="#fff200" stroke-width="2" id="thigh1"/> <!-- Thigh 1 -->
<line x1="0" y1="55" x2="0" y2="75" stroke="#fff200" stroke-width="2" id="calf1"/> <!-- Calf 1 -->
</g>
<g id="leg2">
<line x1="0" y1="35" x2="0" y2="55" stroke="#fff200" stroke-width="2" id="thigh2"/> <!-- Thigh 2 -->
<line x1="0" y1="55" x2="0" y2="75" stroke="#fff200" stroke-width="2" id="calf2"/> <!-- Calf 2 -->
</g>
</g>
<g id="arms">
<line x1="0" y1="15" x2="-20" y2="25" stroke="#fff200" stroke-width="2" id="arm1"/> <!-- Left arm -->
<line x1="0" y1="15" x2="20" y2="25" stroke="#fff200" stroke-width="2" id="arm2"/> <!-- Right arm -->
</g>
</g>
</g>
</svg>
<script>
(function() {
const skateboarder = document.getElementById('skateboarder');
const leg1 = document.getElementById('leg1');
const leg2 = document.getElementById('leg2');
const arm1 = document.getElementById('arm1');
const arm2 = document.getElementById('arm2');
let position = 0;
let direction = 1;
let step = 0;
function animate() {
position += direction * 3;
step = (step + 1) % 20;
if (position > 1000 || position < 0) {
direction *= -1;
skateboarder.setAttribute('transform', `translate(${position}, 0) scale(${-direction}, 1)`);
} else {
skateboarder.setAttribute('transform', `translate(${position}, 0)`);
}
// Animate legs for skateboarding motion
const thighAngle1 = direction * Math.sin(step * Math.PI / 10) * 30;
const thighAngle2 = direction * -Math.sin(step * Math.PI / 10) * 30;
const calfAngle1 = Math.abs(Math.sin(step * Math.PI / 10)) * 60;
const calfAngle2 = Math.abs(Math.sin((step + 10) * Math.PI / 10)) * 60;
leg1.setAttribute('transform', `rotate(${thighAngle1}, 0, 35)`);
leg2.setAttribute('transform', `rotate(${thighAngle2}, 0, 35)`);
document.getElementById('calf1').setAttribute('transform', `rotate(${direction * calfAngle1}, 0, 55)`);
document.getElementById('calf2').setAttribute('transform', `rotate(${direction * calfAngle2}, 0, 55)`);
// Animate arms for balancing motion
const armAngle1 = Math.sin(step * Math.PI / 20) * 10;
const armAngle2 = -Math.sin(step * Math.PI / 20) * 10;
arm1.setAttribute('transform', `rotate(${armAngle1}, 0, 15)`);
arm2.setAttribute('transform', `rotate(${armAngle2}, 0, 15)`);
requestAnimationFrame(animate);
}
animate();
})();
</script>
</div>
Code Preview
TIMELINE
100k STADIUM Site Title
Website logo that is animated, when on hover an underline rise up and colors are inverted.
<div id="stadium-logo" onclick="window.location.href='https://100kstadium.com/';">
<span class="logo-text">100K</span>
<div class="stadium-container">
<span class="stadium-text">STADIUM</span>
<div id="stadium-logo" onclick="window.location.href='https://100kstadium.com/';">
<span class="logo-text">100K</span>
<div class="stadium-container">
<span class="stadium-text">STADIUM</span>
<div class="underline"></div>
</div>
</div>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@600;900&display=swap');
#stadium-logo {
font-family: 'Inter', sans-serif;
font-size: 8vw;
font-weight: 900;
text-transform: uppercase;
letter-spacing: -0.03em;
background-color: black;
padding: 20px;
display: inline-block;
cursor: pointer;
position: relative;
line-height: 0.8;
}
.logo-text {
color: transparent;
-webkit-text-stroke: 2px white;
text-stroke: 2px white;
-webkit-background-clip: text;
background-clip: text;
text-shadow: 0.03em 0.03em 0px rgba(255, 255, 255, 1), 0.02em 0.02em 0px rgba(255, 255, 255, 0.2);
transition: all 0.3s ease;
display: inline-block;
}
.stadium-container {
position: absolute;
display: inline-block;
font-size: 1.5rem;
font-weight: 600;
right: 0;
bottom: 1.5px;
letter-spacing: -0.02em;
}
.stadium-text {
position: relative;
z-index: 2;
color: white;
transition: color 0.3s ease;
}
.underline {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 2px;
background-color: white;
transition: height 0.3s ease;
}
#stadium-logo:hover .logo-text {
-webkit-text-stroke: 2px yellow;
text-stroke: 2px yellow;
text-shadow: 0.01em 0.01em 0px rgba(255, 255, 0, 1), 0.02em 0.02em 0px rgba(255, 255, 0, 0.2);
}
#stadium-logo:hover .stadium-text {
color: black;
}
#stadium-logo:hover .underline {
height: 100%;
}
@media (max-width: 768px) {
#stadium-logo {
font-size: 12vw;
padding: 15px;
}
.stadium-container {
font-size: 1rem;
right: 0;
bottom: 3px;
}
}
</style>
Code Preview
100K
STADIUM
Bait and switch redirection
Four stacked sentences that merge together when clicked, accompanied by an arrow animation.
<div class="ant-animated-container">
<div class="ant-word-container">
<div class="ant-word" data-hover="Ask Questions, Get Answers">Easy</div>
<div class="ant-word" data-hover="Run it Quick">Simple</div>
<div class="ant-animated-container">
<div class="ant-word-container">
<div class="ant-word" data-hover="Ask Questions, Get Answers">Easy</div>
<div class="ant-word" data-hover="Run it Quick">Simple</div>
<div class="ant-word" data-hover="Better Safe Than Sorry">Quick</div>
<div class="ant-word" data-hover="Special Launch Offers">Efficient</div>
<div class="ant-arrow">➜</div>
</div>
<style>
.ant-animated-container {
position: relative;
min-height: 400px;
width: 100%;
max-width: 600px;
margin: 0 auto;
}
.ant-word-container {
position: relative;
width: 100%;
}
.ant-word {
font-family: Bayon, sans-serif;
font-size: clamp(1.5rem, 4vw, 2.5rem);
color: #000;
cursor: pointer;
position: absolute;
left: 0;
width: 100%;
text-align: left;
padding: 5px 20px;
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
white-space: nowrap;
box-sizing: border-box;
min-width: max-content;
height: 50px;
line-height: 40px;
}
.ant-word:hover {
color: #fff;
background: #000;
}
.ant-word.merging {
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
left: 0;
transform: translateX(0);
}
.ant-word.highlighted {
color: #fff;
background: #000;
}
.ant-arrow {
position: absolute;
top: 240px; /* Aligned with the last word's position */
left: calc(100% - 20px);
font-size: 50px;
opacity: 0;
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
height: 50px;
line-height: 50px;
transform: scale(0) translateX(0);
background-color: #000;
color: white;
padding: 0 10px;
}
.ant-arrow.show {
opacity: 1;
transform: scale(1) translateX(0);
animation: slideRight 2s ease-in-out;
}
@keyframes slideRight {
0% {
transform: scale(1) translateX(0);
}
50% {
transform: scale(1) translateX(calc(20vw - 40px));
}
100% {
transform: scale(1) translateX(0);
}
}
.ant-word:nth-child(1) { top: 0; }
.ant-word:nth-child(2) { top: 80px; }
.ant-word:nth-child(3) { top: 160px; }
.ant-word:nth-child(4) { top: 240px; }
@media (max-width: 768px) {
.ant-animated-container {
margin: 0;
}
.ant-word {
padding: 5px 10px;
}
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const words = document.querySelectorAll('.ant-word');
const arrow = document.querySelector('.ant-arrow');
let isAnimating = false;
function setUniformWidth() {
let maxWidth = 0;
words.forEach(word => {
word.style.visibility = 'hidden';
word.style.position = 'absolute';
document.body.appendChild(word.cloneNode(true));
maxWidth = Math.max(maxWidth, word.offsetWidth);
const hoverText = word.getAttribute('data-hover');
word.textContent = hoverText;
maxWidth = Math.max(maxWidth, word.offsetWidth);
word.textContent = word.getAttribute('data-original') || word.textContent;
word.style.visibility = 'visible';
});
maxWidth += 40;
words.forEach(word => {
word.style.width = `${maxWidth}px`;
});
document.querySelector('.ant-word-container').style.width = `${maxWidth}px`;
}
words.forEach(word => {
word.setAttribute('data-original', word.textContent);
});
setUniformWidth();
function mergeWords() {
if (isAnimating) return;
isAnimating = true;
const lastIndex = words.length - 1;
words.forEach((word, index) => {
word.classList.add('merging', 'highlighted');
setTimeout(() => {
word.style.top = '240px';
if (index !== lastIndex) {
word.style.opacity = '0';
}
}, index * 150);
});
setTimeout(() => {
arrow.classList.add('show');
// Reset the animation after it completes
setTimeout(() => {
arrow.style.animation = 'none';
arrow.offsetHeight; // Trigger reflow
arrow.style.animation = null;
}, 2000);
}, 1000);
setTimeout(() => {
arrow.classList.remove('show');
words.forEach((word, index) => {
word.classList.remove('merging', 'highlighted');
word.style.top = `${index * 80}px`;
word.style.opacity = '1';
});
setTimeout(() => {
isAnimating = false;
}, 1000);
}, 3000);
}
words.forEach(word => {
word.addEventListener('click', mergeWords);
word.addEventListener('mouseenter', function() {
if (!isAnimating) {
this.textContent = this.getAttribute('data-hover');
}
});
word.addEventListener('mouseleave', function() {
if (!isAnimating) {
this.textContent = this.getAttribute('data-original');
}
});
});
window.addEventListener('resize', setUniformWidth);
});
</script>
</div>
Code Preview
Easy
Simple
Quick
Efficient
➜
Icon informative hover
hover effect over a circular logo image triggers a rubber band animation and displays a tooltip with custom text.
<div class="custom-daw-hover-box">
<style>
.custom-daw-hover-box .image-container {
position: relative;
<div class="custom-daw-hover-box">
<style>
.custom-daw-hover-box .image-container {
position: relative;
display: inline-block;
}
.custom-daw-hover-box .hover-box {
position: absolute;
background-color: rgba(0, 0, 0, 0.8);
color: white;
padding: 10px;
border-radius: 15px;
display: none;
min-width: 200px;
max-width: 500px;
font-size: 14px;
line-height: 1.4;
border: 2px solid #fff200;
box-shadow: 0 0 10px rgba(255, 242, 0, 0.5);
z-index: 9999;
}
.custom-daw-hover-box .animated {
animation-duration: 1s;
animation-fill-mode: both;
}
.custom-daw-hover-box .rubberBand {
animation-name: rubberBand;
}
@keyframes rubberBand {
from { transform: scale3d(1, 1, 1); }
30% { transform: scale3d(1.25, 0.75, 1); }
40% { transform: scale3d(0.75, 1.25, 1); }
50% { transform: scale3d(1.15, 0.85, 1); }
65% { transform: scale3d(0.95, 1.05, 1); }
75% { transform: scale3d(1.05, 0.95, 1); }
to { transform: scale3d(1, 1, 1); }
}
.custom-daw-hover-box .o-anim-hover:hover {
animation-name: rubberBand;
}
</style>
<div class="image-container">
<figure class="wp-block-image size-thumbnail is-resized animated rubberBand o-anim-hover">
<img src="https://100kstadium.com/wp-content/uploads/2024/09/Midjourney-logo.png" alt="DAW Icon" style="border-radius:100px;width:50px;height:auto"/>
</figure>
<div class="hover-box">Generative AI is the worst it will ever be, so you better start using it. Picked Midjourney but I could've picked many more like glif or playground.</div>
</div>
</div>
<script>
(function() {
function initHoverBoxes() {
const containers = document.querySelectorAll('.custom-daw-hover-box .image-container');
containers.forEach(container => {
const hoverBox = container.querySelector('.hover-box');
container.addEventListener('mousemove', function(e) {
const rect = container.getBoundingClientRect();
const boxRect = hoverBox.getBoundingClientRect();
let x = e.clientX - rect.left + 10;
let y = e.clientY - rect.top + 10;
if (e.clientX + boxRect.width + 10 > window.innerWidth) {
x = e.clientX - rect.left - boxRect.width - 10;
}
if (e.clientY + boxRect.height + 10 > window.innerHeight) {
y = e.clientY - rect.top - boxRect.height - 10;
}
hoverBox.style.left = `${x}px`;
hoverBox.style.top = `${y}px`;
hoverBox.style.display = 'block';
});
container.addEventListener('mouseleave', function() {
hoverBox.style.display = 'none';
});
});
}
// Run the initialization function when the DOM is fully loaded
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initHoverBoxes);
} else {
initHoverBoxes();
}
})();
</script>
Code Preview
Generative AI is the worst it will ever be, so you better start using it. Picked Midjourney but I could've picked many more like glif or playground.
You know those black terminals hackers use in movies? Well, it's that, but harder and more boring.
Two layers image box hover effect
Interactive image reveal effect where hovering over a circular image breaks it into small pixels that move away from the cursor, revealing a second image underneath.
<div id="custom-image-hover-effect" style="width: 100%; max-width: 600px; margin: 0 auto;">
<div class="image-container" style="position: relative; width: 100%; padding-top: 100%; border-radius: 50%; overflow: hidden; border: 3px solid #fff200;">
<img src="https://100kstadium.com/wp-content/uploads/2024/08/IMG_3259-e1701719628240.jpg" alt="Front Image" class="front-image" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 2;">
<img src="https://100kstadium.com/wp-content/uploads/2024/09/glif-retro-anime-anything-burlap-ta4lat1rqjxqhpcdpxa2hx7o.jpg" alt="Back Image" class="back-image" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;">
<div id="custom-image-hover-effect" style="width: 100%; max-width: 600px; margin: 0 auto;">
<div class="image-container" style="position: relative; width: 100%; padding-top: 100%; border-radius: 50%; overflow: hidden; border: 3px solid #fff200;">
<img src="https://100kstadium.com/wp-content/uploads/2024/08/IMG_3259-e1701719628240.jpg" alt="Front Image" class="front-image" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: 2;">
<img src="https://100kstadium.com/wp-content/uploads/2024/09/glif-retro-anime-anything-burlap-ta4lat1rqjxqhpcdpxa2hx7o.jpg" alt="Back Image" class="back-image" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;">
</div>
<script>
(function() {
const container = document.currentScript.parentNode.querySelector('.image-container');
const frontImage = container.querySelector('.front-image');
let pixels = [];
let pixelSize = 15;
let effectRadius = 75;
function createPixels() {
const containerRect = container.getBoundingClientRect();
const rows = Math.ceil(containerRect.height / pixelSize);
const cols = Math.ceil(containerRect.width / pixelSize);
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const pixel = document.createElement('div');
pixel.style.position = 'absolute';
pixel.style.width = `${pixelSize}px`;
pixel.style.height = `${pixelSize}px`;
pixel.style.left = `${x * pixelSize}px`;
pixel.style.top = `${y * pixelSize}px`;
pixel.style.backgroundImage = `url(${frontImage.src})`;
pixel.style.backgroundPosition = `-${x * pixelSize}px -${y * pixelSize}px`;
pixel.style.backgroundSize = `${containerRect.width}px ${containerRect.height}px`;
pixel.style.transition = 'all 0.5s ease-out';
container.appendChild(pixel);
pixels.push(pixel);
}
}
}
function applyEffect(mouseX, mouseY) {
pixels.forEach((pixel) => {
const rect = pixel.getBoundingClientRect();
const pixelCenterX = rect.left + pixelSize / 2 - container.getBoundingClientRect().left;
const pixelCenterY = rect.top + pixelSize / 2 - container.getBoundingClientRect().top;
const distance = Math.sqrt(
Math.pow(mouseX - pixelCenterX, 2) + Math.pow(mouseY - pixelCenterY, 2)
);
if (distance <= effectRadius) {
const angle = Math.atan2(mouseY - pixelCenterY, mouseX - pixelCenterX);
const translateDistance = (effectRadius - distance) * 0.5; // Reduced movement
pixel.style.transform = `rotate(${angle}rad) translate(${translateDistance}px) rotate(-${angle}rad)`;
pixel.style.opacity = 0.2 + (0.8 * distance / effectRadius); // Smoother opacity transition
} else {
pixel.style.transform = 'none';
pixel.style.opacity = '1';
}
});
}
function handleResize() {
const containerRect = container.getBoundingClientRect();
pixelSize = Math.max(5, Math.floor(containerRect.width / 40)); // Adjust pixel size based on container width
effectRadius = Math.max(50, Math.floor(containerRect.width / 8)); // Adjust effect radius based on container width
// Remove existing pixels
pixels.forEach(pixel => pixel.remove());
pixels = [];
// Recreate pixels
createPixels();
}
createPixels();
frontImage.style.opacity = '0';
container.addEventListener('mousemove', (e) => {
const rect = container.getBoundingClientRect();
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
applyEffect(mouseX, mouseY);
});
container.addEventListener('mouseleave', () => {
pixels.forEach(pixel => {
pixel.style.transform = 'none';
pixel.style.opacity = '1';
});
});
window.addEventListener('resize', handleResize);
handleResize(); // Call once to set initial sizes
})();
</script>
</div>