Skip to content
Eric Yancey Dauenhauer edited this page Feb 2, 2024 · 3 revisions

This is a (hopefully) exhaustive list of the components available in SalamiVG.

Note

Some SalamiVG documentation refers to "Tags" as "Components". If one were to nitpick, a "Component" would probably refer to the class (e.g. Rectangle) whereas the "Tag" would refer to the SVG tag (e.g. <rect>), but we are not perfect and use the two terms interchangeably.

Core concepts

Tags are the heart of SVGs, so they is also the heart of this library. Tags always have a render() method which always returns a string representation of the tag. Strings are the primary intended output of the library: the actual visual rendering must happen in a program that can render SVGs such as a browser.

Style inheritance

Tags can have child tags. For example, the root <svg> tag will have child tags to define the shapes in the SVG. When child tags are added, there are a few special attributes that get inherited automatically:

  • fill
  • stroke
  • stroke-width

This allows for some simplified patterns to declare visual styles for multiple elements, e.g.

svg.fill = '#45abf8'
svg.circle(c) // automatically gets `fill="#45abf8"` attribute added

Numeric precision

Floats are a pain sometimes. If you don't need 20 decimals of precision on your SVG attributes, you can set the svg.numericPrecision property to some lower value such as 3. This will result in automatically clipping decimal values to this level of precision. For example:

import { svg } from '@salamivg/core'

svg({}, it => {
  it.rect({ x: Math.PI, y: Math.PI, width: Math.LN2, height: Math.LN2 })
}).render()

Renders:

<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
  <rect x="3.141592653589793" y="3.141592653589793" width="0.6931471805599453" height="0.6931471805599453"></rect>
</svg>

Compared to

import { svg } from '@salamivg/core'

svg({}, it => {
  it.numericPrecision = 3 // sets precision to 3 decimal places
  it.rect({ x: Math.PI, y: Math.PI, width: Math.LN2, height: Math.LN2 })
}).render()

Which renders:

<svg viewBox="0 0 100 100" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100" height="100">
  <rect x="3.142" y="3.142" width="0.693" height="0.693"></rect>
</svg>

Tag

Tag is the base class that all other components extend. You probably will never need to instantiate a Tag yourself, but it is available if there's a tag you need and it isn't included in SalamiVG.

Constructor

new Tag(tagName: string, attributes: Record<string, unknown> = {})

Useful Methods

  • set fill(value: 'none' | string | null | ColorRgb | ColorHsl | LinearGradient): Sets the fill color for the tag, and all of it's children, unless explicitly declared.
  • set stroke(value: 'none' | string | null | ColorRgb | ColorHsl | LinearGradient): Sets the stroke color for the tag, and all of it's children, unless explicitly declared.
  • set strokeWidth(value: number): Sets the stroke width for the tag, and all of it's children, unless explicitly declared.
  • setAttributes(attributes = {}): Set arbitrary attributes on the tag. These will all be rendered as attributes when render() is called.
  • addChild(child: Tag): Adds a child tag. The child can be any instance of a Tag subclass.
  • render(): string: Render the tag to a string representation.

Circle

Constructor

Like most tags, you can pass any additional attributes to the constructor to be added to the tag's attributes.

new Circle({ x: number, y: number, radius: number, ...attributes })
new Circle({ center: Vector2, radius: number, ...attributes })

Useful Properties

  • center: Vector2
  • x: number (corresponds to the SVG cx attribute)
  • y: number (corresponds to the SVG cy attribute)
  • radius: number (corresponds to the SVG r attribute)

Useful Methods

  • contains(point: Vector2): boolean: Returns true when the circle contains the point
  • intersectsCircle(other: Circle, padding = 0): boolean: Returns true when the circle intersects the other circle. If padding is greater than 0, returns true when the circle is closer than padding.
  • bitangents(other: Circle): [Vector2, Vector2, number, 'inner' | 'outer'][]: Returns a list of bitangents with the other circle. Includes both inner and outer bitangents
  • outerBitangents(other: Circle): [Vector2, Vector2, number, 'outer'][]: Returns the two outer bitangents with the other circle.
  • innerBitangents(other: Circle): [Vector2, Vector2, number, 'inner'][]: Returns the two inner bitangents with the other circle.

Defs

This should probably never be used directly. Just a shortcut to create a <defs> tag

Constructor

new Defs()

Useful Methods

  • addDefinition(child: Tag): Alias of addChild

Hexagon

Constructor

new Hexagon({ center: Vector2, circumradius?: number, apothem?: number, rotation?: number = 0, ...attributes })

Useful Methods

  • neighbors(): Hexagon[]: Returns the six hexagons that neighbor the hexagon in a packed hexagonal grid.

LineSegment

Constructor

new LineSegment(start: Vector2, end: Vector2)

This class extends Polyline. Please see Polyline for more details.

LinearGradient

You probably don't want to instantiate this directly. Try using svg.defineLinearGradient() instead

Constructor

