Added text animations
This commit is contained in:
parent
064b6c96f5
commit
2a8676cb31
8 changed files with 176 additions and 44 deletions
|
|
@ -1,3 +1,10 @@
|
|||
---
|
||||
title: Legal notice
|
||||
permalink: /docs/animation/index.html
|
||||
layout: page
|
||||
tags: ['docs']
|
||||
---
|
||||
|
||||
# Hand-Drawn Animation Effects
|
||||
|
||||
This project includes a sustainable animation system for adding hand-drawn, organic animation effects to text and UI elements throughout the site.
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ export default async function (eleventyConfig) {
|
|||
eleventyConfig.addShortcode('svg', shortcodes.svgShortcode);
|
||||
eleventyConfig.addShortcode('image', shortcodes.imageShortcode);
|
||||
eleventyConfig.addShortcode('imageKeys', shortcodes.imageKeysShortcode);
|
||||
eleventyConfig.addShortcode('animateText', shortcodes.animateText);
|
||||
eleventyConfig.addShortcode('year', () => `${new Date().getFullYear()}`);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ const buildCss = async (inputPath, outputPaths) => {
|
|||
postcssImport,
|
||||
tailwindcss,
|
||||
autoprefixer,
|
||||
cssnano
|
||||
cssnano({preset: ['default', {discardUnused: false}]})
|
||||
]).process(inputContent, {from: inputPath});
|
||||
|
||||
for (const outputPath of outputPaths) {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,11 @@ export const markdownLib = markdownIt({
|
|||
typographer: true
|
||||
})
|
||||
.disable('code')
|
||||
.use(markdownItAttrs)
|
||||
.use(markdownItAttrs, {
|
||||
leftDelimiter: '{',
|
||||
rightDelimiter: '}',
|
||||
allowed: ['class', 'id', 'style']
|
||||
})
|
||||
.use(markdownItPrism, {
|
||||
defaultLanguage: 'plaintext'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,19 @@
|
|||
import {imageShortcode, imageKeysShortcode} from './shortcodes/image.js';
|
||||
import {svgShortcode} from './shortcodes/svg.js';
|
||||
|
||||
export default {imageShortcode, imageKeysShortcode, svgShortcode};
|
||||
// Text animation shortcode - wraps each letter in a span with animation class
|
||||
// Speed parameter scales animation duration: 0.5 = 2x slower, 2 = 2x faster (default: 1)
|
||||
const animateText = (content, animation, speed = '1') => {
|
||||
const letters = content.split('');
|
||||
|
||||
const letterSpans = letters
|
||||
.map((letter) => {
|
||||
if (letter === ' ') return ' ';
|
||||
return `<span class="text-${animation}">${letter}</span>`;
|
||||
})
|
||||
.join('');
|
||||
|
||||
return letterSpans;
|
||||
};
|
||||
|
||||
export default {imageShortcode, imageKeysShortcode, svgShortcode, animateText};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/* Hand-drawn animation effects for text and UI elements */
|
||||
|
||||
/* Shiver effect - subtle shake/vibration */
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
SHIVER — Subtle vibration and micro-rotation
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes shiver {
|
||||
0%, 100% {
|
||||
transform: translate(0, 0) rotate(0deg);
|
||||
|
|
@ -34,12 +34,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
.shiver {
|
||||
.text-shiver {
|
||||
display: inline-block;
|
||||
animation: shiver 0.8s ease-in-out infinite;
|
||||
animation: shiver 0.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Wobble effect - gentle sway */
|
||||
.text-shiver:nth-child(2n) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
.text-shiver:nth-child(3n) {
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
WOBBLE — Gentle sway with rotation
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes wobble {
|
||||
0%, 100% {
|
||||
transform: rotate(0deg) translateY(0);
|
||||
|
|
@ -52,32 +63,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
.wobble {
|
||||
.text-wobble {
|
||||
display: inline-block;
|
||||
animation: wobble 2s ease-in-out infinite;
|
||||
animation: wobble 0.8s ease-in-out infinite;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
||||
/* Draw effect - simulate hand-drawing text */
|
||||
@keyframes draw-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
filter: blur(2px);
|
||||
transform: translateX(-10px) rotate(-5deg);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
filter: blur(0);
|
||||
transform: translateX(0) rotate(0deg);
|
||||
}
|
||||
.text-wobble:nth-child(2n) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
.draw {
|
||||
display: inline-block;
|
||||
animation: draw-in 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55) forwards;
|
||||
.text-wobble:nth-child(3n) {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
/* Jitter effect - erratic movement */
|
||||
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
JITTER — Erratic rapid movement
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes jitter {
|
||||
0%, 100% { transform: translate(0, 0); }
|
||||
10% { transform: translate(-2px, 1px); }
|
||||
|
|
@ -91,12 +95,15 @@
|
|||
90% { transform: translate(-2px, -2px); }
|
||||
}
|
||||
|
||||
.jitter {
|
||||
.text-jitter {
|
||||
display: inline-block;
|
||||
animation: jitter 0.5s ease-in-out infinite;
|
||||
animation: jitter 0.4s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Bounce effect - playful bounce */
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
BOUNCE — Playful vertical bounce
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes bounce {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
|
|
@ -106,35 +113,111 @@
|
|||
}
|
||||
}
|
||||
|
||||
.bounce {
|
||||
.text-bounce {
|
||||
display: inline-block;
|
||||
animation: bounce 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
/* Stagger animations for multiple elements */
|
||||
.shiver:nth-child(2n) {
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
BOBBING — Independent vertical movement with staggered timing
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes bobbing {
|
||||
0%, 100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
}
|
||||
|
||||
.text-bob {
|
||||
display: inline-block;
|
||||
animation: bobbing 1.8s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.text-bob:nth-child(2n) {
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
.shiver:nth-child(3n) {
|
||||
animation-delay: 0.2s;
|
||||
.text-bob:nth-child(3n) {
|
||||
animation-delay: 0.25s;
|
||||
}
|
||||
|
||||
.wobble:nth-child(2n) {
|
||||
.text-bob:nth-child(4n) {
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
.text-bob:nth-child(5n) {
|
||||
animation-delay: 0.55s;
|
||||
}
|
||||
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
WAVE — Letters move up and down in a flowing wave pattern
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@keyframes wave {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
12.5% {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
25% {
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
37.5% {
|
||||
transform: translateY(-12px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
62.5% {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
75% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
87.5% {
|
||||
transform: translateY(2px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
.text-wave {
|
||||
display: inline-block;
|
||||
animation: wave 1.2s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.text-wave:nth-child(2n) {
|
||||
animation-delay: 0.15s;
|
||||
}
|
||||
|
||||
.text-wave:nth-child(3n) {
|
||||
animation-delay: 0.3s;
|
||||
}
|
||||
|
||||
.wobble:nth-child(3n) {
|
||||
.text-wave:nth-child(4n) {
|
||||
animation-delay: 0.45s;
|
||||
}
|
||||
|
||||
.text-wave:nth-child(5n) {
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
/* Reduce motion for accessibility */
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════════════
|
||||
ACCESSIBILITY — Respect motion preferences
|
||||
═══════════════════════════════════════════════════════════════════════ */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.shiver,
|
||||
.wobble,
|
||||
.draw,
|
||||
.jitter,
|
||||
.bounce {
|
||||
.text-shiver,
|
||||
.text-wobble,
|
||||
.text-jitter,
|
||||
.text-bounce,
|
||||
.text-bob,
|
||||
.text-wave {
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
layout: mix
|
||||
title: "Tomorrow’s Bacon"
|
||||
title: "Tomorrow's Bacon"
|
||||
project: TomorrowsBacon
|
||||
permalink: /mixes/tomorrowsbacon/index.html
|
||||
go: tomorrowsbacon
|
||||
|
|
@ -9,6 +9,20 @@ A digital mixed CD.
|
|||
|
||||
Argument goes here, eventually. In the meantime, imagine that I pasted in some filler text.
|
||||
|
||||
{% animateText "shivering", "shiver" %}
|
||||
{% animateText "wobbling", "wobble" %}
|
||||
{% animateText "jittering", "jitter" %}
|
||||
{% animateText "bouncing", "bounce" %}
|
||||
{% animateText "bobbing up and down!", "bob" %}
|
||||
{% animateText "wave motion!", "wave" %}
|
||||
{% animateText "slower wave", "wave", "0.5" %}
|
||||
{% animateText "fast shiver", "shiver", "2" %}
|
||||
{% animateText "glacial", "wobble", "0.1" %}
|
||||
|
||||
{% animateText "glacial", "shiver", "0.1" %}
|
||||
|
||||
|
||||
|
||||
{% set itemList = collections.mix %}
|
||||
{% set headingLevel = "h3" %}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@ const spacing = tokensToTailwind(clampGenerator(spacingTokens.items));
|
|||
|
||||
export default {
|
||||
content: ['./src/**/*.{html,js,md,njk,liquid,webc}'],
|
||||
safelist: [
|
||||
'text-shiver',
|
||||
'text-wobble',
|
||||
'text-jitter',
|
||||
'text-bounce',
|
||||
'text-bob',
|
||||
'text-wave'
|
||||
],
|
||||
presets: [],
|
||||
theme: {
|
||||
screens: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue