All files / svg-transform svg-flip-to.ts

100% Statements 5/5
100% Branches 10/10
100% Functions 2/2
100% Lines 5/5

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36                                                7x     7x 2x   5x 5x        
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]);
    },
  );
}