Expresso.Element.Diagram.Geometry (expresso v0.1.0)

Copy Markdown View Source

The box and the center of an element of an SVG file

The move_to option of an on entity in a part moves the part to the center of a different element of the file. This module finds the two centers from the tree of the file, with no browser. The render of the deck then writes the distance as --x and --y, as for set: [x: ..., y: ...].

The box of an element is the smallest rectangle that holds its shape, in the coordinates of the svg element of the file. The module reads the transform attribute of the element and of each parent, so an element in a moved group gets the correct box. These shapes have a box:

ElementBox
rect, image, use, foreignObjectx, y, width and height
circlecx, cy and r
ellipsecx, cy, rx and ry
linethe two points
polyline, polygoneach point of points
patheach end point and each control point of d
text, tspanthe point of x and y
g, a, svg, switchthe box of each child

The box of a path holds its control points, so a curve can have a box that is a little larger than its shape. A text has no width without its font, so its box is the point where the text starts. A text with text-anchor: middle thus has the correct horizontal center.

Summary

Types

A box: left, top, right, bottom

An affine transform: x' = a·x + c·y + e, y' = b·x + d·y + f

Functions

Return the box of an element in the coordinates of the file

Return the distance from the center of one element to the center of another

Types

box()

@type box() :: {float(), float(), float(), float()}

A box: left, top, right, bottom

matrix()

@type matrix() :: {float(), float(), float(), float(), float(), float()}

An affine transform: x' = a·x + c·y + e, y' = b·x + d·y + f

Functions

box(arg1, parent)

@spec box(Floki.html_node(), matrix()) :: box() | nil

Return the box of an element in the coordinates of the file

matrix is the matrix of the parent of the element. The function returns nil for an element with no shape.

distance(tree, from, to)

@spec distance(Floki.html_tree(), String.t(), String.t()) ::
  {:ok, {float(), float()}} | {:error, String.t()}

Return the distance from the center of one element to the center of another

tree is the tree of the file from Floki.parse_fragment!/1. The distance is in the coordinates of the parent of the element from, because a part moves in the coordinates of its parent. The function returns an error for an id that the file does not have, and for an element with no shape.

iex> tree = Floki.parse_fragment!(~s{<svg><rect id="a" x="0" y="0" width="10" height="10"/><g transform="translate(100, 20)"><circle id="b" cx="5" cy="5" r="5"/></g></svg>})
iex> Expresso.Element.Diagram.Geometry.distance(tree, "a", "b")
{:ok, {100.0, 20.0}}