svgFlipTo function
An order of applySvgTransforms that makes the element mirrored or not, as seen on screen, around one of its anchors: svgFlipTo(false) makes a mirrored text readable again.
ts
import { svgFlipTo } from 'utils';Signature
ts
export function svgFlipTo(
isFlipped = true,
axis: 'horizontal' | 'vertical' = 'horizontal',
anchor: Anchor = 'center',
): SvgTransformOrder<[isFlipped?: boolean, axis?: 'horizontal' | 'vertical', anchor?: Anchor]>Parameters
| Name | Description |
|---|---|
isFlipped | Whether the element must look mirrored. Defaults to true. |
axis | The mirror used when the state changes: 'horizontal' swaps left and right, 'vertical' top and bottom. Defaults to 'horizontal'. |
anchor | The point of the element that stays in place. Defaults to 'center'. |
Returns
The order, to change with set(isFlipped, axis, anchor).
Example
ts
const flip = svgFlipTo(false);
applySvgTransforms(valve, [flip]);
flip.set(true); // facing the other way, same placeTests
Line coverage: 100 %.
- ✅ mirrors horizontally around the center by default
- ✅ mirrors vertically around an anchor
- ✅ makes the element mirrored: true, from scale(-1 1) translate(-40 0)
- ✅ makes the element mirrored: false, from translate(0 0)
- ✅ makes the element mirrored: false, from scale(-1 1) translate(-40 0)
Source
src/svg-transform/svg-flip-to.ts (on GitHub)
Uses
Anchor: One of the 9 points of a box: its corners, the middles of its sides, its center.getSvgAnchorPoint: Finds an anchor of the box an SVG element takes on screen: a corner, the middle of a side or the center.SvgTransformOrder: An order ofapplySvgTransforms, created bysvgRotateBy,svgRotateTo,svgFlipTo,svgScaleBy,svgTranslateByorsvgPlaceOn: keep it to change its values later withset.
Files it needs
src/svg-transform/svg-flip-to.ts imports, directly or not:
src/svg-transform/anchor.tssrc/svg-transform/get-svg-anchor-point.tssrc/svg-transform/internal/create-matrix.tssrc/svg-transform/internal/create-order.tssrc/svg-transform/internal/get-anchor-point.tssrc/svg-transform/internal/get-owner-svg.tssrc/svg-transform/internal/is-mirrored.tssrc/svg-transform/internal/order-states.tssrc/svg-transform/svg-transform-order.ts
Source code
ts
import type { Anchor } from './anchor';
import { getSvgAnchorPoint } from './get-svg-anchor-point';
import { createMatrix, createOrder, isMirrored } from './internal';
import type { SvgTransformOrder } from './svg-transform-order';
/**
* An order of `applySvgTransforms` that makes the element mirrored or not, as seen on screen, around one of
* its anchors: `svgFlipTo(false)` makes a mirrored text readable again.
*
* @param isFlipped - Whether the element must look mirrored. Defaults to `true`.
* @param axis - The mirror used when the state changes: `'horizontal'` swaps left and right, `'vertical'` top
* and bottom. Defaults to `'horizontal'`.
* @param anchor - The point of the element that stays in place. Defaults to `'center'`.
* @returns The order, to change with `set(isFlipped, axis, anchor)`.
* @example
* const flip = svgFlipTo(false);
* applySvgTransforms(valve, [flip]);
* flip.set(true); // facing the other way, same place
*/
export function svgFlipTo(
isFlipped = true,
axis: 'horizontal' | 'vertical' = 'horizontal',
anchor: Anchor = 'center',
): SvgTransformOrder<[isFlipped?: boolean, axis?: 'horizontal' | 'vertical', anchor?: Anchor]> {
return createOrder(
[isFlipped, axis, anchor],
(element, screen, flipped = true, mirror = 'horizontal', point = 'center') => {
if (isMirrored(screen) === flipped) {
return createMatrix(element);
}
const { x, y } = getSvgAnchorPoint(element, point);
return createMatrix(element, mirror === 'horizontal' ? [-1, 0, 0, 1, 2 * x, 0] : [1, 0, 0, -1, 0, 2 * y]);
},
);
}Test file
ts
import { applySvgTransforms } from './apply-svg-transforms';
import { svgFlipTo } from './svg-flip-to';
import { describeOnScreen, renderSvg } from './testing';
describe(svgFlipTo, () => {
it('mirrors horizontally around the center by default', () => {
const byId = renderSvg(
'<g transform="rotate(30 50 50)"><rect id="valve" x="40" y="45" width="20" height="10" /></g>',
);
const before = describeOnScreen(byId('valve'));
applySvgTransforms(byId('valve'), [svgFlipTo()]);
expect(describeOnScreen(byId('valve'))).toMatchObject({ x: before.x, y: before.y, isFlipped: true });
});
it('mirrors vertically around an anchor', () => {
const byId = renderSvg('<rect id="valve" x="10" y="10" width="20" height="10" />');
applySvgTransforms(byId('valve'), [svgFlipTo(true, 'vertical', 'top')]);
expect(describeOnScreen(byId('valve'))).toMatchObject({ x: 10, y: 0, isFlipped: true });
});
it.for([
[true, 'scale(-1 1) translate(-40 0)', true],
[false, 'translate(0 0)', false],
[false, 'scale(-1 1) translate(-40 0)', false],
] as const)('makes the element mirrored: %s, from %s', ([isFlipped, transform, expected]) => {
const byId = renderSvg(`<rect id="label" transform="${transform}" x="10" y="10" width="20" height="10" />`);
applySvgTransforms(byId('label'), [svgFlipTo(isFlipped)]);
expect(describeOnScreen(byId('label'))).toMatchObject({ x: 10, y: 10, isFlipped: expected });
});
});Keywords: svg, flip, to, svg transforms, function