Skip to content

svgPlaceOn function ​

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.

ts
import { svgPlaceOn } from 'utils';

Signature ​

ts
export function svgPlaceOn(
  reference: SVGGraphicsElement,
  referenceAnchor: Anchor = 'center',
  anchor: Anchor = 'center',
): SvgTransformOrder<[reference: SVGGraphicsElement, referenceAnchor?: Anchor, anchor?: Anchor]>

Parameters ​

NameDescription
referenceThe element to go to.
referenceAnchorThe point of reference to reach. Defaults to 'center'.
anchorThe point of the element that lands on it. Defaults to 'center'.

Returns ​

The order, to change with set(reference, referenceAnchor, anchor).

Example ​

ts
applySvgTransforms(badge, [svgPlaceOn(symbol, 'bottom-left', 'top-right')]); // the badge corner on the symbol corner

Tests ​

Line coverage: 100 %.

  • ✅ puts an anchor on an anchor of an element of another group
  • ✅ centers on the center by default

Source ​

src/svg-transform/svg-place-on.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 of applySvgTransforms, created by svgRotateBy, svgRotateTo, svgFlipTo, svgScaleBy, svgTranslateBy or svgPlaceOn: keep it to change its values later with set.

Files it needs ​

src/svg-transform/svg-place-on.ts imports, directly or not:

Source code
ts
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);
    },
  );
}
Test file
ts
import { applySvgTransforms } from './apply-svg-transforms';
import { getSvgAnchorPoint } from './get-svg-anchor-point';
import { svgPlaceOn } from './svg-place-on';
import { renderSvg } from './testing';

describe(svgPlaceOn, () => {
  it('puts an anchor on an anchor of an element of another group', () => {
    const byId = renderSvg(`
      <g transform="translate(200 100) rotate(30) scale(1.5)"><rect id="badge" width="10" height="6" /></g>
      <g transform="translate(50 60)"><rect id="symbol" width="40" height="20" /></g>
    `);
    applySvgTransforms(byId('badge'), [svgPlaceOn(byId('symbol'), 'bottom-left', 'top-right')]);
    const badge = getSvgAnchorPoint(byId('badge'), 'top-right');
    expect(badge.x).toBeCloseTo(50, 3);
    expect(badge.y).toBeCloseTo(80, 3);
  });

  it('centers on the center by default', () => {
    const byId = renderSvg(
      '<rect id="label" width="10" height="10" /><rect id="zone" x="100" y="100" width="50" height="50" />',
    );
    applySvgTransforms(byId('label'), [svgPlaceOn(byId('zone'))]);
    expect(getSvgAnchorPoint(byId('label'))).toMatchObject({ x: 125, y: 125 });
  });
});

Keywords: svg, place, on, svg transforms, function

Generated from the JSDoc of the sources.