Skip to content

Style shape library

Keenan Crane edited this page Jan 29, 2023 · 11 revisions

Style currently supports a variety of shapes, listed below. Note that the system is constantly evolving and this page may be out of date. Updated attributes for individual shapes can be found in the individual Shapes.ts files in the /shapes subdirectory. In the attribute lists below, the vec2 type describes a 2D vector u, whose scalar components can be accessed via u[0] and u[1].

Using shapes in Style

In Style, a shape instance is declared inside a rule using a statement of the form

x.myShape = Shape {
   attribute1: value1
   attribute2: value2
   ...
}

For instance, to associate all Substance objects x of type Point with a red circle of radius 5, you would write

forall Point x {
   x.myCircle = Circle {
      radius: 5
      fillColor: rgba(1,0,0,1)
   }
}   

Notice that this definition, the center: attribute of the circle is not set. Undefined parameters like these will be automatically optimized by Penrose.

Keeping shapes on the canvas

All shapes have a property ensureOnCanvas, which by default is set to true. This special constraint ensures that the shape remains within the bounding rectangle of the canvas (which must be declared at the top of each Style file). This constraint can be omitted by setting ensureOnCanvas: false.

SVG Passthrough

In addition to the attribute listed below, any valid SVG attribute can be specified. The values of these attributes will be passed through to the output SVG without any modification by Penrose. Note that kebab-case SVG attributes can be specified by the corresponding camelCase string, e.g., to set the attribute vertical-align to top, write verticalAlign: top.

Circle

Property Type
center vec2
r scalar
strokeWidth scalar
strokeStyle string
strokeColor color
fillColor color

Ellipse

Property Type
center vec2
rx scalar
ry scalar
strokeWidth scalar
strokeStyle string
strokeColor color
fillColor color

Text

A Text shape is used to display plain text; see Equation for mathematical expressions. The Text shape supports many of the same attributes as SVG text. Note that by default, all text is centered vertically and horizontally, via the textAnchor and alignmentBaseline fields (which can be changed to left, bottom, etc.).

The width and height of every Text shape is automatically set to the width/height of its bounding box—you do not have to set these values. In fact, it is often convenient to use these values when defining other shapes. For instance, to draw a Rectangle around an existing Text shape called t, you can set the rectangle's width/height/center fields to width: t.width, height: t.height, and center: t.center. (Note that this rectangle will be properly centered on the text only if the text retains the default values textAnchor: middle and alignmentBaseline: alphabetic; changing these values may cause the two shapes to become misaligned).

Property Type
center vec2
string string (e.g. X.label or "text")
fillColor color
strokeWidth scalar
strokeStyle string
strokeColor color
fontFamily string (e.g., "Palatino")
fontSize string (e.g., "12pt")
fontStyle string (any CSS style string)
fontVariant string (e.g., "italic")
fontWeight string (e.g., "bold")
textAnchor string (e.g., "middle")
textAligmentBaseline string (e.g., "middle")

Equation

An Equation is used to typeset mathematical expressions. It assumes that the string field corresponds to a math mode TeX expression, and uses MathJax to render this string. Note that ordinary (non-math) text can be drawn via the Text shape.

Property Type
center vec2
w scalar
h scalar
string string (e.g. X.label or "text")
fontSize string ("12pt")
fillColor color

Arrow

Property Type
style string
start vec2
end vec2
rotation scalar
thickness scalar
fillColor color
arrowheadStyle string ("arrowhead-1", "arrowhead-2")
arrowheadSize scalar

Polygon

Property Type
points string (e.g., ((1.,2.), (3.,4.), (5.,6))
fillColor color
strokeColor color
strokeAlpha scalar
strokeWidth scalar
strokeDashArray string
strokeStyle string
strokeLineCap string

Path

Property Type
style string
effect string
arrowheadStyle string ("arrowhead-1", "arrowhead-2")
start vec2
end vec2
strokeWidth scalar
thickness scalar
arrowheadSize scalar
fillColor color
d pathdata
leftArrowhead bool
rightArrowhead bool

Defining an SVG path using d

The d attribute should receive information about the particular points you want to draw your path on. Currently, Path can handle SVG commands for lines and arcs. For detailed information about the information that each SVG command expects, check out this resource. In your style program, to render each of the following types of SVG commands, pass d the return value of the following functions:

  • Line or series of connected line segments: pathFromPoints(complete, [[x1, y1], [x2, y2],...,[xn, yn]]) where:
    • complete: "open" to keep the SVG path open, "closed" to draw a line from the last point to the first
    • [[x1, y1], [x2, y2],...,[xn, yn]] is the list of ordered points to make up the SVG path
  • Arc: arc(complete, start, end, radius, rotation, largeArc, arcSweep) (well-illustrated documentation on the purpose of each of the arc attributes in SVG can be found here):
    • complete: "open" to keep the SVG path open, "closed" to draw a line from the last point to the first
    • start: Coordinate [x,y] representing the beginning of the arc
    • end: Coordinate [x,y] representing the endpoint of the arc
    • radius: List of length 2 [rx, ry], where rx is the radius of the ellipse to draw the arc along in the x direction (i.e. the width), and ry is the radius of the ellipse in the y direction.
    • rotation Number representing the degree of rotation of the ellipse
    • largeArc: 0 to draw shorter of 2 arcs, 1 to draw the longer
    • arcSweep: 0 to draw in the counter-clockwise direction from start to end, 1 to draw in the clockwise direction
  • Curve passing through three points: interpolateQuadraticFromPoints(pathType,p0,p1,p2) where:
    • pathType: "open" to keep the SVG path open, "closed" to draw a line from the last point to the first
    • p0: start point
    • p1: middle point — unlike a standard quadratic Bézier curve, which will not pass through the middle control point, this curve will actually pass exactly through this point.
    • p2: end point

Line

Property Type
style string
stroke string
arrowheadStyle string ("arrowhead-1", "arrowhead-2")
start vec2
end vec2
thickness scalar
arrowheadSize scalar
fillColor color
leftArrowhead bool
rightArrowhead bool

Rectangle

Property Type
style string
strokeStyle string
center vec2
w scalar
h scalar
strokeWidth scalar
fillColor color
strokeColor color

Square

Property Type
style string
strokeStyle string
center vec2
side scalar
strokeWidth scalar
strokeColor color
fillColor color

Image

Property Type
style string
stroke string
path string
center vec2
w scalar
h scalar
opacity scalar
rotation scalar
Clone this wiki locally