From 7ae960aae0ef87f39883ec123771c27bda38d51b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Roche?= Date: Sat, 28 Dec 2024 18:57:59 +0100 Subject: [PATCH] tempus --- .vscode/settings.json | 3 +++ app/(pages)/(components)/lenis/index.jsx | 16 ++++++------- app/(pages)/home/page.jsx | 2 +- app/(pages)/layout.jsx | 2 ++ components/gsap/index.tsx | 4 ++-- components/link/index.tsx | 16 ++++++------- components/marquee/index.tsx | 20 ++++++++-------- docs/gsap/README.md | 2 +- hooks/use-framerate.ts | 24 -------------------- libs/orchestra/minimap/index.tsx | 29 ++++++++++++------------ libs/orchestra/stats/index.ts | 28 +++++++++++++++-------- libs/webgl/components/raf/index.ts | 15 ++++++++---- next-env.d.ts | 2 +- package.json | 4 ++-- pnpm-lock.yaml | 28 ++++++++++++++++------- styles/global.css | 4 ++++ 16 files changed, 103 insertions(+), 96 deletions(-) delete mode 100644 hooks/use-framerate.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 51890e60..50248034 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -22,5 +22,8 @@ }, "[typescript]": { "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" } } diff --git a/app/(pages)/(components)/lenis/index.jsx b/app/(pages)/(components)/lenis/index.jsx index ef3dd306..097f93bc 100644 --- a/app/(pages)/(components)/lenis/index.jsx +++ b/app/(pages)/(components)/lenis/index.jsx @@ -1,16 +1,16 @@ 'use client' -import { useFrame } from '@darkroom.engineering/hamo' import 'lenis/dist/lenis.css' import { ReactLenis } from 'lenis/react' import { useRef } from 'react' +import { useTempus } from 'tempus/react' export function Lenis({ root, options }) { const lenisRef = useRef() - useFrame((time) => { + useTempus((time) => { lenisRef.current.lenis.raf(time) - }, 0) + }) return ( { - return ( - node.nodeName === 'VERCEL-LIVE-FEEDBACK' || - node.id === 'theatrejs-studio-root' - ) - }, + anchors: true, + prevent: (node) => + node.nodeName === 'VERCEL-LIVE-FEEDBACK' || + node.id === 'theatrejs-studio-root', }} /> ) diff --git a/app/(pages)/home/page.jsx b/app/(pages)/home/page.jsx index bc37d3f8..187405fc 100644 --- a/app/(pages)/home/page.jsx +++ b/app/(pages)/home/page.jsx @@ -3,7 +3,7 @@ import s from './home.module.css' export default function Home() { return ( - + {/* content */} ) diff --git a/app/(pages)/layout.jsx b/app/(pages)/layout.jsx index 243b5537..9fb0e739 100644 --- a/app/(pages)/layout.jsx +++ b/app/(pages)/layout.jsx @@ -1,4 +1,5 @@ import { GoogleAnalytics, GoogleTagManager } from '@next/third-parties/google' +import { ReactTempus } from 'tempus/react' import { Debug } from '~/components/debug' import { GSAP } from '~/components/gsap' import { RealViewport } from '~/components/real-viewport' @@ -76,6 +77,7 @@ export default function Layout({ children }) { {children} + {GA_ID && } diff --git a/components/gsap/index.tsx b/components/gsap/index.tsx index e27d4c39..3a218bed 100644 --- a/components/gsap/index.tsx +++ b/components/gsap/index.tsx @@ -1,8 +1,8 @@ 'use client' -import Tempus from '@darkroom.engineering/tempus' import gsap from 'gsap' import { useLayoutEffect } from 'react' +import Tempus from 'tempus' import { ScrollTriggerConfig } from './scroll-trigger' export function GSAP({ scrollTrigger = false }) { @@ -14,7 +14,7 @@ export function GSAP({ scrollTrigger = false }) { gsap.ticker.remove(gsap.updateRoot) Tempus?.add((time: number) => { gsap.updateRoot(time / 1000) - }, 0) + }) }, []) return scrollTrigger && diff --git a/components/link/index.tsx b/components/link/index.tsx index c6a241fe..9d0dd6ea 100644 --- a/components/link/index.tsx +++ b/components/link/index.tsx @@ -1,8 +1,6 @@ 'use client' -import { useLenis } from 'lenis/react' import NextLink, { type LinkProps as NextLinkProps } from 'next/link' -import { usePathname } from 'next/navigation' import type { ElementType, HTMLAttributes, Ref } from 'react' interface LinkProps @@ -25,8 +23,8 @@ export function Link({ ref, ...props }: LinkProps) { - const lenis = useLenis() - const pathname = usePathname() + // const lenis = useLenis() + // const pathname = usePathname() if (!href || typeof href !== 'string') { const Tag = fallback @@ -42,16 +40,16 @@ export function Link({ rel: isExternal ? 'noopener noreferrer' : undefined, } - const isAnchor = href.startsWith('#') || href.startsWith(`${pathname}#`) + // const isAnchor = href.startsWith('#') || href.startsWith(`${pathname}#`) return ( { - if (isAnchor && lenis) { - e.preventDefault() - lenis.scrollTo(href) - } + // if (isAnchor && lenis) { + // e.preventDefault() + // lenis.scrollTo(href) + // } onClick?.(e) }} {...internalLinkProps} diff --git a/components/marquee/index.tsx b/components/marquee/index.tsx index 659d32c2..5246edba 100644 --- a/components/marquee/index.tsx +++ b/components/marquee/index.tsx @@ -1,15 +1,15 @@ -'use client' +"use client" import { - useFrame, useIntersectionObserver, useResizeObserver, -} from '@darkroom.engineering/hamo' -import cn from 'clsx' -import { useLenis } from 'lenis/react' -import { type HTMLAttributes, useRef } from 'react' -import { modulo } from '~/libs/maths' -import s from './marquee.module.css' +} from "@darkroom.engineering/hamo" +import cn from "clsx" +import { useLenis } from "lenis/react" +import { type HTMLAttributes, useRef } from "react" +import { useTempus } from "tempus/react" +import { modulo } from "~/libs/maths" +import s from "./marquee.module.css" interface MarqueeProps extends HTMLAttributes { repeat?: number @@ -40,7 +40,7 @@ export function Marquee({ const lenis = useLenis() // eslint-disable-line react-hooks/exhaustive-deps - useFrame((_, deltaTime) => { + useTempus((_, deltaTime) => { if (!intersection.isIntersecting) return if (pauseOnHover && isHovered.current) return @@ -89,7 +89,7 @@ export function Marquee({ }`} className={s.inner} aria-hidden={i !== 0} - data-nosnippet={i !== 0 ? '' : undefined} + data-nosnippet={i !== 0 ? "" : undefined} ref={(node) => { if (!node) return elementsRef.current[i] = node diff --git a/docs/gsap/README.md b/docs/gsap/README.md index c5fa2701..a0550242 100644 --- a/docs/gsap/README.md +++ b/docs/gsap/README.md @@ -4,7 +4,7 @@ Satūs uses GSAP for animations ## Usage -To setup GSAP in your project, you can import it like with the `` component, it will merge automatically merge GSAP ticker with [Tempus](https://www.npmjs.com/package/@darkroom.engineering/tempus). If `scrollTrigger` is passed as a prop, it will also setup ScrollTrigger so it's synced with [Lenis](https://www.npmjs.com/package/@darkroom.engineering/lenis). +To setup GSAP in your project, you can import it like with the `` component, it will merge automatically merge GSAP ticker with [Tempus](https://www.npmjs.com/package/tempus). If `scrollTrigger` is passed as a prop, it will also setup ScrollTrigger so it's synced with [Lenis](https://www.npmjs.com/package/lenis). ```jsx diff --git a/hooks/use-framerate.ts b/hooks/use-framerate.ts deleted file mode 100644 index 4ec86e1e..00000000 --- a/hooks/use-framerate.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { useFrame } from '@darkroom.engineering/hamo' -import { useRef } from 'react' - -type FPSValue = number | (() => number) -type FrameCallback = (time: number, deltaTime: number) => void - -export function useFramerate( - fps: FPSValue, - callback?: FrameCallback, - priority = 0 -): void { - const timeRef = useRef(0) - - useFrame((time, deltaTime) => { - timeRef.current += deltaTime - - const executionTime = 1000 / (typeof fps === 'function' ? fps() : fps) - - if (timeRef.current >= executionTime) { - timeRef.current = timeRef.current % executionTime - callback?.(time, deltaTime) - } - }, priority) -} diff --git a/libs/orchestra/minimap/index.tsx b/libs/orchestra/minimap/index.tsx index 82a49579..d5718f3a 100644 --- a/libs/orchestra/minimap/index.tsx +++ b/libs/orchestra/minimap/index.tsx @@ -1,9 +1,10 @@ -'use client' +"use client" -import { useFrame, useWindowSize } from '@darkroom.engineering/hamo' -import { useCallback, useEffect, useId, useRef, useState } from 'react' -import { create } from 'zustand' -import s from './minimap.module.css' +import { useWindowSize } from "@darkroom.engineering/hamo" +import { useCallback, useEffect, useId, useRef, useState } from "react" +import { useTempus } from "tempus/react" +import { create } from "zustand" +import s from "./minimap.module.css" type MinimapEntry = { element: HTMLElement @@ -18,7 +19,7 @@ const useMinimapStore = create(() => ({ list: {}, })) -export function useMinimap({ color = 'blue' } = {}) { +export function useMinimap({ color = "blue" } = {}) { const [element, setElement] = useState() const id = useId() @@ -47,7 +48,7 @@ export function useMinimap({ color = 'blue' } = {}) { } export function Minimap() { - const [aspectRatio, setAspectRatio] = useState('1') + const [aspectRatio, setAspectRatio] = useState("1") useEffect(() => { const resizeObserver = new ResizeObserver(([entry]) => { @@ -70,14 +71,14 @@ export function Minimap() { window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) - elementRef.current.style.setProperty('--progress', progress.toString()) + elementRef.current.style.setProperty("--progress", progress.toString()) }, []) useEffect(() => { - window.addEventListener('scroll', onScroll) + window.addEventListener("scroll", onScroll) return () => { - window.removeEventListener('scroll', onScroll) + window.removeEventListener("scroll", onScroll) } }, [onScroll]) @@ -89,8 +90,8 @@ export function Minimap() {
@@ -107,7 +108,7 @@ export function Minimap() { function Marker({ element, color }: MinimapEntry) { const markerRef = useRef(null!) - useFrame(() => { + useTempus(() => { if (!element) return if (!markerRef.current) return @@ -120,7 +121,7 @@ function Marker({ element, color }: MinimapEntry) { const width = rect.width / window.innerWidth // markerRef.current.style.top = `${top * 100}%` - markerRef.current.style.setProperty('--top', top.toString()) + markerRef.current.style.setProperty("--top", top.toString()) // markerRef.current.style.height = `${height * 100}%` markerRef.current.style.left = `${left * 100}%` markerRef.current.style.width = `${width * 100}%` diff --git a/libs/orchestra/stats/index.ts b/libs/orchestra/stats/index.ts index 80452ba7..75eda1fb 100644 --- a/libs/orchestra/stats/index.ts +++ b/libs/orchestra/stats/index.ts @@ -1,6 +1,6 @@ -import { useFrame } from '@darkroom.engineering/hamo' import { useEffect, useMemo } from 'react' import _Stats from 'stats-gl' +import { useTempus } from 'tempus/react' import s from './stats.module.css' export function Stats() { @@ -15,14 +15,22 @@ export function Stats() { } }, [stats]) - useFrame(() => { - stats.begin() - }, Number.NEGATIVE_INFINITY) - - useFrame(() => { - stats.end() - stats.update() - }, Number.POSITIVE_INFINITY) + useTempus( + () => { + stats.begin() + }, + { + priority: Number.NEGATIVE_INFINITY, + } + ) - return null + useTempus( + () => { + stats.end() + stats.update() + }, + { + priority: Number.POSITIVE_INFINITY, + } + ) } diff --git a/libs/webgl/components/raf/index.ts b/libs/webgl/components/raf/index.ts index 867d509d..2e2714a5 100644 --- a/libs/webgl/components/raf/index.ts +++ b/libs/webgl/components/raf/index.ts @@ -1,14 +1,19 @@ -import { useFrame } from '@darkroom.engineering/hamo' import { useThree } from '@react-three/fiber' +import { useTempus } from 'tempus/react' export function RAF({ render = true }) { const advance = useThree((state) => state.advance) - useFrame((time: number) => { - if (render) { - advance(time / 1000) + useTempus( + (time: number) => { + if (render) { + advance(time / 1000) + } + }, + { + priority: 1, } - }, 1) + ) return null } diff --git a/next-env.d.ts b/next-env.d.ts index 1b3be084..40c3d680 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -2,4 +2,4 @@ /// // NOTE: This file should not be edited -// see https://nextjs.org/docs/app/api-reference/config/typescript for more information. +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/package.json b/package.json index 7aa720fe..e59f5f3e 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ }, "dependencies": { "@darkroom.engineering/hamo": "0.6.46", - "@darkroom.engineering/tempus": "0.0.46", "@hubspot/api-client": "^12.0.1", "@next/third-parties": "^15.0.3", "@react-three/drei": "^9.115.0", @@ -28,7 +27,7 @@ "babel-plugin-react-compiler": "19.0.0-beta-a7bf2bd-20241110", "clsx": "^2.1.1", "gsap": "^3.12.5", - "lenis": "1.1.16", + "lenis": "1.1.19-dev.3", "next": "15.0.4", "postprocessing": "^6.36.4", "react": "19.0.0", @@ -39,6 +38,7 @@ "stats-gl": "^3.6.0", "storyblok-js-client": "^6.10.1", "storyblok-rich-text-react-renderer": "^2.9.2", + "tempus": "1.0.0-dev.5", "three": "^0.170.0", "tunnel-rat": "^0.1.2", "zustand": "5.0.1" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 46193432..916fc06d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,9 +14,6 @@ importers: '@darkroom.engineering/hamo': specifier: 0.6.46 version: 0.6.46(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@darkroom.engineering/tempus': - specifier: 0.0.46 - version: 0.0.46 '@hubspot/api-client': specifier: ^12.0.1 version: 12.0.1 @@ -48,8 +45,8 @@ importers: specifier: ^3.12.5 version: 3.12.5 lenis: - specifier: 1.1.16 - version: 1.1.16(react@19.0.0) + specifier: 1.1.19-dev.3 + version: 1.1.19-dev.3(react@19.0.0) next: specifier: 15.0.4 version: 15.0.4(@babel/core@7.26.0)(babel-plugin-react-compiler@19.0.0-beta-a7bf2bd-20241110)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.80.6) @@ -80,6 +77,9 @@ importers: storyblok-rich-text-react-renderer: specifier: ^2.9.2 version: 2.9.2(react@19.0.0) + tempus: + specifier: 1.0.0-dev.5 + version: 1.0.0-dev.5(react@19.0.0) three: specifier: ^0.170.0 version: 0.170.0 @@ -3871,8 +3871,8 @@ packages: resolution: {integrity: sha512-lMXbcFHNDr+gzy/7ghuJDVB/Yyycj+ZL/7pN3Gm/s5Xqrc9+5sj3IrDAPylcEJ1cKCbUnXbwESrhhqpcYv4d4g==} hasBin: true - lenis@1.1.16: - resolution: {integrity: sha512-bGS8IxJW3x310gTwFylgYU6bGzeVnTALmgyLP8RZ9DFSYC/hN3fi+urCWspr5otljbDAGF4ND2GKCFtemAd45Q==} + lenis@1.1.19-dev.3: + resolution: {integrity: sha512-GezqBOT+a2jS9XA0aa1rTyTeEeFkIYa7n36wbBeXWenvQDWYdR7vXcGMw2i3WfSxt/WgTYHMe46vEtIqQDrpxw==} peerDependencies: react: '>=17.0.0' vue: '>=3.0.0' @@ -5202,6 +5202,14 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} + tempus@1.0.0-dev.5: + resolution: {integrity: sha512-8uBIR/rKj41TJMGCN/0X4DcNAZJnehJzZR37M5vbWT0/cq0F525lP5w6hcaGXIe3ultlUzlGu0isfnX3yjME+A==} + peerDependencies: + react: '>=17.0.0' + peerDependenciesMeta: + react: + optional: true + terser-webpack-plugin@5.3.10: resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} engines: {node: '>= 10.13.0'} @@ -10055,7 +10063,7 @@ snapshots: lefthook-windows-arm64: 1.8.2 lefthook-windows-x64: 1.8.2 - lenis@1.1.16(react@19.0.0): + lenis@1.1.19-dev.3(react@19.0.0): optionalDependencies: react: 19.0.0 @@ -11554,6 +11562,10 @@ snapshots: tapable@2.2.1: {} + tempus@1.0.0-dev.5(react@19.0.0): + optionalDependencies: + react: 19.0.0 + terser-webpack-plugin@5.3.10(esbuild@0.24.0)(webpack@5.96.1(esbuild@0.24.0)): dependencies: '@jridgewell/trace-mapping': 0.3.25 diff --git a/styles/global.css b/styles/global.css index 9046cff0..8d2becc0 100644 --- a/styles/global.css +++ b/styles/global.css @@ -12,6 +12,10 @@ } } +* { + scrollbar-width: thin; +} + /* Core styles that shouldn't be reset */ body { min-height: 100vh;