Skip to content

Commit

Permalink
feat: add animations examples
Browse files Browse the repository at this point in the history
  • Loading branch information
yjose committed Nov 8, 2024
1 parent 96fd966 commit da27b63
Show file tree
Hide file tree
Showing 11 changed files with 162 additions and 21 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"tailwind-merge": "^2.5.3",
"tailwindcss-motion": "0.4.1-beta",
"tsx": "^4.19.1",
"typescript-eslint": "^8.5.0"
},
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/videos/review-demo.mp4
Binary file not shown.
3 changes: 2 additions & 1 deletion src/components/home/hero-animation.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
</div>

<!-- TODO: consider using canvas lit -->
<script is:inline src="https://unpkg.com/@rive-app/[email protected]"></script>
<script is:inline src="https://unpkg.com/@rive-app/[email protected]"></script>
<!-- <script is:inline src="https://unpkg.com/@rive-app/[email protected]"></script> -->
<script>
import { Rive } from "@rive-app/canvas";
const r = new Rive({
Expand Down
97 changes: 92 additions & 5 deletions src/components/home/hero.astro
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,54 @@ import HeroAnimation from "./hero-animation.astro";
<div class="flex flex-col items-center lg:flex-row">
<div class="z-10">
<h1
class="w-full max-w-screen-lg text-center font-sans text-heading-lg font-bold md:text-left md:text-title"
class="motion-preset-slide-down block w-full max-w-screen-lg text-center font-sans text-heading-lg font-bold md:hidden md:text-left md:text-title"
>
Shaping the future of Moroccan IT community, one step at a time
</h1>

<div
class="hidden w-full max-w-screen-lg text-center font-sans text-heading-lg font-bold md:block md:text-left md:text-title"
>
<p class="m-preset-typewriter-[22] motion-loop-once">
Shaping the future of
</p>
<p
class="m-preset-typewriter-[22] motion-delay-[700ms] motion-loop-once"
>
Moroccan IT community,
</p>
<p
class="m-preset-typewriter-[18] motion-delay-[1400ms] motion-loop-once"
>
one step at a time
</p>
</div>
<p
class="my-8 max-w-[600px] text-center font-sans text-label-sm font-thin md:text-left"
class="motion-preset-slide-down my-8 max-w-[600px] text-center font-sans text-label-sm font-thin motion-delay-[1600ms] motion-ease-spring-smooth md:text-left"
>
Your journey from learning to leading unfolds: insightful Podcast,
aspiring videos, cutting edge OSS projects, in depth conferences and
many more.
</p>
<div class="flex justify-center space-x-4 py-4 md:justify-start">
<ButtonLink href="#projects">
<ButtonLink
href="#projects"
className="motion-preset-slide-down motion-delay-[1800ms] motion-ease-spring-smooth"
>
Discover projects <Icon name="arrow-right" class="ml-2 rotate-45" />
</ButtonLink>
<ButtonLink variant="outline" className="hidden self-center md:flex">
<ButtonLink
variant="outline"
className="motion-ease-spring-smoothhidden motion-preset-slide-down self-center motion-delay-[2000ms] md:flex"
>
Podcast <Icon name="arrow-right" class="ml-2" />
</ButtonLink>
</div>
</div>
</div>
</div>
<div
class="container pointer-events-none relative z-20 mx-auto mt-2 px-4 md:-mt-36"
class="container motion-preset-slide-up pointer-events-none relative z-20 mx-auto mt-2 px-4 motion-delay-[1800ms] motion-ease-spring-smooth md:-mt-36"
>
<HeroAnimation />
</div>
Expand All @@ -49,4 +73,67 @@ import HeroAnimation from "./hero-animation.astro";
linear-gradient(to bottom, #000 1px, transparent 1px);
background-size: 200px 200px;
}
/* custom typewriter animation based on tailwind motion but with some tweaks to make it work for our use case */
.m-preset-typewriter-\[22\] {
--motion-duration: 2500ms;
--motion-typewriter-value: 22ch;
animation:
typing var(--motion-duration) steps(22) var(--motion-delay, 0ms) forwards,
blink 0.4s step-end var(--motion-delay, 0ms) none;
white-space: nowrap;
border-right: 2px solid;
border-color: transparent;
font-family: monospace;
overflow: hidden;
width: 0;
}
.m-preset-typewriter-\[18\] {
--motion-duration: 2000ms;
--motion-typewriter-value: 18ch;
animation:
typing var(--motion-duration) steps(18) var(--motion-delay, 0ms) forwards,
blink-last-line 0.4s step-end var(--motion-delay, 0ms) infinite;
white-space: nowrap;
border-right: 2px solid;
border-color: transparent;
font-family: monospace;
overflow: hidden;
width: 0;
}
@media screen and (prefers-reduced-motion: no-preference) {
@keyframes typing {
10% {
width: 0;
}
40%,
60% {
width: calc(var(--motion-typewriter-value) + 1px);
}
100% {
width: var(--motion-typewriter-value);
}
}
}
@keyframes blink {
0% {
border-color: black;
}
50% {
border-color: black;
}
95% {
border-color: black;
}
100% {
border-color: transparent;
}
}
@keyframes blink-last-line {
50% {
border-color: black;
}
100% {
border-color: black;
}
}
</style>
13 changes: 11 additions & 2 deletions src/components/home/testimonials.astro
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@ const testimonials: Testimonial[] = testimonialsData;
<div class="relative">
<video
src={testimonial.video}
class="aspect-[9/12] w-full object-cover"
class="aspect-[9/16] w-full object-cover"
id={`video-${testimonial.name}`}
/>
<div class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-50">
<div
class="absolute inset-0 flex cursor-pointer items-center justify-center bg-black bg-opacity-50 transition-opacity duration-300"
id={`overlay-${testimonial.name}`}
onclick={`
document.getElementById('video-${testimonial.name}').play();
this.style.opacity = '0';
setTimeout(() => this.style.display = 'none', 300);
`}
>
<button class="text-4xl text-white" aria-label="Play video">
</button>
Expand Down
6 changes: 3 additions & 3 deletions src/components/home/testimonials.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@
"role": "Mobile tribe lead",
"company": "@bytesio",
"profile_image": "/testimonials/elazizlyoussouf.jpg",
"video": "/testimonials/elazizlyoussouf.mp4"
"video": "/videos/review-demo.mp4"
},
{
"name": "@_iMeriem",
"role": "Software engineer",
"company": "@Ultraken",
"profile_image": "/testimonials/imeriem.jpg",
"video": "/testimonials/imeriem.mp4"
"video": "/videos/review-demo.mp4"
},
{
"name": "@adnanmarokchi",
"role": "Full stack java developer",
"company": "@ti4it.com",
"profile_image": "/testimonials/adnanmarokchi.jpg",
"video": "/testimonials/adnanmarokchi.mp4"
"video": "/videos/review-demo.mp4"
},
{
"name": "@SarahDev",
Expand Down
22 changes: 16 additions & 6 deletions src/components/home/values-and-mission.astro
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,19 @@ const mission = [
];
---

<section class="bg-[#F2F4F7] py-16 font-light">
<section
id="mission"
class="group bg-[#F2F4F7] py-16 font-light"
data-visible-in-the-view="false"
>
<div class="container mx-auto px-4">
<h2 class="mb-8 text-center text-4xl font-bold md:text-left">
<h2
class="mb-8 text-center text-4xl font-bold group-data-[visible-in-the-view=true]:motion-preset-slide-down group-data-[visible-in-the-view=true]:motion-delay-200 md:text-left"
>
Our mission
</h2>
<p
class="mb-12 max-w-[800px] text-center text-paragraph-lg font-thin text-neutral-dark-50 md:text-left"
class="group-data-[visible-in-the-view=true]:motion-delay-400 mb-12 max-w-[800px] text-center text-paragraph-lg font-thin text-neutral-dark-50 group-data-[visible-in-the-view=true]:motion-preset-slide-down md:text-left"
>
Is to Empower Moroccan 🇲🇦 IT enthusiasts and beyond to thrive through
continuous learning, exchange, collaboration, and innovation.
Expand All @@ -55,7 +61,7 @@ const mission = [
<div class="mb-12 grid grid-cols-1 gap-8 sm:grid-cols-3">
{
mission.map(item => (
<div>
<div class="group-data-[visible-in-the-view=true]:motion-delay-600 group-data-[visible-in-the-view=true]:motion-preset-slide-down">
<h4 class="mb-4 text-center text-label-lg font-semibold md:text-left">
{item.title}
</h4>
Expand All @@ -67,11 +73,15 @@ const mission = [
}
</div>

<h2 class="my-8 text-center text-4xl font-bold md:text-left">Our values</h2>
<h2
class="group-data-[visible-in-the-view=true]:motion-delay-800 my-8 text-center text-4xl font-bold group-data-[visible-in-the-view=true]:motion-preset-slide-down md:text-left"
>
Our values
</h2>
<div class="grid grid-cols-2 gap-8 md:grid-cols-3">
{
values.map(value => (
<div class="flex flex-col items-center">
<div class="flex flex-col items-center group-data-[visible-in-the-view=true]:motion-preset-slide-down group-data-[visible-in-the-view=true]:motion-delay-1000">
<div class="mb-4 h-24">
<Image src={value.icon} class="h-full w-24" alt={value.name} />
</div>
Expand Down
21 changes: 21 additions & 0 deletions src/components/layout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -66,5 +66,26 @@ const socialImageURL = new URL(
<body>
<slot />
<Footer />
<script>
const observerCallback: IntersectionObserverCallback = entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.setAttribute("data-visible-in-the-view", "true");
}
});
};

// Create observer with options
const observer = new IntersectionObserver(observerCallback, {
threshold: 0.1, // Trigger when at least 10% of the element is visible
});

// Observe all elements with the data attribute
document
.querySelectorAll("[data-visible-in-the-view]")
.forEach(element => {
observer.observe(element);
});
</script>
</body>
</html>
6 changes: 3 additions & 3 deletions src/components/podcast/hero-animation.astro
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
</div>

<!-- consider using canvas lit -->
<script is:inline src="https://unpkg.com/@rive-app/[email protected]"></script>
<script is:inline src="https://unpkg.com/@rive-app/[email protected]"></script>

<!-- <script is:inline src="https://unpkg.com/@rive-app/[email protected]"></script> -->
<script>
import { Rive } from "@rive-app/canvas";
const r = new Rive({
src: "/animations/podcast_hero_graphic.riv",
canvas: document.getElementById("canvas") as HTMLCanvasElement,
autoplay: true,

// stateMachines: "Motion",
onLoad: () => {
// Ensure the drawing surface matches the canvas size and device pixel ratio
r.resizeDrawingSurfaceToCanvas();
Expand Down
2 changes: 1 addition & 1 deletion tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -153,5 +153,5 @@ module.exports = {
},
},
},
plugins: [require("@tailwindcss/typography")],
plugins: [require("@tailwindcss/typography"), require("tailwindcss-motion")],
};

0 comments on commit da27b63

Please sign in to comment.