joakin/elm-canvas/1.0.1

NOTE: this package is not compatible with Elm 0.19.1

Canvas

This library exposes a low level API that mirrors most of the DOM canvas API.

To use it, remember to include the elm-canvas custom element script in your page before you initialize your Elm application.

WARNING: This library is intended as a very low-level API that mirrors the DOM API almost exactly, while providing a bit of extra type safety where it makes sense. The DOM API is highly stateful and side-effectful, so be careful. To understand how to use this library properly, please read the MDN docs: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D and all the nested pages

Usage in HTML

element : Int -> Int -> List (Attribute msg) -> List Command -> Html msg

Create a Html element that you can use in your view.

view : Model -> Html Msg
view { isRunning, time } =
    Canvas.element
        width
        height
        [ onClick ToggleRunning ]
        [ Canvas.clearScreen
        , Canvas.fillStyle (Color.rgba 0 0 0 1)
        , List.range 0 100
            |> List.map (renderItem time)
            |> Canvas.batch
        ]

Composing Commands

type alias Command =
Value

Represents a command to execute on the DOM canvas. You build commands with the helper functions the library exposes, which mirror the canvas API.

Then, you pass the commands to the element you render on the view, and they will be run!

batch : List Command -> Command

Batch a list of Commands into a single Command. Useful to compose functions that generate lists of commands without having to do List manipulations all the time.

clearScreen : Command
clearScreen =
    batch
        [ clearRect 0 0 400 400
        , fillStyle (Color.rgb 0 0 0)
        ]

Colors

fillStyle : Color -> Command

Specifies the color or style to use inside shapes. The default is #000 (black). MDN Docs

fillStyle (Color.rgba 125 200 255 0.6)
strokeStyle : Color -> Command

Specifies the color or style to use for the lines around shapes. The default is #000 (black). MDN docs

[ strokeStyle (Color.rgb 0 0 255)
, strokeRect 10 10 100 100
]

Text

font : String -> Command

Specifies the current text style being used when drawing text. This string uses the same syntax as the CSS font specifier. The default font is 10px sans-serif. MDN docs

[ font "48px serif"
, strokeText "Hello world" 50 100
]
= Left
| Right
| Center
| Start
| End

Type of text alignment

  • Left
    • The text is left-aligned.
  • Right
    • The text is right-aligned.
  • Center
    • The text is centered.
  • Start
    • The text is aligned at the normal start of the line (left-aligned for left-to-right locales, right-aligned for right-to-left locales).
  • End
    • The text is aligned at the normal end of the line (right-aligned for left-to-right locales, left-aligned for right-to-left locales).
textAlign : TextAlign -> Command

Specifies the current text alignment being used when drawing text. Beware that the alignment is based on the x value of the fillText command. So if textAlign is Center, then the text would be drawn at x - (width / 2).

The default value is Start. MDN docs

[ font "48px serif"
, textAlign Left
, strokeText "Hello world" 0 100
]
= Top
| Hanging
| Middle
| Alphabetic
| Ideographic
| Bottom

Type of text baseline.

  • Top
    • The text baseline is the top of the em square.
  • Hanging
    • The text baseline is the hanging baseline. (Used by Tibetan and other Indic scripts.)
  • Middle
    • The text baseline is the middle of the em square.
  • Alphabetic
    • The text baseline is the normal alphabetic baseline.
  • Ideographic
    • The text baseline is the ideographic baseline; this is the bottom of the body of the characters, if the main body of characters protrudes beneath the alphabetic baseline. (Used by Chinese, Japanese and Korean scripts.)
  • Bottom
    • The text baseline is the bottom of the bounding box. This differs from the ideographic baseline in that the ideographic baseline doesn't consider descenders.
textBaseline : TextBaseLine -> Command

Specifies the current text baseline being used when drawing text.

The default value is Alphabetic.

See MDN docs for examples and rendering of the different modes.

