Skip to content

Shapes ​

Every element of a group draws the same shape, centered on the element and filling its width and height. A part has exactly one shape. To mix shapes, use parts.

ShapeFields (default)Draws
circlestartAngle (-π/2), sweep (2π)a filled ellipse, or a slice of it
rectcornerRadius (0)a filled rectangle
ringstrokeWidth, startAngle (-π/2), sweep (2π), segments (1)a stroked circle, or arcs of it
trianglenonea filled triangle pointing up
linenonea bar with fully rounded ends

Angles are in radians. -π/2 (about -1.5708) is the top, 0 is the right, and arcs go clockwise.

circle ​

A filled ellipse inscribed in the element. In a square element it is a circle.

With sweep below 2π, only part of the disc is drawn: the area between the arc (from startAngle to startAngle + sweep) and the straight line that joins its ends. With sweep = π it is a half disc. With 3π/2 it is a disc with one side cut off by the chord.

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeCircleArc",
  "duration": 0.8,
  "layout": { "type": "single", "size": 0.8 },
  "shape": { "type": "circle", "startAngle": 0, "sweep": 4.71238898 },
  "tracks": [
    { "property": "rotate", "keyTimes": [0, 1], "values": [0, 6.283185307] }
  ]
}
null

rect ​

A filled rectangle. cornerRadius is a fraction of the shorter side of the element, from 0 (square corners) to 0.5 (fully round ends).

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeRect",
  "duration": 1.6,
  "layout": { "type": "single", "size": 0.55 },
  "shape": { "type": "rect", "cornerRadius": 0.25 },
  "tracks": [
    { "property": "rotate", "keyTimes": [0, 0.5, 1], "values": [0, 1.570796327, 3.141592654], "easing": "easeInOut" },
    { "property": "scale", "keyTimes": [0, 0.25, 0.5, 0.75, 1], "values": [1, 0.7, 1, 0.7, 1], "easing": "easeInOut" }
  ]
}
null

ring ​

A stroked circle. strokeWidth is a fraction of the shorter side of the element. The outer edge of the stroke touches the element, so the ring never grows outside it. Stroke ends are flat.

sweep draws only an arc of the circle:

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeRing",
  "duration": 0.75,
  "layout": { "type": "single", "size": 0.9 },
  "shape": { "type": "ring", "strokeWidth": 0.1, "sweep": 4.71238898 },
  "tracks": [
    { "property": "rotate", "keyTimes": [0, 1], "values": [0, 6.283185307] }
  ]
}
null

Segments ​

segments splits the ring into that many arcs, evenly spaced. Each arc starts at startAngle + k × 2π / segments and covers sweep.

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeRingSegments",
  "duration": 1.4,
  "layout": { "type": "single", "size": 0.9 },
  "shape": { "type": "ring", "strokeWidth": 0.12, "segments": 3, "sweep": 1.5 },
  "tracks": [
    { "property": "rotate", "keyTimes": [0, 1], "values": [0, 6.283185307] },
    { "property": "strokeEnd", "keyTimes": [0, 0.5, 1], "values": [0.2, 1, 0.2], "easing": "easeInOut" }
  ]
}
ShapeRingSegmentsOpen in playground
null

Trimming with strokeStart and strokeEnd ​

A ring has two extra properties that tracks can animate: strokeStart (rest value 0) and strokeEnd (rest value 1). They trim every arc, as fractions of the arc, like strokeStart and strokeEnd in Core Animation. Nothing is drawn when strokeEnd is at or below strokeStart.

Here the end grows from 0 to 1 in the first half of the cycle, then the start catches up in the second half:

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeRingTrim",
  "duration": 1.5,
  "layout": { "type": "single", "size": 0.9 },
  "shape": { "type": "ring", "strokeWidth": 0.1 },
  "tracks": [
    { "property": "strokeStart", "keyTimes": [0, 0.5, 1], "values": [0, 0, 1], "easing": "easeInOut" },
    { "property": "strokeEnd", "keyTimes": [0, 0.5, 1], "values": [0, 1, 1], "easing": "easeInOut" },
    { "property": "rotate", "keyTimes": [0, 1], "values": [0, 3.141592654] }
  ]
}
null

Ring only

strokeStart and strokeEnd tracks and rest values need a ring shape. validate() reports them on any other shape.

A disc that opens like a mouth

A ring whose strokeWidth is 0.5 is a full disc. Trimming it opens a slice. The built-in Pacman indicator works this way.

triangle ​

A filled isosceles triangle: top center, bottom right, bottom left.

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeTriangle",
  "duration": 1.5,
  "layout": { "type": "single", "size": 0.7 },
  "shape": { "type": "triangle" },
  "tracks": [
    { "property": "rotate", "keyTimes": [0, 1], "values": [0, 2.094395102], "easing": "easeInOut" }
  ]
}
null

line ​

A filled rectangle with a corner radius of half its shorter side: a bar with round ends. Use it in a row for equalizer bars, or in an oriented ring for a spinner.

json
{
  "$schema": "https://maitrungduc1410.github.io/loader-kit/schema/v1.json",
  "schemaVersion": 1,
  "name": "ShapeLine",
  "duration": 0.9,
  "layout": { "type": "row", "count": 4, "gap": 0.12, "itemHeight": 0.8 },
  "shape": { "type": "line" },
  "stagger": [0, 0.3, 0.15, 0.45],
  "tracks": [
    { "property": "scaleY", "keyTimes": [0, 0.5, 1], "values": [0.3, 1, 0.3], "easing": "easeInOut" }
  ]
}
null

Exact rules ​

The specification defines each shape precisely, including how arcs of an ellipse are measured.

Released under the MIT License.