From 93eb451880446de237992512520172962c501a29 Mon Sep 17 00:00:00 2001
From: Alvalen
Date: Mon, 1 Jul 2024 15:41:21 +0700
Subject: [PATCH] feat: add animate quote at about page
---
app/(root)/page.jsx | 7 ++-
app/about/(quote)/quote.jsx | 63 ++++++++++++++++++++
app/about/(quote)/style.css | 45 ++++++++++++++
app/about/(quote)/useIntersectionObserver.js | 32 ++++++++++
app/about/page.jsx | 21 +++++++
5 files changed, 167 insertions(+), 1 deletion(-)
create mode 100644 app/about/(quote)/quote.jsx
create mode 100644 app/about/(quote)/style.css
create mode 100644 app/about/(quote)/useIntersectionObserver.js
diff --git a/app/(root)/page.jsx b/app/(root)/page.jsx
index 8280b94..7bd6cc6 100644
--- a/app/(root)/page.jsx
+++ b/app/(root)/page.jsx
@@ -100,7 +100,12 @@ const MyPage = () => {
type: "spring",
}}>
diff --git a/app/about/(quote)/quote.jsx b/app/about/(quote)/quote.jsx
new file mode 100644
index 0000000..8b53c35
--- /dev/null
+++ b/app/about/(quote)/quote.jsx
@@ -0,0 +1,63 @@
+// Quote.js
+import "./style.css";
+import { motion } from "framer-motion";
+import { useIntersectionObserver } from "./useIntersectionObserver";
+
+export default function Quote() {
+ const text1 = '"There are no limits to what you can accomplish'.split(" ");
+ const text2 = 'except the limits you place on your own thinking."'.split(
+ " "
+ );
+ const [ref, isIntersecting] = useIntersectionObserver();
+
+ return (
+
+
+ {text1.map((word, index) => (
+
+ {word}{" "}
+
+ ))}
+
+
+ {text2.map((word, index) => (
+
+ {word}{" "}
+
+ ))}
+
+
+ );
+}
diff --git a/app/about/(quote)/style.css b/app/about/(quote)/style.css
new file mode 100644
index 0000000..9532051
--- /dev/null
+++ b/app/about/(quote)/style.css
@@ -0,0 +1,45 @@
+@keyframes scale {
+ 100% {
+ transform: scale(1);
+ -webkit-transform: scale(1);
+ -moz-transform: scale(1);
+ -ms-transform: scale(1);
+ -o-transform: scale(1);
+ }
+}
+
+@keyframes fade-in {
+ 100% {
+ opacity: 1;
+ filter: blur(0);
+ -webkit-filter: blur(0);
+ }
+}
+
+.q-wrap {
+ display: inline-block;
+ opacity: 1;
+ filter: blur(4px);
+ -webkit-filter: blur(4px);
+}
+
+.q-wrap:nth-child(1) {
+ animation: fade-in 0.8s 0.1 forwards cubic-bezier(0.11, 0, 0.5, 0);
+ -webkit-animation: fade-in 0.8s 0.1 forwards cubic-bezier(0.11, 0, 0.5, 0);
+}
+
+.q-wrap:nth-child(2) {
+ animation: fade-in 0.8s 0.2 forwards cubic-bezier(0.11, 0, 0.5, 0);
+ -webkit-animation: fade-in 0.8s 0.2 forwards cubic-bezier(0.11, 0, 0.5, 0);
+}
+
+.q {
+ text-align: center;
+ transform: scale(0.92);
+ -webkit-transform: scale(0.92);
+ -moz-transform: scale(0.92);
+ -ms-transform: scale(0.92);
+ -o-transform: scale(0.92);
+ animation: scale 3s forwards cubic-bezier(0.5, 1, 0.89, 1);
+ -webkit-animation: scale 3s forwards cubic-bezier(0.5, 1, 0.89, 1);
+}
\ No newline at end of file
diff --git a/app/about/(quote)/useIntersectionObserver.js b/app/about/(quote)/useIntersectionObserver.js
new file mode 100644
index 0000000..8ffdd9b
--- /dev/null
+++ b/app/about/(quote)/useIntersectionObserver.js
@@ -0,0 +1,32 @@
+// useIntersectionObserver.js
+import { useEffect, useState, useRef } from "react";
+
+export function useIntersectionObserver() {
+ const [isIntersecting, setIsIntersecting] = useState(false);
+ const ref = useRef(null);
+
+ useEffect(() => {
+ const observer = new IntersectionObserver(
+ ([entry]) => {
+ setIsIntersecting(entry.isIntersecting);
+ },
+ {
+ root: null,
+ rootMargin: "0px",
+ threshold: 0.1,
+ }
+ );
+
+ if (ref.current) {
+ observer.observe(ref.current);
+ }
+
+ return () => {
+ if (ref.current) {
+ observer.unobserve(ref.current);
+ }
+ };
+ }, []);
+
+ return [ref, isIntersecting];
+}
diff --git a/app/about/page.jsx b/app/about/page.jsx
index 5ab119e..fdd777d 100644
--- a/app/about/page.jsx
+++ b/app/about/page.jsx
@@ -8,6 +8,7 @@ import FixedButon from "@/components/FixedButton";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
import Card from "./(spotify)/card.jsx";
+import Quote from "./(quote)/quote.jsx";
// images
import Me1 from "@/public/img/me1.jpg";
@@ -453,6 +454,26 @@ export default function Page() {
+
+
+
+
+
+
>
);