fillText : String -> Float -> Float -> Maybe Float -> Command

Draws a text string at the specified coordinates, filling the string's characters with the current foreground color. An optional parameter allows specifying a maximum width for the rendered text, which the user agent will achieve by condensing the text or by using a lower font size.

The text is rendered using the font and text layout configuration as defined by the font, textAlign, textBaseline, and direction properties.

To draw the outlines of the characters in a string, call the context's strokeText method.

fillText text x y maxWidth

MDN docs

[ font "48px serif"
, fillText "Hello world" 50 100 Nothing
]
strokeText : String -> Float -> Float -> Maybe Float -> Command

Strokes — that is, draws the outlines of — the characters of a specified text string at the given (x, y) position. If the optional fourth parameter for a maximum width is provided, the text is scaled to fit that width.

See the fillText method to draw the text with the characters filled with color rather than having just their outlines drawn.

strokeText text x y maxWidth

MDN docs

strokeText "Hello world" 40 50 (Just 100)

Shapes

fillRect : Float -> Float -> Float -> Float -> Command

Draws a filled rectangle whose starting point is at the coordinates (x, y) with the specified width and height and whose style is determined by the fillStyle attribute. MDN docs

fillRect x y width height
strokeRect : Float -> Float -> Float -> Float -> Command

Paints a rectangle which has a starting point at (x, y) and has a width and an height onto the canvas, using the current stroke style. MDN docs

strokeRect x y width height
clearRect : Float -> Float -> Float -> Float -> Command

Sets all pixels in the rectangle defined by starting point (x, y) and size (width, height) to transparent black, erasing any previously drawn content. MDN docs

clearRect x y width height

A common problem with clearRect is that it may appear it does not work when not using paths properly. Don't forget to call beginPath before starting to draw the new frame after calling clearRect.

fillCircle : Float -> Float -> Float -> Command

This is a helper non-standard method to fill a circle. Normally, you'd need to call beginPath, arc with the correct arguments, and fill. This is a convenience function to easily fill a circle that mirrors fillRect.

fillCircle x y radius
strokeCircle : Float -> Float -> Float -> Command

This is a helper non-standard method to stroke a circle. Normally, you'd need to call beginPath, arc with the correct arguments, and stroke. This is a convenience function to easily fill a circle that mirrors strokeRect.

strokeCircle x y radius

Paths

beginPath : Command

Starts a new path by emptying the list of sub-paths. Call this method when you want to create a new path. MDN docs

closePath : Command

Causes the point of the pen to move back to the start of the current sub-path. It tries to add a straight line (but does not actually draw it) from the current point to the start. If the shape has already been closed or has only one point, this function does nothing. MDN docs

[ beginPath
, moveTo 20 20
, lineTo 200 20
, lineTo 120 120
, closePath -- draws last line of the triangle
, stroke
]
= NonZero
| EvenOdd

Type that represents the algorithm by which to determine if a point is inside a path or outside a path. If you are not sure, use NonZero as it is the default in the DOM API.

fill : FillRule -> Command

Fills the current or given path with the current fill style using the non-zero or even-odd winding rule. See type FillRule. MDN docs

clip : FillRule -> Command

Turns the path currently being built into the current clipping path. MDN docs

Note: Be aware that clip only works with shapes added to the path; it doesn't work with shape primitives such as rectangles created with fillRect. In this case you'd have to use rect to draw a rectangular path shape to be clipped.

stroke : Command

Strokes the current or given path with the current stroke style using the non-zero winding rule. MDN docs

arc : Float -> Float -> Float -> Float -> Float -> Bool -> Command

Adds an arc to the path which is centered at (x, y) position with radius starting at startAngle and ending at endAngle going in the given direction by anticlockwise (False is clockwise). MDN docs

[ beginPath
, arc x y radius startAngle endAngle anticlockwise
, stroke
]
arcTo : Float -> Float -> Float -> Float -> Float -> Command

