All files / svg-transform svg-scale-by.ts

100% Statements 3/3
100% Branches 4/4
100% Functions 2/2
100% Lines 3/3

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                                            4x 4x 4x      
import type { Anchor } from './anchor';
import { createMatrix, createOrder, getAnchorPoint, inOwnAxes } from './internal';
import type { SvgTransformOrder } from './svg-transform-order';
 
/**
 * An order of `applySvgTransforms` that enlarges or shrinks the element in its own axes, around an anchor of
 * its drawing, which gives the direction: with `'left'`, it grows to the right; with `'bottom'`, upwards.
 *
 * @param scaleX - The factor along its width: `2` doubles it.
 * @param scaleY - The factor along its height. Defaults to `scaleX`.
 * @param anchor - The point of its drawing that stays in place. Defaults to `'center'`.
 * @returns The order, to change with `set(scaleX, scaleY, anchor)`.
 * @example
 * const level = svgScaleBy(1, 0, 'bottom');
 * applySvgTransforms(tankLevel, [level]);
 * level.set(1, 0.75, 'bottom'); // filled to 75 %, from the bottom
 */
export function svgScaleBy(
  scaleX: number,
  scaleY = scaleX,
  anchor: Anchor = 'center',
): SvgTransformOrder<[scaleX: number, scaleY?: number, anchor?: Anchor]> {
  return createOrder([scaleX, scaleY, anchor], (element, screen, sx, sy = sx, point = 'center') => {
    const { x, y } = getAnchorPoint(element.getBBox(), point);
    return inOwnAxes(screen, createMatrix(element, [sx, 0, 0, sy, x * (1 - sx), y * (1 - sy)]));
  });
}