From 4bca6b44bc61fecdd9c85d935efbe75bcb6488f7 Mon Sep 17 00:00:00 2001 From: cole Date: Mon, 1 Apr 2024 17:20:58 +0800 Subject: [PATCH] docs: add react hook demo --- eslint.config.js | 1 + playground/public/react.svg | 1 + playground/public/vue.svg | 1 + playground/src/demos/WithReact.tsx | 42 +++++++++++++++++++++++ playground/src/hooks/useResizeObserver.ts | 33 ++++++++++++++++++ playground/src/pages/index.mdx | 10 ++++-- 6 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 playground/public/react.svg create mode 100644 playground/public/vue.svg create mode 100644 playground/src/demos/WithReact.tsx create mode 100644 playground/src/hooks/useResizeObserver.ts diff --git a/eslint.config.js b/eslint.config.js index 66da7ba..7beb9e0 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -4,4 +4,5 @@ export default bernankez({ unocss: true, astro: true, formatters: true, + vue: true, }); diff --git a/playground/public/react.svg b/playground/public/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/playground/public/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/public/vue.svg b/playground/public/vue.svg new file mode 100644 index 0000000..770e9d3 --- /dev/null +++ b/playground/public/vue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/playground/src/demos/WithReact.tsx b/playground/src/demos/WithReact.tsx new file mode 100644 index 0000000..fd6029d --- /dev/null +++ b/playground/src/demos/WithReact.tsx @@ -0,0 +1,42 @@ +import { useBackmoji, useImageLoader, useImageRenderer } from "@backmoji/react"; +import ReactLogo from "/react.svg?url"; +import { useEffect, useRef } from "react"; +import { useLatest } from "ahooks"; +import { useResizeObserver } from "../hooks/useResizeObserver"; + +export function WithReact() { + const canvasRef = useRef(null); + + const img = useImageLoader(ReactLogo); + const renderer = useImageRenderer(img); + const backmojiResult = useBackmoji(renderer, canvasRef, { + height: 150, + rowGap: 15, + columnGap: 30, + }); + const { render, canvas, setSize } = useLatest(backmojiResult).current; + const divRef = useResizeObserver((entries) => { + for (const entry of entries) { + const { width, height } = entry.contentRect; + setSize?.(width, height); + render?.(); + } + }); + + useEffect(() => { + if (canvas) { + setSize?.(divRef.current?.clientWidth, divRef.current?.clientHeight); + render?.(); + + return () => { + canvas.remove(); + }; + } + }, [canvas]); + + return ( +
+ +
+ ); +} diff --git a/playground/src/hooks/useResizeObserver.ts b/playground/src/hooks/useResizeObserver.ts new file mode 100644 index 0000000..37f4ad6 --- /dev/null +++ b/playground/src/hooks/useResizeObserver.ts @@ -0,0 +1,33 @@ +import { useLatest } from "ahooks"; +import { useEffect, useRef, useState } from "react"; + +export function useResizeObserver( + callback: ResizeObserverCallback, + options?: ResizeObserverOptions, +): React.RefObject { + const ref = useRef(null); + const callbackRef = useLatest(callback); + + useEffect(() => { + const { current } = ref; + + if (!current) { + return; + } + + const cb: ResizeObserverCallback = (entries, observer) => { + return callbackRef.current(entries, observer); + }; + + const observer = new ResizeObserver(cb); + observer.observe(current, options); + + return () => { + if (current) { + observer.unobserve(current); + } + }; + }, [options]); + + return ref; +} diff --git a/playground/src/pages/index.mdx b/playground/src/pages/index.mdx index 79321f2..492a2d0 100644 --- a/playground/src/pages/index.mdx +++ b/playground/src/pages/index.mdx @@ -127,8 +127,12 @@ render(); ### Render with animation -### Use with React +### Using with React -### Use with Vue +import { WithReact } from "@/demos/WithReact"; -### Options \ No newline at end of file + + +### Using with Vue + +### Options