Skip to content

Commit

Permalink
Make them words dance
Browse files Browse the repository at this point in the history
  • Loading branch information
xypnox committed Jan 7, 2024
1 parent c39b67b commit ccca714
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 64 deletions.
59 changes: 0 additions & 59 deletions src/components/colorPoem.astro

This file was deleted.

87 changes: 87 additions & 0 deletions src/components/colorPoem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { keyframes, styled } from 'solid-styled-components';
import { flattenObject } from '../lib/objects';
import { For, createMemo } from 'solid-js';

export type Props = {
poem: string;
colors: string[];
};

/* CSS Animate text color between the array of colors for 3 seconds between each color */
function colorShiftGradientAnimation(colors: string[]) {
const colorShiftGradient = colors.map((color, index) => {
return `${Math.round(index * 100 / colors.length)}% { color: ${color}; }`;
});
return `
${colorShiftGradient.join("")}
`;
}

export const ColorPoem = ({ poem, colors }: Props) => {
const colorVars = flattenObject({ colors }, (keys, value) => [
`poem-${keys.join("-")}`,
value,
]);

const cssColorVars = Object.entries(colorVars)
.map(([key, value]) => `--${key}: ${value};`)
.join("\n");

const cssColorVarsArray = Object.entries(colorVars).map(([key, value]) => `var(--${key})`);

function splitText(poem: string) {
const poemLines = poem.split("\n");
const coloredPoemLines = poemLines.map((line) => {
const words = line.split(" ");
return words;
});
return coloredPoemLines;
}

// console.log({
// cp: splitText(poem),
// cssColorVars,
// colorVars,
// colors,
// poem,
// cssColorVarsArray,
// clg: colorShiftGradientAnimation(colors),
// });

const colorKeyframes = createMemo(() => (colors: string[]) => keyframes`
${colorShiftGradientAnimation(colors)}
`)

const Word = createMemo(() => (colors: string[]) => styled('span')`
animation: ${colorKeyframes()(colors)} 5s linear alternate infinite;
animation-delay: var(--poem-line-word-delay);
color: var(--poem-line-word-color);
`)

const WordComp = Word()(cssColorVarsArray);

return <div style={cssColorVars}>
<For each={splitText(poem)}>{(line) => {
return (
<PoemLine>
<For each={line}>{(word, index) => {
return <WordComp style={{
"--poem-line-word-delay": `${(index() / line.length * 5).toFixed(2)}s`,
"--poem-line-word-color": colors[index() % colors.length],
}} >{word}</WordComp>;
}}</For>
</PoemLine>
);
}}</For>
</div>

}


const PoemLine = styled('div')`
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 0.5rem;
min-height: 1.5rem;
`;
6 changes: 4 additions & 2 deletions src/content/poems/water-under-the-bridge.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ title: "Water under the bridge"
date: 2024-01-06
---

import ColorPoem from '../../components/colorPoem.astro'
import { ColorPoem } from '../../components/colorPoem.tsx'

<ColorPoem poem={
<ColorPoem
client:load
poem={
`Water under the bridge
is tumbling in a river
Save the ones still swimming
Expand Down
4 changes: 1 addition & 3 deletions src/layouts/BaseLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ const { title, meta, showLoading, htmlClass, themeCssVars } = Astro.props;
<script>
import "iconify-icon";
</script>
<script is:inline>
import "../scripts/instantPage.js"
</script>
<script src="../scripts/instantPage.js"></script>
</html>

<style is:global define:vars={themeCssVars ?? {}}></style>

0 comments on commit ccca714

Please sign in to comment.