folkertdev / svg-path-lowlevel / Path.LowLevel

A low-level package for working with svg path strings

This package has two use cases

It is meant as a foundation: there is little type safety and convenience. It's just a literal translation of the SVG spec into elm data types.

toString : List SubPath -> String

Convert a list of subpaths to svg path syntax

myPath : List SubPath
myPath =
    [ { moveto = MoveTo Relative ( 10, 20 )
      , drawtos =
            [ EllipticalArc Absolute
                [ { radii = ( 25, 25 )
                , xAxisRotate = -30
                , arcFlag = SmallestArc
                , direction = CounterClockwise
                , target = ( 50, -25 )
                }
                ]
            ]
      }
    ]

Path.LowLevel.toString myPath
    --> "m10,20 A25,25 -30 0 1 50,-25"

toStringWith : List Option -> List SubPath -> String

Convert a list of subpaths to a string, with some extra formatting options


type Option

Formatting options

decimalPlaces : Basics.Int -> Option

Set the maximum number of decimal places in the output string

myPath : List SubPath
myPath =
    [ { moveto = MoveTo Relative ( 10, 20 )
      , drawtos =
          [ LineTo Absolute
            [ ( 1 / 3, 1 / 3 )
            , ( 1 / 7, 1 / 7 )
            ]
          ]
      }
    ]

toStringWith [] myPath
    --> "m10,20 L0.3333333333333333,0.3333333333333333 0.14285714285714285,0.14285714285714285"

toStringWith [ decimalPlaces 3 ] myPath
    --> "m10,20 L0.333,0.333 0.143,0.143"


type alias SubPath =
{ moveto : MoveTo
, drawtos : List DrawTo 
}

A subpath is a MoveTo followed by a list of DrawTos


type Mode
    = Relative
    | Absolute

The mode of an instruction


type MoveTo
    = MoveTo Mode Coordinate

MoveTo instructions move the cursor, but don't draw anything.


type DrawTo
    = LineTo Mode (List Coordinate)
    | Horizontal Mode (List Basics.Float)
    | Vertical Mode (List Basics.Float)
    | CurveTo Mode (List ( Coordinate, Coordinate, Coordinate ))
    | SmoothCurveTo Mode (List ( Coordinate, Coordinate ))
    | QuadraticBezierCurveTo Mode (List ( Coordinate, Coordinate ))
    | SmoothQuadraticBezierCurveTo Mode (List Coordinate)
    | EllipticalArc Mode (List EllipticalArcArgument)
    | ClosePath

Constructors for DrawTo instructions


type alias Coordinate =
( Basics.Float, Basics.Float )

Represent a point in 2D space with a tuple of floats


type ArcFlag
    = SmallestArc
    | LargestArc

Determine which arc to draw


type Direction
    = Clockwise
    | CounterClockwise

Determine which arc to draw


type alias EllipticalArcArgument =
{ radii : ( Basics.Float
, Basics.Float )
, xAxisRotate : Basics.Float
, arcFlag : ArcFlag
, direction : Direction
, target : Coordinate 
}

The arguments for an Arc

encodeFlags : ( ArcFlag, Direction ) -> ( Basics.Int, Basics.Int )

Turn the flags into numbers

case arcFlag of
    LargestArc -> 1
    SmallestArc -> 0

case direction of
    Clockwise -> 0
    CounterClockwise -> 1

decodeFlags : ( Basics.Int, Basics.Int ) -> Maybe ( ArcFlag, Direction )

Try to decode two ints into flag values. Inverse of encodeFlags.