diff --git a/package-lock.json b/package-lock.json index e01389f5..a3ddc583 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2863,16 +2863,6 @@ } } }, - "node_modules/@thednp/bezier-easing": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@thednp/bezier-easing/-/bezier-easing-1.0.7.tgz", - "integrity": "sha512-A/M4ijFjRu8bTSbCqhQs7xsFA20hbtlEenER7rK3j8OgS7jk9MdN51P4uhCHXUDoTTWjCH49/6wvP4CaRKyKHQ==" - }, - "node_modules/@thednp/shorty": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@thednp/shorty/-/shorty-1.0.3.tgz", - "integrity": "sha512-PPaERUGmRpi2eWxYUV5yv/pvalPgPOjwKRmRqGMWGuV8xgkvxgtjKIiFJA2D2ei4l4Ih9mEBktDg6Z9+y+To9Q==" - }, "node_modules/@theguild/remark-mermaid": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/@theguild/remark-mermaid/-/remark-mermaid-0.0.5.tgz", @@ -5577,12 +5567,6 @@ "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", "dev": true }, - "node_modules/dommatrix": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/dommatrix/-/dommatrix-1.0.3.tgz", - "integrity": "sha512-l32Xp/TLgWb8ReqbVJAFIvXmY7go4nTxxlWiAFyhoQw9RKEOHBZNnyGvJWqDVSPmq3Y9HlM4npqF/T6VMOXhww==", - "deprecated": "dommatrix is no longer maintained. Please use @thednp/dommatrix." - }, "node_modules/dompurify": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz", @@ -8856,17 +8840,6 @@ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", "dev": true }, - "node_modules/kute.js": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/kute.js/-/kute.js-2.2.4.tgz", - "integrity": "sha512-M63qfJplLT/1+qeRdFtHimC0D4fqUyRqHJcsnWWTY9s+isB6TsNNx/oSR2XzMm4CsY9Rvqurd+xUYSyJggmhbQ==", - "dependencies": { - "@thednp/bezier-easing": "^1.0.1", - "@thednp/shorty": "^1.0.3", - "minifill": "^0.0.17", - "svg-path-commander": "1.0.5" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -10161,11 +10134,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minifill": { - "version": "0.0.17", - "resolved": "https://registry.npmjs.org/minifill/-/minifill-0.0.17.tgz", - "integrity": "sha512-tV56LFXsi8vjH4tUExtlu8aPKKQw/U/mn4OIrDU9x30H+9sP8/dWFbXzkAPmcH6o+9fho98kyafnk4VgQViYQQ==" - }, "node_modules/minimatch": { "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", @@ -13012,14 +12980,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/svg-path-commander": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/svg-path-commander/-/svg-path-commander-1.0.5.tgz", - "integrity": "sha512-hhQfARVXoPrwwe4DNPWM4hjQLK7rTxwQ+TUc5mxoe5g0k5eStc4SPnKqmivlm/dzZ98bI+yDyKye92n2t+oOiQ==", - "dependencies": { - "dommatrix": "^1.0.3" - } - }, "node_modules/tailwind-merge": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.2.tgz", @@ -15691,7 +15651,6 @@ "clsx": "^2.1.1", "framer-motion": "^11.11.1", "hamburger-react": "^2.5.0", - "kute.js": "^2.2.4", "lucide-react": "^0.446.0", "moment": "^2.30.1", "next": "14.2.5", diff --git a/website/app/globals.css b/website/app/globals.css index bf6a977e..781bbe96 100644 --- a/website/app/globals.css +++ b/website/app/globals.css @@ -31,7 +31,7 @@ body { } .react-grid-sample2 { - background: linear-gradient(to bottom, #ffffff 80%, transparent 80%), url(../public/static/bg-texture-2.png); + background: linear-gradient(to bottom, #ffffff 80%, transparent 80%), url(../public/static/noise-texture-2.webp); } /* override daisyui theme */ @@ -67,11 +67,11 @@ body { } .texture-bg { - background-image: url(../public/static/bg-texture.png); + background-image: url(../public/static/noise-texture-1.webp); } .texture-bg-2 { - background-image: url(../public/static/bg-texture-2.png); + background-image: url(../public/static/noise-texture-2.webp); } .LiveCode input[type="date"]::-webkit-calendar-picker-indicator { diff --git a/website/app/support/page.tsx b/website/app/support/page.tsx index caa7ffe8..458a1102 100644 --- a/website/app/support/page.tsx +++ b/website/app/support/page.tsx @@ -9,12 +9,12 @@ export default function FeaturesPage() {
@@ -47,7 +47,7 @@ export default function FeaturesPage() { page
diff --git a/website/components/bg-shapes.tsx b/website/components/bg-shapes.tsx index 23a51d50..587ad009 100644 --- a/website/components/bg-shapes.tsx +++ b/website/components/bg-shapes.tsx @@ -1,18 +1,36 @@ "use client"; +import { easeInOut, interpolatePaths } from "@/lib/path-interpolation"; import { useEffect } from "react"; -import KUTE from "kute.js"; const Shape1 = () => { useEffect(() => { - const tween1 = KUTE.fromTo( - "#s1-blob1", - { path: "#s1-blob1" }, - { path: "#s1-blob2" }, - { duration: 3500, yoyo: true, repeat: 100 } - ); - - tween1.start(); + const blob1 = document.getElementById("s1-blob1"); + const path1 = blob1?.getAttribute("d"); + const path2 = document.getElementById("s1-blob2")?.getAttribute("d"); + + let startTime: number; + const duration = 11000; + + const animateBlob = (timestamp: number) => { + if (!startTime) startTime = timestamp; + const elapsed = timestamp - startTime; + const progress = (elapsed % duration) / duration; // Normalized progress (0 to 1) + const easedProgress = easeInOut(progress); + + if (!blob1 || !path1 || !path2) return; + + const currentPath = interpolatePaths( + path1, + path2, + Math.abs(Math.sin(easedProgress * Math.PI)) + ); + blob1?.setAttribute("d", currentPath); + + requestAnimationFrame(animateBlob); + }; + + requestAnimationFrame(animateBlob); }, []); return ( @@ -45,14 +63,32 @@ const Shape1 = () => { const Shape2 = () => { useEffect(() => { - const tween1 = KUTE.fromTo( - "#s2-blob1", - { path: "#s2-blob1" }, - { path: "#s2-blob2" }, - { duration: 3500, yoyo: true, repeat: 100 } - ); - - tween1.start(); + const blob1 = document.getElementById("s2-blob1"); + const path1 = blob1?.getAttribute("d"); + const path2 = document.getElementById("s2-blob2")?.getAttribute("d"); + + let startTime: number; + const duration = 11000; + + const animateBlob = (timestamp: number) => { + if (!startTime) startTime = timestamp; + const elapsed = timestamp - startTime; + const progress = (elapsed % duration) / duration; // Normalized progress (0 to 1) + const easedProgress = easeInOut(progress); + + if (!blob1 || !path1 || !path2) return; + + const currentPath = interpolatePaths( + path1, + path2, + Math.abs(Math.sin(easedProgress * Math.PI)) + ); + blob1?.setAttribute("d", currentPath); + + requestAnimationFrame(animateBlob); + }; + + requestAnimationFrame(animateBlob); }, []); return ( diff --git a/website/components/footer.tsx b/website/components/footer.tsx index 12a4b1e9..f177e945 100644 --- a/website/components/footer.tsx +++ b/website/components/footer.tsx @@ -67,7 +67,7 @@ export const Footer = () => {