Skip to content
On this page

Transform

Sometimes it can be useful to apply 2D transformations to one or more components collectively. This is where Transform comes in handy.

Code
vue
<script setup lang="ts">
import { Mafs, Cartesian, Polygon, Circle, Text, Transform, MovablePoint, useMovablePoint, Theme, vec } from 'mafs-vue'
import { computed } from 'vue'

const t = useMovablePoint([-4, -2])
const s = useMovablePoint([8, 4])
const r = useMovablePoint([1, 0], {
    constrain: (p) => vec.normalize(p)
})
const angle = computed(() => Math.atan2(r.point[1], r.point[0]))

</script>
<template>
    <Mafs :height="400" :viewBox="{ x: [-8, 8], y: [-3, 3] }">
        <Cartesian />
        <Transform :translate="t.point">
            <Transform :rotate="angle">
                <Transform :scale="s.point">
                    <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>
                </Transform>
                <MovablePoint :ctx="s" :color="Theme.blue" />
            </Transform>
            <MovablePoint :ctx="r" />
        </Transform>
        <MovablePoint :ctx="t" :color="Theme.green" />
    </Mafs>
</template>

Props

<Transform ... />

NameDescriptionDefault
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.

vue
<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 Vue 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.
  • Coordinates.* cannot be transformed.
  • Function.OfX cannot be transformed.
  • VectorField cannot be transformed.