UNPKG

html-squircle

Version:

Utilities for generating superellipse squircles in the form of SVG strings, to be used in clip-path and background inline styles.

62 lines (49 loc) 1.7 kB
import { useMemo } from "react" import { clipSquircleObj } from "../core/clipSquircle.js" import { sortAndSerialize } from "../utils/sortAndSerialize.js" import { useCache } from "./CacheContext.js" import { useResizeObserver } from "./useResizeObserver.js" import type { RefObject } from "react" import type { SquircleOptionsClip, SquircleOptionsClipReact } from "../types.js" /** * Pass a ref for the observed element and options for the squircle computation * function. * * Note this will NOT work properly if you apply the style to an element your * component manages which may leave the DOM without your component unmounting. * Apply it only to elements which will be rendered unconditionally with your * component. */ export const useClipSquircle = ( ref: RefObject<Element | null>, options?: SquircleOptionsClipReact, ): ReturnType<typeof clipSquircleObj> => { // Observe the size const size = useResizeObserver(ref) // Get the cache if provided const cache = useCache() // Memoize the result const clipSquircle = useMemo(() => { // Add observed size to the size-less props const config: SquircleOptionsClip = { ...options, ...size, } // If no cache provided, just compute result if (!cache) { return clipSquircleObj(config) } // Compute cache key const cacheKey = sortAndSerialize(config) // Get from cache const cached = (cache.get(cacheKey) as ReturnType<typeof clipSquircleObj> | undefined) ?? clipSquircleObj(config) // Set in cache if (!cache.has(cacheKey)) { cache.set(cacheKey, cached) } return cached }, [cache, options, size]) return clipSquircle }