Adds an arc to the path with the given control points and radius.

The arc drawn will be a part of a circle, never elliptical. Typical use could be making a rounded corner.

One way to think about the arc drawn is to imagine two straight segments, from the starting point (latest point in current path) to the first control point, and then from the first control point to the second control point. These two segments form a sharp corner with the first control point being in the corner. Using arcTo, the corner will instead be an arc with the given radius.

The arc is tangential to both segments, which can sometimes produce surprising results, e.g. if the radius given is larger than the distance between the starting point and the first control point.

If the radius specified doesn't make the arc meet the starting point (latest point in the current path), the starting point is connected to the arc with a straight line segment.

arcTo x1 y1 x2 y2 radius

MDN docs

bezierCurveTo : Float -> Float -> Float -> Float -> Float -> Float -> Command

Adds a cubic Bézier curve to the path. It requires three points. The first two points are control points and the third one is the end point. The starting point is the last point in the current path, which can be changed using moveTo before creating the Bézier curve. MDN docs

bezierCurveTo cp1x cp1y cp2x cp2y x y
  • cp1x
    • The x axis of the coordinate for the first control point.
  • cp1y
    • The y axis of the coordinate for the first control point.
  • cp2x
    • The x axis of the coordinate for the second control point.
  • cp2y
    • The y axis of the coordinate for the second control point.
  • x
    • The x axis of the coordinate for the end point.
  • y
    • The y axis of the coordinate for the end point.
lineTo : Float -> Float -> Command

Connects the last point in the sub-path to the x, y coordinates with a straight line (but does not actually draw it). MDN docs

lineTo x y
moveTo : Float -> Float -> Command

Moves the starting point of a new sub-path to the (x, y) coordinates. MDN docs

moveTo x y
quadraticCurveTo : Float -> Float -> Float -> Float -> Command

Adds a quadratic Bézier curve to the path. It requires two points. The first point is a control point and the second one is the end point. The starting point is the last point in the current path, which can be changed using moveTo before creating the quadratic Bézier curve. MDN docs

quadraticCurveTo cpx cpy x y
  • cpx
    • The x axis of the coordinate for the control point.
  • cpy
    • The y axis of the coordinate for the control point.
  • x
    • The x axis of the coordinate for the end point.
  • y
    • The y axis of the coordinate for the end point.
rect : Float -> Float -> Float -> Float -> Command

Creates a path for a rectangle at position (x, y) with a size that is determined by width and height. Those four points are connected by straight lines and the sub-path is marked as closed, so that you can fill or stroke this rectangle. MDN docs

rect x y width height

Line settings

type LineCap
= ButtCap
| RoundCap
| SquareCap

Type of end points for line drawn.

  • ButtCap
    • The ends of lines are squared off at the endpoints.
  • RoundCap
    • The ends of lines are rounded.
  • SquareCap
    • The ends of lines are squared off by adding a box with an equal width and half the height of the line's thickness.
lineCap : LineCap -> Command

Determines how the end points of every line are drawn. See LineCap for the possible types. By default this property is set to ButtCap. MDN docs

[ beginPath
, moveTo 0 0
, lineWidth 15
, lineCap RoundCap
, lineTo 100 100
, stroke
]
lineDashOffset : Float -> Command

Sets the line dash pattern offset or "phase". MDN docs

[ setLineDash [4, 16]
, lineDashOffset 2
, beginPath
, moveTo 0 100
, lineTo 400 100
, stroke
]
= BevelJoin
| RoundJoin
| MiterJoin

Determines how two connecting segments with non-zero lengths in a shape are joined together. MDN docs

  • Round
    • Rounds off the corners of a shape by filling an additional sector of disc centered at the common endpoint of connected segments. The radius for these rounded corners is equal to the line width.
  • Bevel
    • Fills an additional triangular area between the common endpoint of connected segments, and the separate outside rectangular corners of each segment.
  • Miter
    • Connected segments are joined by extending their outside edges to connect at a single point, with the effect of filling an additional lozenge-shaped area. This setting is affected by the miterLimit property.
