All files / svg-transform svg-place-on.ts

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

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                                          4x     4x 4x 4x        
import type { Anchor } from './anchor';
import { getSvgAnchorPoint } from './get-svg-anchor-point';
import { createMatrix, createOrder } from './internal';
import type { SvgTransformOrder } from './svg-transform-order';
 
/**
 * An order of `applySvgTransforms` that moves the element so that one of its anchors lands on an anchor of
 * another element, as seen on screen, whatever groups each one is in.
 *
 * @param reference - The element to go to.
 * @param referenceAnchor - The point of `reference` to reach. Defaults to `'center'`.
 * @param anchor - The point of the element that lands on it. Defaults to `'center'`.
 * @returns The order, to change with `set(reference, referenceAnchor, anchor)`.
 * @example
 * applySvgTransforms(badge, [svgPlaceOn(symbol, 'bottom-left', 'top-right')]); // the badge corner on the symbol corner
 */
export function svgPlaceOn(
  reference: SVGGraphicsElement,
  referenceAnchor: Anchor = 'center',
  anchor: Anchor = 'center',
): SvgTransformOrder<[reference: SVGGraphicsElement, referenceAnchor?: Anchor, anchor?: Anchor]> {
  return createOrder(
    [reference, referenceAnchor, anchor],
    (element, _screen, other, otherPoint = 'center', point = 'center') => {
      const to = getSvgAnchorPoint(other, otherPoint);
      const from = getSvgAnchorPoint(element, point);
      return createMatrix(element).translate(to.x - from.x, to.y - from.y);
    },
  );
}