folkertdev / one-true-path-experiment / LowLevel.Command

Low-level access to drawing instructions.

This is a low-level module that you probably shouldn't deal with. It is much nicer to use the functions in the Curve module or the SubPath module.

These functions are only meant to build up primitives.

Moving the cursor


type MoveTo
    = MoveTo (( Basics.Float, Basics.Float ))

Constructors for MoveTo instructions

moveTo : ( Basics.Float, Basics.Float ) -> MoveTo

Move to a position on the canvas without drawing. The M instruction.

Drawing on the canvas

Type


type DrawTo
    = LineTo (List ( Basics.Float, Basics.Float ))
    | CurveTo (List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ))
    | QuadraticBezierCurveTo (List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ))
    | EllipticalArc (List EllipticalArcArgument)
    | ClosePath

Constructors for DrawTo instructions

You may miss some constructs in comparison to SVG. Only absolute coordinates are supported, and the smooth curve variants are removed. These choices were made to keep the number of constructors small.

Relative coordinates can always be transformed to abslute ones.

horizontal and vertical movements can be written as LineTo commands, smooth (also known as short-hand) curve extensions can be achieved with Curve.smoothQuadraticBezier and Curve.smoothCubicBezier.

The SubPath.parser will do these transformations automatically.

Straight lines

lineTo : List ( Basics.Float, Basics.Float ) -> DrawTo

Draw a series of line segments to absolute positions. The L instruction.

Close Path

closePath : DrawTo

Draw a straight line from the cursor position to the starting position of the path. The Z instruction.

Beziers

quadraticCurveTo : List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> DrawTo

A quadratic bezier. The Q instruction.

cubicCurveTo : List ( ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ), ( Basics.Float, Basics.Float ) ) -> DrawTo

A cubic bezier. The C instruction.

Arcs

arcTo : List EllipticalArcArgument -> DrawTo

An elliptical arc. The A instruction.


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

The arguments for an Arc

argument : EllipticalArcArgument
argument =
    { start = ( 0, 42 )
    , end = ( 42, 0 )
    , radii = ( 1, 1 )
    , xAxisRotate = 90
    , arcFlag = largestArc
    , direction = clockwise
    }

The xAxisRotate parameter is in degrees (note that in the Segment module, it is in radians).

clockwise : Direction

Corresponds to a sweep flag of 0

Note: this is clockwise in the "normal" coordinate system with positive y pointing up and positive x pointing right

counterClockwise : Direction

Corresponds to a sweep flag of 1

Note: this is counter-clockwise in the "normal" coordinate system with positive y pointing up and positive x pointing right

largestArc : ArcFlag

Corresponds to an arc flag of 1

smallestArc : ArcFlag

Corresponds to an arc flag of 0


type alias ArcFlag =
Path.LowLevel.ArcFlag

Determine which arc to draw


type alias Direction =
Path.LowLevel.Direction

Determine which arc to draw

Threading State


type alias CursorState =
{ start : ( Basics.Float
, Basics.Float )
, cursor : ( Basics.Float
, Basics.Float )
, previousControlPoint : Maybe ( Basics.Float
, Basics.Float ) 
}

updateCursorState : DrawTo -> CursorState -> CursorState

Simulate the effect of a drawto command on the cursor position

state : CursorState
state =
    { start = (0,0)
    , cursor = (10, 10)
    , previousControlPoint = Nothing
    }

updateCursorState (lineTo [(20, 10)]) state
    --> { start = (0,0), cursor = (20,10), previousControlPoint = Nothing }

updateCursorState (quadraticCurveTo [(( 15, 20), (20, 10))]) state
    --> { start = (0,0), cursor = (20,10), previousControlPoint = Just (15, 20) }

Conversion

merge : DrawTo -> DrawTo -> Result ( DrawTo, DrawTo ) DrawTo

Merge adjacent commands if possible

merge (lineTo [ ( 0, 0 ) ]) (lineTo [ ( 10, 10 ) ]) --> Ok (lineTo [ (0,0) , (10, 10) ])

merge (lineTo [ ( 0, 0 ) ]) closePath --> Err (lineTo [ (0,0) ], closePath)

fromLowLevelMoveTo : Path.LowLevel.MoveTo -> CursorState -> ( CursorState, MoveTo )

fromLowLevelDrawTos : List Path.LowLevel.DrawTo -> CursorState -> ( CursorState, List DrawTo )

fromLowLevelDrawTo : Path.LowLevel.DrawTo -> CursorState -> Maybe ( DrawTo, CursorState )

toLowLevelDrawTo : DrawTo -> Path.LowLevel.DrawTo

Convert a one-true-path drawto to a svg-path-lowlevel drawto. Used in conversion to string

toLowLevelMoveTo : MoveTo -> Path.LowLevel.MoveTo

Convert a one-true-path moveto to a svg-path-lowlevel moveto. Used in conversion to string

mapCoordinateDrawTo : (( Basics.Float, Basics.Float ) -> ( Basics.Float, Basics.Float )) -> DrawTo -> DrawTo

Transform the coordinates in a drawto

scaleMoveTo : ( Basics.Float, Basics.Float ) -> MoveTo -> MoveTo

scale a moveto

scaleDrawTo : { origin : ( Basics.Float, Basics.Float ), scaleX : Basics.Float, scaleY : Basics.Float } -> DrawTo -> DrawTo

scale a drawto