Le Skateur
Animation d'un skateur allant d'un bout à l'autre sur une ligne, il y a un titre au-dessus.
<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>
Aperçu
TIMELINE
100kSTADIUM logo
Logo de site web qui est animé, lorsqu'il est survolé une barre soulignée grossit et les couleurs sont inversées.
<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>
Aperçu
100K
STADIUM
Redirection de l'attention animé
Quatre phrases empilées qui fusionnent lorsqu'on clique dessus, accompagnées d'une animation en forme de flèche.
<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>
Aperçu
Easy
Simple
Quick
Efficient
➜
Texte informatif sur image
L'effet de survol d'une image de logo circulaire déclenche une animation d'élastique et affiche une info-bulle avec un texte personnalisé.
<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>
Aperçu
L'IA générative est au pire niveau qu'elle ne le sera jamais, alors autant commencer à l'utiliser. J'ai choisi Midjourney mais j'aurais pu en choisir beaucoup d'autres comme Glif ou Playground.
Un DAW est un logiciel pour faire de la musique sur ordinateur, l'équivalent numérique d'une console de mixage, de son rack d'effets et de sa bande magnétique, c'est la pierre angulaire de la production. Ils se valent tous, mais le mien est le meilleur (typique des ingé son).
Fait presque autant que photoshop, mais n'appartient pas à Adobe (lol). Gratuit et en ligne.
Les logiciels de montage vidéo ont fait beaucoup de chemin depuis les pelicules qu'on collait manuellement ensemble. J'utilise aussi CapCut et Shotcut.
Images imbriquées
Effet interactif de révélation d'image où le survol d'une image circulaire la décompose en petits pixels qui s'éloignent du curseur, révélant une seconde image en dessous.
<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>