Skip to content

Commit c754872

Browse files
committed
Add an animation in the welcome text
Slide in different kinds of volunteers, one at a time.
1 parent e16a369 commit c754872

File tree

2 files changed

+136
-3
lines changed

2 files changed

+136
-3
lines changed

src/components/WelcomeList.astro

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
---
2+
interface Props {
3+
volunteers?: string[];
4+
}
5+
6+
const { volunteers = ["developers", "designers"] } = Astro.props;
7+
---
8+
9+
<div>
10+
<div>We are a welcoming and inclusive volunteer group of</div>
11+
<div class="volunteer-anim">
12+
<div class="volunteer-anim-container">
13+
<div class="volunteer-text">{volunteers[0]}</div>
14+
<div class="volunteer-text"></div>
15+
&nbsp;
16+
</div>
17+
</div>
18+
<div>who use creative technology to address civic and social problems.</div>
19+
</div>
20+
21+
<style>
22+
.volunteer-anim {
23+
margin-left: -1em;
24+
padding-left: 1em;
25+
position: relative;
26+
overflow: hidden;
27+
}
28+
29+
.volunteer-anim-container {
30+
position: relative;
31+
container-type: inline-size;
32+
}
33+
34+
.volunteer-text {
35+
color: var(--color-stone-800);
36+
font-weight: 600;
37+
position: absolute;
38+
left: 0;
39+
top: 0;
40+
white-space: nowrap;
41+
opacity: 1;
42+
transform: translateX(0) skewX(0);
43+
transition: opacity 0.5s ease-out, transform .8s cubic-bezier(0.34, 1.51, 0.64, 1);
44+
}
45+
46+
.fade-out {
47+
opacity: 0;
48+
transition: opacity 0.25s ease-out;
49+
}
50+
51+
.slide-in {
52+
opacity: 1;
53+
transform: translateX(0) skewX(0);
54+
}
55+
56+
.pre-slide-in {
57+
opacity: 0;
58+
transform: translateX(100cqw) skewX(-60deg);
59+
}
60+
</style>
61+
62+
<script define:vars={{ volunteers }}>
63+
window.addEventListener("DOMContentLoaded", () => {
64+
let index = 0;
65+
let [outElem, inElem] = document.querySelectorAll(".volunteer-anim-container > div");
66+
67+
// we seem to have to add this class one time before showNext() does it below.
68+
// otherwise, the first element doesn't slide in correctly.
69+
inElem.classList.add("pre-slide-in");
70+
71+
function showNext()
72+
{
73+
if (!outElem || !inElem) {
74+
return;
75+
}
76+
77+
const nextIndex = (index + 1) % volunteers.length;
78+
79+
// set incoming text
80+
inElem.textContent = volunteers[nextIndex];
81+
inElem.style.display = "";
82+
inElem.classList.remove("fade-out");
83+
inElem.classList.add("pre-slide-in");
84+
85+
// start outgoing element's fade out
86+
outElem.classList.remove("slide-in", "pre-slide-in");
87+
outElem.classList.add("fade-out");
88+
89+
// animate the incoming element after giving the DOM a chance to update
90+
// after adding the pre-slide-in class
91+
setTimeout(() => {
92+
if (!outElem || !inElem) {
93+
return;
94+
}
95+
96+
inElem.classList.remove("pre-slide-in");
97+
inElem.classList.add("slide-in");
98+
}, 20);
99+
100+
// after the slide-in animation, swap element roles
101+
setTimeout(() => {
102+
if (!outElem || !inElem) {
103+
return;
104+
}
105+
106+
outElem.style.display = "none";
107+
inElem.style.display = "";
108+
index = nextIndex;
109+
[outElem, inElem] = [inElem, outElem];
110+
}, 850);
111+
}
112+
113+
// animate in the first element a second after the page loads, so it's more
114+
// noticeable the first time, and then start doing it every 3 seconds
115+
setTimeout(() => {
116+
showNext();
117+
setInterval(showNext, 3000);
118+
}, 1000);
119+
});
120+
</script>

src/pages/index.astro

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import CodeSummary from "@/components/CodeSummary.astro";
44
import NewsSummary from "@/components/NewsSummary.astro";
55
import BigText from "@/components/BigText.astro";
66
import Button from "@/components/Button.astro";
7+
import WelcomeList from "@/components/WelcomeList.astro";
78
import { newsletterURL, pitchProjectURL, slackURL } from "@/utils/urls";
89
910
const ButtonClass = `
@@ -15,6 +16,20 @@ const ButtonClass = `
1516
decoration-primary/0
1617
hover:decoration-primary/80
1718
`;
19+
const Volunteers = [
20+
"developers",
21+
"designers",
22+
"data geeks",
23+
"citizen activists",
24+
"bus riders",
25+
"learners",
26+
"user researchers",
27+
"cyclists",
28+
"community builders",
29+
"civic activists",
30+
"teachers",
31+
"project managers",
32+
];
1833
---
1934

2035
<BaseLayout title="Home" header="">
@@ -26,9 +41,7 @@ const ButtonClass = `
2641
</Fragment>
2742

2843
<Fragment slot="body">
29-
We are a welcoming and inclusive volunteer group of <i>developers</i>, <i>designers</i>,
30-
<i>data geeks</i>, and <i>citizen activists</i> who use creative technology to address civic
31-
and social problems.
44+
<WelcomeList volunteers={Volunteers} />
3245
</Fragment>
3346
</BigText>
3447

0 commit comments

Comments
 (0)