lineJoin : LineJoin -> Command

Sets how two connecting segments (of lines, arcs or curves) with non-zero lengths in a shape are joined together (degenerate segments with zero lengths, whose specified endpoints and control points are exactly at the same position, are skipped). See the type LineJoin.

By default this property is set to MiterJoin. Note that the lineJoin setting has no effect if the two connected segments have the same direction, because no joining area will be added in this case.

MDN docs

[ lineWidth 10
, lineJoin RoundJoin
, beginPath
, moveTo 0 0
, lineTo 200 100
, lineTo 300 0
, stroke
]
lineWidth : Float -> Command

Sets the thickness of lines in space units. When setting, zero, negative, Infinity and NaN values are ignored; otherwise the current value is set to the new value. MDN docs

[ beginPath
, moveTo 0 0
, lineWidth 15
, lineTo 100 100
, stroke
]
miterLimit : Float -> Command

Sets the miter limit ratio in space units. When setting, zero, negative, Infinity and NaN values are ignored; otherwise the current value is set to the new value. MDN docs

setLineDash : List Float -> Command

Sets the line dash pattern used when stroking lines, using an array of values which specify alternating lengths of lines and gaps which describe the pattern.

To return to using solid lines, set the line dash list to an empty array.

setLineDash segments
  • segments
    • An Array of numbers which specify distances to alternately draw a line and a gap (in coordinate space units). If the number of elements in the array is odd, the elements of the array get copied and concatenated. For example, [5, 15, 25] will become [5, 15, 25, 5, 15, 25]. If the array is empty, the line dash list is cleared and line strokes return to being solid.

MDN docs

Shadows

shadowBlur : Float -> Command

Specifies the level of the blurring effect; this value doesn't correspond to a number of pixels and is not affected by the current transformation matrix. The default value is 0. Negative, Infinity or NaN values are ignored. Note that shadows are only drawn, if the shadowColor property is set to a non-transparent value. MDN docs

[ shadowColor (Color.rgb 0 0 0)
, shadowBlur 10
, fillStyle (Color.rgb 255 255 255)
, fillRect 10 10 100 100
]
shadowColor : Color -> Command

Specifies the color of the shadow. MDN docs

Note that shadows are only drawn, if the shadowColor property is set (non-transparent) and either the shadowBlur, the shadowOffsetX, or the shadowOffsetY property are non-zero.

[ shadowColor (Color.rgb 0 0 0)
, shadowOffsetY 10
, shadowOffsetX 10
, fillStyle (Color.rgb 0 255 0)
, fillRect 10 10 100 100
]
shadowOffsetX : Float -> Command

Specifies the distance that the shadow will be offset in horizontal distance. MDN docs

The default value is 0. Infinity or NaN values are ignored.

[ shadowColor (Color.rgb 0 0 0)
, shadowOffsetY 10
, shadowOffsetX 10
, fillStyle (Color.rgb 0 255 0)
, fillRect 10 10 100 100
]
shadowOffsetY : Float -> Command

Specifies the distance that the shadow will be offset in vertical distance. MDN docs

The default value is 0. Infinity or NaN values are ignored.

[ shadowColor (Color.rgb 0 0 0)
, shadowOffsetY 10
, shadowOffsetX 10
, fillStyle (Color.rgb 0 255 0)
, fillRect 10 10 100 100
]

Global Canvas settings

globalAlpha : Float -> Command

Specifies the alpha value that is applied to shapes and images before they are drawn onto the canvas. The value is in the range from 0.0 (fully transparent) to 1.0 (fully opaque). The default value is 1.0. Values outside the range, including Infinity and NaN will not be set and globalAlpha will retain its previous value.

See also the chapter Applying styles and color. MDN docs

