MacCASOutreach/graphicsvg/3.0.0

NOTE: the latest version is 9.0.0

GraphicSVG

A library for creating SVG graphics in a way that is compatible with Elm's old Graphics library. Also includes built-in functions for creating games and other applications including keyboard presses and mouse movements.

Basic Types

type Stencil

A primitive template representing the shape you wish to draw. This must be turned into a Shape before being drawn to the screen with collage (see below).

type Shape userMsg

A filled, outlined, or filled and outlined object that can be drawn to the screen using collage.

type Collage userMsg

The Collage type represents the drawable surface of the window which contains a (x, y) pair of horizontal and vertical dimensions (arbitrary units, not necessarily in pixels) to which the drawing surface will be scaled, and the `List' of Shapes to be drawn on the drawing surface.

type alias GraphicSVG userMsg =
Collage userMsg

The GraphicSVG type alias represents the drawable surface of the window.

This type is only used to define a type signature for a user defined view as follows:

view : GraphicSVG.GraphicSVG userMsg

for use with graphicsApp and as follows:

view : Model -> GraphicSVG.GraphicSVG MyMsg

for use with notificationsApp, gameApp and App.

These assume that Model is the name of the user model type alias and MyMsg is the name of the user message type. Simply substitute the names actually used for these labels.

THIS IS DEPRECIATED AND ONLY KEPT FOR COMPATIBILITY WITH THE PREVIOUS VERSION; Use "Collage userMsg" instead of "GraphicSVG userMsg", as they are identical except in name.

Rendering To Screen

collage : Float -> Float -> List (Shape userMsg) -> Collage userMsg

Creates a blank canvas on which you can draw. Takes a width, height and a list of Shapes. Use this in your view functions in the three types of Apps above:

collage 500 500
    [
        circle 10 |> filled red
    ]
mapCollage : (a -> b) -> Collage a -> Collage b

To apply the function over all the shapes in the given Collage using the map function. (Ask if you don't know what this means.)

App

type alias App flags userModel userMsg =
Program flags ( userModel, HiddenModel ) (Msg userMsg)

This type alias is only used as a target for a user main type signature to make the type signature more clear and concise when main calls cmdApp:

main : App Flags Model Msg
main =
    app Tick
        { init = init
        , update = update
        , view = view
        , subscriptions = subscriptions
        , onUrlRequest = onUrlRequest
        , onUrlChange = onUrlChange
        }

where Tick is a message handler called once per browser window update, Flags is the type alias (or type) of the flags input from JavaScript Model is the type alias of the user persistent model, and Msg is the name of the user message type; if other names are used, they can just be substituted for these names.

Note that "type alias" could also be an ordinary "type" in all case, just that the syntax for producing a new type is not as clean as using a type alias for a record.

app :
{ init : flags -> Url -> Key -> ( userModel, Cmd userMsg )
, update : userMsg -> userModel -> ( userModel, Cmd userMsg )
, view :
userModel
-> { title : String
, body : Collage userMsg
}
, subscriptions : userModel -> Sub userMsg
, onUrlRequest : UrlRequest -> userMsg
, onUrlChange : Url -> userMsg
}
-> App flags userModel userMsg

Advanced Function Warning! app takes one parameter of its own type of the form:

{
  init = \flags url key -> (model, cmd)
, view = \model -> { title = "Your Title goes here",
                   , body = view model
                   }
, update = \userMsg userModel -> ( userModel, Cmd userMsg )
, subscriptions = \userModel -> Sub userMsg
, onUrlRequest = \urlRequest -> userMsg
,onUrlChange = \url -> userMsg
}

This matches the Elm architecture and is analogous to Browser.application.

Stencils

line : ( Float, Float ) -> ( Float, Float ) -> Stencil

Create a line from a point to a point. Use outlined to convert to a viewable Shape.

polygon : List ( Float, Float ) -> Stencil

Create a closed shape given a list of points. Can use outlined or filled to convert to a Shape.

openPolygon : List ( Float, Float ) -> Stencil

Create an open shape given a list of points. Unlike with polygon, the first and last points will not join up automatically. Can use outlined or filled to convert to a Shape.

ngon : Int -> Float -> Stencil

Create a regular polygon with a given number of sides and radius. Examples:

ngon 3 50 -- triangle


ngon 5 50 -- pentagon


ngon 8 50 -- octogon
triangle : Float -> Stencil

Synonym for ngon 3. Creates a triangle with a given size.

rightTriangle : Float -> Float -> Stencil

Creates a right-angled triangle with a given base and height.

isosceles : Float -> Float -> Stencil

Creates an isosceles triangle with a given base and height.

sideAngleSide : Float -> Float -> Float -> Stencil

Creates a triangle given two side lengths and the angle between them.

For example, sideAngleSide 30 (degrees 45) 50 creates a triangle with side lengths 30 and 50 with an angle of 45 degrees between them.

square : Float -> Stencil

Creates a square with a given side length. (Synonym for rect s s)

rect : Float -> Float -> Stencil

Creates a rectangle with a given width and height.

rectangle : Float -> Float -> Stencil

Synonym for rect.

roundedRect : Float -> Float -> Float -> Stencil

Creates a rectangle with a given width, height, and circular rounded corners with the given radius.

circle : Float -> Stencil

Creates a circle with a given radius.

oval : Float -> Float -> Stencil

Creates an oval with a given width and height.

wedge : Float -> Float -> Stencil

Creates a wedge with a given radius, and a given fraction of a circle.

wedge 50 0.5 -- semi-circle


wedge 50 0.25 -- quarter-circle


wedge 50 0.75 -- three-quarter circle

Creating Shapes from Stencils

filled : Color -> Stencil -> Shape userMsg

Fill a Stencil with a Color, creating a Shape.

circle 10
    |> filled red
outlined : LineType -> Color -> Stencil -> Shape userMsg

Outline a Stencil with a LineType and Color, creating a Shape.

circle 10
    |> outlined (solid 5) red
repaint : Color -> Shape userMsg -> Shape userMsg

Repaint an already-filled Shape. This is helpful for repainting every Shape inside a group as well.

group
    [ circle 10
        |> filled orange
    , rect 10 40
        |> filled blue
    ]
    |> repaint green
addOutline : LineType -> Color -> Shape userMsg -> Shape userMsg

Add an outline to an already-filled Shape. This only works with Shapes based on primary Stencil's, not on Group or Shape's produced by clip, union, subtract, etc.

circle 10
    |> filled red
    |> addOutline (solid 5) white
rgb : Float -> Float -> Float -> Color

Define a colour given its red, green and blue components.

rgba : Float -> Float -> Float -> Float -> Color

Define a colour given its red, green, blue and alpha components. Alpha is a decimal number (Float) from 0 to 1 representing the level of transparency.

hsl : Float -> Float -> Float -> Color

Define a colour given its hue, saturation and light components.

hsla : Float -> Float -> Float -> Float -> Color

Define a colour given its hue, saturation, light and alpha components. Alpha is a decimal number (Float) from 0 to 1 representing the level of transparency.

Grouping Shapes

group : List (Shape userMsg) -> Shape userMsg

Combine any number of Shape types into one Shape that can be transformed (moved, rotated, scaled, etc) as one Shape.

Rendering HTML

html : Float -> Float -> Html userMsg -> Shape userMsg

Display HTML inside an SVG foreignObject.

Curves

curve : ( Float, Float ) -> List Pull -> Stencil

Creates a curve starting at a point, pulled towards a point, ending at a third point. For example,

curve (0,0) [Pull (0,10) (0,20)]

gives a curve starting at (0,0), pulled towards (0,10) and ending at (0,20).

Think about curves as what you get when you take a bunch of bendy sticks with their ends glued down to a board, and then pulling each stick towards another point. You always need an initial point and at least one Pull, but you can add as many Pulls as you want to add additional curve segments, but each curve segment can only bend one way, since it is pulled in one direction.

type Pull
= Pull ( Float, Float ) ( Float, Float )

To make it easier to read the code defining a curve, and to make sure we always use the right number of curve points and pull points (which is one more curve point than pull points), we define a special Pull type, whose first point is the point we pull towards, and second point is the end point for this curve segments.

curveHelper : Shape userMsg -> Shape userMsg

Apply to a curve or group of curves in order to view their start points, end points and Pull points. Helpful while perfecting curves.

curve (0,0) [Pull (0,10) (0,20)]
    |> curveHelper

Line Styles

The LineType type is used to define the appearance of an outline for a Stencil. LineType also defines the appearence of line and curve.

solid : Float -> LineType

Define a solid LineType with the given width.

dotted : Float -> LineType

Define a dotted LineType with the given width.

dashed : Float -> LineType

Define a dashed LineType with the given width. Dashes are short line segments, versus dots which are theoretically points, but may be drawn with very short line segments.

longdash : Float -> LineType

Define a dashed LineType with the given width, where the dashes are longer than normal.

dotdash : Float -> LineType

Define a LineType with the given width, including alternating dots and dashes.

custom : List ( Float, Float ) -> Float -> LineType

A custom line defined by a list of (on,off):

custom [ ( 10, 5 ) ] 5 -- a line with dashes 10 long and spaces 5 long


custom [ ( 10, 5 ), ( 20, 5 ) ] -- on for 10, off 5, on 20, off 5

Text

text : String -> Stencil

Creates a text Stencil. You can change this Stencil using the text helper functions. Note that |> filled ... or |> outlined ... must go at the end of the text helper functions (ie note that all these functions have type Stencil -> Stencil). For example,

text "Hello World"
    |> fixedwidth
    |> bold
    |> size 14
    |> filled black
size : Float -> Stencil -> Stencil

Apply to a text Stencil to change the font size of the text.

The size has a unit called "points", which depends on the size and type of screen used, but try 12 to start.

Apply to a text Stencil to make the text bold.

Apply to a text Stencil to make the text italicized (slanted).

Apply to a text Stencil to underline the text.

Apply to a text Stencil to put a line through the centre of the text.

Apply to a text Stencil to centre the text.

Apply to a text Stencil to make the text selectable (so users can copy your text and paste it elsewhere).

Apply to a text Stencil to render the text with a Sans Serif font (ie one without thinner and thicker bits).

Apply to a text Stencil to render the text with a Serif font (ie one with thinner and thicker bits).

Apply to a text Stencil to render the text Stencil with a font in which every character has the same width. This will mean that the letters line up from line to line which is important in programming languages like Elm.

customFont : String -> Stencil -> Stencil

Apply to a text Stencil to render the text with a font of your choosing by specifying its name in a String.

Use this sparingly as support for each font will vary across browsers and devices.

Transformations

move : ( Float, Float ) -> Shape userMsg -> Shape userMsg

Move a Shape by a number of units along the x-axis and y-axis.

rotate : Float -> Shape userMsg -> Shape userMsg

Rotate a Shape by the specified amount (in radians). Use the degrees function to convert from degrees into radians:

[
    rect 30 60
        |> filled blue
        |> rotate(degrees 30)
]
scale : Float -> Shape userMsg -> Shape userMsg

Scale a Shape by a given factor.

scaleX : Float -> Shape userMsg -> Shape userMsg

Scale a Shape in the x-axis by a given factor.

scaleY : Float -> Shape userMsg -> Shape userMsg

Scale a Shape in the y-axis by a given factor.

mirrorX : Shape userMsg -> Shape userMsg

Flip a Shape along the x-axis.

mirrorY : Shape userMsg -> Shape userMsg

Flip a Shape along the y-axis.

Group Operations

clip : Shape userMsg -> Shape userMsg -> Shape userMsg

Clipping to a shape

Cut out the `Shape` on the left using the `Shape` on the right.
union : Shape userMsg -> Shape userMsg -> Shape userMsg

Shape union

Combine two `Shape`s together into one to use with clip.
subtract : Shape userMsg -> Shape userMsg -> Shape userMsg

Shape subtraction

Subtract the `Shape` on the right from the `Shape` on the left.
outside : Shape userMsg -> Shape userMsg

The whole region outside the given Shape.

ghost : Stencil -> Shape userMsg

Make a Shape into a ghost. Mostly to be used inside of the clip operations.

Notifications

notifyTap : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when a Shape is clicked or tapped.

notifyTapAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the mouse or finger when the Shape is clicked or tapped.

notifyEnter : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when the mouse enters a Shape.

notifyEnterAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the mouse when the mouse enters a Shape.

notifyLeave : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when the mouse leaves a Shape.

notifyLeaveAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the mouse when the mouse leaves a Shape.

notifyMouseMoveAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the mouse when the mouse is moved across a Shape.

notifyMouseDown : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when the mouse button is pressed while the cursor is over a Shape.

notifyMouseDownAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the mouse when the mouse button is pressed while the cursor is over a Shape.

notifyMouseUp : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when the mouse button is released while the cursor is over a Shape.

notifyMouseUpAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the mouse when the mouse button is released while the cursor is over a Shape.

notifyTouchStart : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when the user begins touching a Shape.

notifyTouchStartAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the user's finger when the user begins touching a Shape.

notifyTouchEnd : userMsg -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) when the user lifts their finger off a Shape.

notifyTouchEndAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the user's finger when the user lifts their finger off a Shape.

notifyTouchMoveAt : (( Float, Float ) -> userMsg) -> Shape userMsg -> Shape userMsg

Receive a message (userMsg) with the x and y position of the user's finger when the user moves their finger over a Shape.

Miscellaneous

makeTransparent : Float -> Shape userMsg -> Shape userMsg

Make a Shape transparent by the fraction given. Multiplies on top of other transparencies:

circle 10
    |> filled red
    |> makeTransparent 0.5
--results in a transparency of 0.5 (half vislible)


circle 10
    |> filled red
    |> makeTransparent 0.5
    |> makeTransparent 0.5
--results in a transparency of 0.25 (a quarter visible)
Float
-> Float
-> List ( Float, Shape userMsg )
-> List (Shape userMsg)

Take a Collage width and height as well as a list of tuples of depth and Shape. to produce a list of Shape's suitable for display as a group in a Collage with Shape's with lesser depth larger and in front of Shape's with greater depth.

Helpers

graphPaper : Float -> Shape userMsg

Creates a graph paper with squares of a given size.

graphPaperCustom : Float -> Float -> Color -> Shape userMsg

Creates graph paper with squares of a given size, with a user-defined thickness and colour.

map : (a -> b) -> Shape a -> Shape b

To compose multiple pages or components which each have a Msg/view/update, we need to map messages. (Ask if you don't know what this means.)

Let there be colours!

type Color

The Color type is used for filling or outlining a Stencil.