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
| Name | Description |
|---|---|
reference | The element to go to. |
referenceAnchor | The point of reference to reach. Defaults to 'center'. |
anchor | The 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 cornerTests
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 ofapplySvgTransforms, created bysvgRotateBy,svgRotateTo,svgFlipTo,svgScaleBy,svgTranslateByorsvgPlaceOn: keep it to change its values later withset.
Files it needs
src/svg-transform/svg-place-on.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/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 } 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