@ky28059/react-free-transform

A flexible, CSS matrix()-based library for free-transform of arbitrary HTML elements in React.

1npm i @ky28059/react-free-transform

Examples

A simple example using the base <FreeTransformContainer /> component:

A more complex example with custom transform controls, using the useFreeTransform() hook:

Usage

Component: <FreeTransformContainer />

For basic use cases, use the <FreeTransformContainer /> component. The FreeTransformContainer renders a wrapper div that registers the transform controls on itself. The current transformation, as well as some callback functions, are exposed to the component's children via a render callback.

1import { FreeTransformContainer } from '@ky28059/react-free-transform';
2
3export default function Example() {
4    return (
5        <FreeTransformContainer className="...">
6            {({ transform }) => (
7                // Render your wrapper children here
8                <img
9                    src="..."
10                    className="..."
11                    style={{ transform }}
12                    draggable={false}
13                />
14            )}
15        </FreeTransformContainer>
16    )
17}

Component API:

PropTypeValue
classNamestring?An optional className to apply to the wrapper div.
children(s: FreeTransformState) => ReactNodeA render function that returns the container's children.

where the render callback is passed an object with properties

PropTypeValue
transformstringThe CSS property value of the current transform.
zoom(p: number) => voidA callback that zooms the container by the given scale (e.g. zoom(0.3) roughly dilates the transform by 130%). To zoom out, pass a negative value (e.g. zoom(-0.1)).
reset() => voidA callback that resets the current transformation.

Hook: useFreeTransform()

For more advanced use cases, use the useFreeTransform() hook directly.

1import { useFreeTransform } from '@ky28059/react-free-transform';
2
3export default function Example() {
4    const { register, transform, zoom, reset } = useFreeTransform();
5
6    return (
7        <div>
8            <div
9                // For the controls to work, it's recommended that your container has the following styles:
10                className="flex items-center justify-center overflow-hidden touch-none ..."
11                ref={register}
12            >
13                <img
14                    src="..."
15                    className="..."
16                    style={{ transform }}
17                    draggable={false}
18                />
19            </div>
20
21            <button className="..." onClick={() => zoom(0.1)}>
22                +
23            </button>
24
25            <button className="..." onClick={() => zoom(-0.1)}>
26                -
27            </button>
28
29            <button className="..." onClick={reset}>
30                Reset transformation
31            </button>
32        </div>
33    )
34}

The hook returns an object of

PropTypeValue
register(c: HTMLElement | null) => voidA callback that registers the given HTMLElement as a transform wrapper. When registering a JSX element, you can pass this callback as a ref.
transformstringThe CSS property value of the current transform.
zoom(p: number) => voidA callback that zooms the container by the given scale.
reset() => voidA callback that resets the current transformation.