From a9356fe7b1a7eab21897d00de7485528bca6d0a6 Mon Sep 17 00:00:00 2001 From: Jesse Breuer Date: Sat, 29 Jun 2024 17:29:15 -0400 Subject: [PATCH] feat: Add GSAP for animations (#199) * feat: Add GSAP for animtations * feat: Rotate profile card img on scroll * fix: Fix jest error * style: Animate text on page load --- app/page.tsx | 2 +- .../cards/profile-card/profile-card.tsx | 32 +++++++++++++++++-- package-lock.json | 15 +++++++++ package.json | 1 + 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 41c5d55..effaf57 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -21,7 +21,7 @@ export const revalidate = 3600; // revalidate at most every hour export default function HomePage() { return ( <> -
+
diff --git a/components/cards/profile-card/profile-card.tsx b/components/cards/profile-card/profile-card.tsx index a8387fe..d92966d 100644 --- a/components/cards/profile-card/profile-card.tsx +++ b/components/cards/profile-card/profile-card.tsx @@ -1,6 +1,34 @@ +'use client'; + import Image from 'next/image'; +import gsap from 'gsap/dist/gsap'; // import from /dist to avoid ESM compiler issues +import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'; // import from /dist to avoid ESM compiler issues +import { TextPlugin } from 'gsap/dist/TextPlugin'; // import from /dist to avoid ESM compiler issues +import { useGSAP } from '@gsap/react'; + +gsap.registerPlugin(ScrollTrigger); +gsap.registerPlugin(TextPlugin); export function ProfileCard() { + useGSAP(() => { + gsap.to('.rotate-img', { + scrollTrigger: { + trigger: '.rotate-container', // start and end animation when element with this classname enters and leaves viewport + start: '-40px top', // start at -40px above the rotate-container top of viewport + end: 'bottom top', // end at bottom of rotate-container reaches top of scroller end + scrub: true, + }, + rotation: 360, + }); + + gsap.to('.figcaption-container', { + duration: 3, + text: { + value: 'Welcome to the garden.', + }, + }); + }); + return (
@@ -10,9 +38,9 @@ export function ProfileCard() { alt="A profile picture" width="128" height="128" - className="aspect-auto h-32 w-32 rounded-full duration-200 dark:grayscale dark:hover:grayscale-0" + className="rotate-img aspect-auto h-32 w-32 rounded-full" /> -
Welcome to the garden.
+
); diff --git a/package-lock.json b/package-lock.json index f45de87..3aedd54 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "digital-garden", "version": "1.0.0", "dependencies": { + "@gsap/react": "^2.1.1", "@octokit/rest": "^21.0.0", "@octokit/types": "^13.5.0", "@types/node": "20.14.2", @@ -816,6 +817,15 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@gsap/react": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@gsap/react/-/react-2.1.1.tgz", + "integrity": "sha512-apGPRrmpqxvl1T6Io1KgT8tFU+IuACI6z4zmT7t8+PASserJeLVRFJdSNUFA2Xb/eVkZI1noE8LIrY/w/oJECw==", + "dependencies": { + "gsap": "^3.12.5", + "react": ">=16" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", @@ -4963,6 +4973,11 @@ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, + "node_modules/gsap": { + "version": "3.12.5", + "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz", + "integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==" + }, "node_modules/has": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz", diff --git a/package.json b/package.json index 5f5d6c8..6060daa 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "test:coverage": "jest --coverage" }, "dependencies": { + "@gsap/react": "^2.1.1", "@octokit/rest": "^21.0.0", "@octokit/types": "^13.5.0", "@types/node": "20.14.2",