new LinearGradient({
  stops?: ColorStop[],
  colors?: Array<ColorRgb | ColorHsl | string>,
  start?: Vector2 = new Vector2(0, 0),
  end?: Vector2 = new Vector2(0, 1),
  id?: string,
  numericPrecision?: number = Infinity
})

Path

SVG Paths can do anything, so this is a pretty useful tag to know.

Constructor

new Path(attributes = {})

The better way to build a path rather than the constructor is with the builder method:

path(p => {
  // move the path, add lines, add curves, set properties, etc
})

Or with the static fromPoints method, which instantiates a Path from a list of points:

Path.fromPoints(points: Vector2[])

Useful Properties

  • cursor: Vector2: A mutable property which represents the current endpoint of the path. Very useful to calculate the "next point" if the path is "moving".

Useful Methods

Note: the coordinateType argument can either be absolute or relative. Consult MDN if you aren't sure which one to use. absolute is probably easier most of the time.

  • moveTo(point: Vector2, coordinateType = 'absolute'): Adds a "move" command to the path
  • lineTo(point: Vector2, coordinateType = 'absolute'): Adds a "line" command to the path
  • cubicBezier(controlPoint1: Vector2, controlPoint2: Vector2, endPoint: Vector2, coordinateType = 'absolute'): Adds a "cubic bezier" command to the path
  • smoothBezier(controlPoint: Vector2, endPoint: Vector2, coordinateType = 'absolute'): Adds a "smooth bezier" command to the path. Consult MDN for details, this one is hard to use appropriately.
  • quadraticBezier(controlPoint: Vector2, endPoint: Vector2, coordinateType = 'absolute'): Adds a "quadratic bezier" command to the path.
  • smoothQuadraticBezier(controlPoint: Vector2, endPoint: Vector2, coordinateType = 'absolute'): Adds a "smooth quadractic bezier" command to the path. Intended to be used in conjunction with quadracticBezier
  • arc({ rx: number, ry: number, xAxisRotation = 0, largeArcFlag = false, sweepFlag = false, end: Vector2 }, coordinateType = 'absolute'): Adds an "arc" command to the path. Note that most of the args are defaulted, so the only required args are rx, ry, and end

Polygon

Constructor

new Polygon({ points: Vector2[], ...attributes })

Useful Properties

  • boundingBox: Rectangle: A rectangle which represents the bounding box around the polygon

Useful Methods

  • contains(point: Vector2): boolean: Returns true when the polygon contains the point.

Polyline

Constructor

new Polygon({ points: Vector2[], ...attributes })

More useful is the builder:

polyline(line => {
  line.push(point)
  console.log(line.cursor)
})

Useful Properties

  • cursor: Vector2: A mutable property which represents the current endpoint of the path. Very useful to calculate the "next point" if the path is "moving".
  • boundingBox: Rectangle: A rectangle which represents the bounding box around the polyline

Useful Methods

  • push(point: Vector2): Adds a point to the path, and updates the cursor property
  • empty(): boolean: Returns true when the polyline has no points

Rectangle

Constructor

new Rectangle({ x: number, y: number, width: number, height: number, borderRadius?: number = 0, ...attributes })

Note

borderRadius is recommended instead of rx, but you can still pass rx (and even ry!) if you prefer.

Or with the static fromCenter method, if the center of the Rectangle is known.

Rectangle.fromCenter(center: Vector2, width: number, height: number)

Useful Properties

  • x: number
  • y: number
  • width: number
  • height: number
  • center: Vector2
  • corner: Vector2: The upper left corner of the rectangle. Equivalent to new Vector2(rectangle.x, rectangle.y)

Useful Methods

  • vertices(): Vector2[]: Returns the 4 vertices of the rectangle
  • sides(): LineSegment[]: Returns LineSegments representing the 4 sides of the rectangle
  • empty(): boolean: Returns true when the rectangle's area is 0

Svg

Constructor

new Svg({ width = 100, height = 100, scale = 1, ...attributes })

Recommended: use the renderSvg method

renderSvg({}, svg => {
  svg.fill = '#000'
})

Useful properties

  • center: Vector2
  • filenameMetadata: Record<string, unknown>: Useful for setting data that can be written to the filename when using the renderSvg loop

Useful Methods

  • contains(point: Vector2): boolean: Returns true when the point is inside the viewBox of the Svg
  • defineLinearGradient(attributes: LinearGradientAttributes): LinearGradient: Defines a LinearGradient, and adds the appropriate <defs> child to the Svg. Returns a LinearGradient instance which can be passed to fill and stroke of this or other tags.
  • setBackground(color: string | ColorRgb | ColorHsl): Adds a "background" rectangle with the specified fill color
  • path(path: Path | PathBuilder): Adds a Path to the Svg children.
  • lineSegment(lineSegment: LineSegment): Adds a LineSegment to the Svg children
  • circle(circle: Circle | CircleBuilder): Adds a Circle to the Svg children
  • rect(rect: Rectangle | RectangleBuilder): Adds a Rectangle to the Svg children
  • polygon(poly: Polygon): Adds a Polygon to the Svg children
  • polyline(line: Polyline | PolylineBuilder): Adds a Polyline to the Svg children