Transform
Sometimes it can be useful to apply 2D transformations to one or more components collectively. This is where Transform
comes in handy.
import { Mafs, CartesianCoordinates, Transform, useMovablePoint, Theme, Text, Polygon, Circle, vec } from "mafs"
function SimpleTransformExample() {
const t = useMovablePoint([-4, -2])
const s = useMovablePoint([8, 4], { color: Theme.blue })
const r = useMovablePoint([1, 0], {
color: Theme.green,
constrain: (p) => vec.normalize(p),
})
const angle = Math.atan2(r.point[1], r.point[0])
return (
<Mafs viewBox={{ x: [-8, 8], y: [-3, 3] }}>
<CartesianCoordinates />
<Transform translate={t.point}>
<Transform rotate={angle}>
<Transform scale={s.point}>
<HelloBox />
</Transform>
{s.element}
</Transform>
{r.element}
</Transform>
{t.element}
</Mafs>
)
}
function HelloBox() {
return (
<>
<Polygon points={[[0, 0], [1, 0], [1, 1], [0, 1]]} />
<Circle center={[0.5, 0.5]} radius={0.5} />
<Text x={0.5} y={0.5}>
Hello world!
</Text>
</>
)
}
Props
<Transform ... />
Name | Description | Default |
---|---|---|
matrix | Matrix | β |
translate | Vector2 | β |
scale | number | Vector2 | β |
rotate | number | β |
shear | Vector2 | β |
Transformation types
Transform
supports many transformation convenience props, but they all boil down to matrix multiplication.
You can pass your own matrix via the matrix
prop and it will be combined with any other transformations you define. Use vec.matrixBuilder()
to construct such a matrix if needed.
Nesting
Nesting is supported. Transformations will be applied inside out, so the innermost Transform
will be applied first.
<Transform translate={[10, 10]}>
<Transform rotate={Math.PI / 2}>
{/* Things in here will be rotated, _then_ translated */}
</Transform>
</Transform>
Prop order matters
Though it's not typical for prop order in React to be significant, it is for Transform
. Transformations will be applied in the order the props are set on the component, with the exception of matrix
which always comes first.
Exceptions
Not all elements support Transform
. This may change in the future.
- Text nodes have their anchor points transformed, but not the text itself.
CartesianCoordinates
cannot be transformed.Function.OfX
cannot be transformed.VectorField
cannot be transformed.