-- Drawing two transparent rectangles
[ globalAlpha 0.5
, fillStyle (Color.rgb 0 0 255)
, fillRect 10 10 100 100
, fillStyle (Color.rgb 255 0 0)
, fillRect 50 50 100 100
]
= SourceOver
| SourceIn
| SourceOut
| SourceAtop
| DestinationOver
| DestinationIn
| DestinationOut
| DestinationAtop
| Lighter
| Copy
| Xor
| Multiply
| Screen
| Overlay
| Darken
| Lighten
| ColorDodge
| ColorBurn
| HardLight
| SoftLight
| Difference
| Exclusion
| Hue
| Saturation
| Color
| Luminosity

Type of compositing operation, identifying which of the compositing or blending mode operations to use. See the chapter Compositing from the Canvas Tutorial.

For more information and pictures of what each mode does, see the MDN docs.

globalCompositeOperation : GlobalCompositeOperationMode -> Command

Sets the type of compositing operation to apply when drawing new shapes, where type is a GlobalCompositeOperationMode identifying which of the compositing or blending mode operations to use.

See the chapter Compositing from the Canvas Tutorial, or visit the MDN docs for more information and pictures of what each mode does.

globalCompositeOperation Screen
save : Command

Saves the entire state of the canvas by pushing the current state onto a stack. MDN docs

The drawing state that gets saved onto a stack consists of:

  • The current transformation matrix.
  • The current clipping region.
  • The current dash list.
  • The current values of the following attributes: strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled.
restore : Command

Restores the most recently saved canvas state by popping the top entry in the drawing state stack. If there is no saved state, this method does nothing. MDN docs

Global Canvas transforms

rotate : Float -> Command

Adds a rotation to the transformation matrix. The angle argument represents a clockwise rotation angle and is expressed in radians.

rotate (degrees 90)

The rotation center point is always the canvas origin. To change the center point, we will need to move the canvas by using the translate method.

MDN docs

scale : Float -> Float -> Command

Adds a scaling transformation to the canvas units by x horizontally and by y vertically.

By default, one unit on the canvas is exactly one pixel. If we apply, for instance, a scaling factor of 0.5, the resulting unit would become 0.5 pixels and so shapes would be drawn at half size. In a similar way setting the scaling factor to 2.0 would increase the unit size and one unit now becomes two pixels. This results in shapes being drawn twice as large.

scale x y
  • x
    • Scaling factor in the horizontal direction.
  • y
    • Scaling factor in the vertical direction.

Note: You can use scale -1 1 to flip the context horizontally and scale 1 -1 to flip it vertically.

MDN docs

translate : Float -> Float -> Command

Adds a translation transformation by moving the canvas and its origin x horizontally and y vertically on the grid. MDN docs

translate x y
transform : Float -> Float -> Float -> Float -> Float -> Float -> Command

Multiplies the current transformation with the matrix described by the arguments of this method. You are able to scale, rotate, move and skew the context.

See also the setTransform method which resets the current transform to the identity matrix and then invokes transform.

transform a b c d e f
  • a (m11)
    • Horizontal scaling.
  • b (m12)
    • Horizontal skewing.
  • c (m21)
    • Vertical skewing.
  • d (m22)
    • Vertical scaling.
  • e (dx)
    • Horizontal moving.
  • f (dy)
    • Vertical moving.

MDN docs

setTransform : Float -> Float -> Float -> Float -> Float -> Float -> Command

Resets (overrides) the current transformation to the identity matrix and then invokes a transformation described by the arguments of this method.

See also the transform method, which does not override the current transform matrix and multiplies it with a given one.

setTransform a b c d e f
  • a (m11)
    • Horizontal scaling.
  • b (m12)
    • Horizontal skewing.
  • c (m21)
    • Vertical skewing.
  • d (m22)
    • Vertical scaling.
  • e (dx)
    • Horizontal moving.
  • f (dy)
    • Vertical moving.

MDN docs