2426021684 / elm-collage / Collage

The collage module is here to help you create freeform graphics. You can style all sorts of forms including shapes, paths, text, and images, and then shift, rotate, scale, and group them.

Contents

Coordinate system

Collages use the same coordinate system you might see in an algebra or physics problem. The origin (0,0) is at the center of the collage, not the top left corner as in some other graphics libraries. Furthermore, the y-axis points up: so moving a collage 10 units in the y-axis will move it up on screen. This is intentional. The goal is to provide an elegant interface which is abstracted as much as possible from implementation details.

Creating graphics

To create a graphic you start with creating some form: a shape, a path or a chunk of text. After creating a form, you can style it. It depends on the kind of form you created how you can style it. A shape, for example, can be filled with a uniform color, outlined with a dotted line, or both. A path only can be traced with a line style and a piece of text can be made monospaced, bold, italic, underlined etc. You can think of a form as some kind of stencil, dipping it in different colors of ink and stamp it onto the screen once or multiple times.

Styling a form will turn it into a collage. Collages are the most powerful object of this library. They cannot be styled anymore, but they can be shifted, rotated, scaled, made partially transparent, and grouped into a new collage. Yeah, you read that correctly: you can group multiple collages into a new one, which you can shift, rotate, scale, and group again!

So remember: before you can transform your drawing, you have to style it (i.e. turn it into a collage), only after styling you can shift, rotate, scale, etc. Including an external image or a piece of raw Html also belongs to the possibilities. And of course they can be shifted, rotated, scaled, ... Ok, you get the grip!

Summary

Shape          Path         Text            Image       Html

- polygon      - line       - fromString
- ngon         - segment                      |           |
- triangle     - path         |               |           |
- rectangle                   |               |           |
- square         |            |               |           |
- oval           |            |               |           |
- circle         |            |               |           |
  |              |            |               |           |
filled         traced       rendered        image       html
outlined         |            |               |           |
styled           |            |               |           |
  |              |            |               |           |
  +––––––––––––––+––––––––––––+–––––––––––––––+–––––––––––+
                              |
                              |
                              ˅

                           Collage  ˂––+
                                       |
                           - shift     |
                           - scale     |
                           - rotate    |
                           - opacity   |
                           - group     |
                             |         |
                             +–––––––––+

Basics


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

A 2-tuple of Floats representing a 2D point. (0,0) represents a point in the center of the canvas.

opposite : Point -> Point

Calculate the point at the opposite side of the origin.

Simply negates the coordinates:

opposite ( x, y ) =
  ( -x, -y )


type alias Collage msg =
Core.Collage Core.FillStyle LineStyle Text.Style msg

An opaque type representing any styled form or group of forms that can be shifted, rotated, scaled, etc. A collage could be a red circle, a dotted line, a chunk of text, or an arbitrary Html element.

Transforming collages

shift : ( Basics.Float, Basics.Float ) -> Collage msg -> Collage msg

Shift a collage by the given amount (x,y) within its local space.

This is a relative translation, so

collage
  |> shift ( 5, 10 )

would shift collage five pixels to the right and ten pixels up.

Note that this influences the way collages are composed with the Collage.Layout module, since collages are always composed with respect to their local origins. Shifting a collage with (5,10) is equivalent to moving its local origin with (-5,-10).

shiftX : Basics.Float -> Collage msg -> Collage msg

Shift a collage by the given amount on the X axis within its local space.

shiftY : Basics.Float -> Collage msg -> Collage msg

Shift a collage by the given amount on the Y axis within its local space.

scale : Basics.Float -> Collage msg -> Collage msg

Scale a collage by a given factor.

Scaling by 2 doubles both dimensions and quadruples the area.

scaleX : Basics.Float -> Collage msg -> Collage msg

Scale a collage horizontally (in its local space) by a given factor.

Scaling by 2 doubles the width and doubles the area.

scaleY : Basics.Float -> Collage msg -> Collage msg

Scale a collage vertically (in its local space) by a given factor.

Scaling by 2 doubles the height and doubles the area.

rotate : Basics.Float -> Collage msg -> Collage msg

Rotate a collage by a given angle.

Rotate takes standard Elm angles, which are radians, and turns things counterclockwise. So to turn collage 30° to the left you would say:

collage
  |> rotate (degrees 30)

opacity : Basics.Float -> Collage msg -> Collage msg

Set the opacity of a collage.

The default is 1, and 0 is totally transparent.

Grouping collages

group : List (Collage msg) -> Collage msg

Take a list of collages and combine them into a single collage, which again can be shifted, rotated, scaled, etc.

group [ drawing1, drawing2, drawing3 ]
  |> scale 3
  |> rotate (degrees 90)

Shapes

Drawing shapes


type alias Shape =
Core.Shape

Any kind of shape that can be filled and/or outlined.

Shapes only describe the dimensions of the figure. Position, color, thickness, etc. are all specified later.

rectangle : Basics.Float -> Basics.Float -> Shape

A rectangle of given width and height.

square : Basics.Float -> Shape

A square of given size.

Of course this is equal to using rectangle with the same width and height:

square size == rectangle size size

roundedRectangle : Basics.Float -> Basics.Float -> Basics.Float -> Shape

A rectangle with rounded corners.

First two arguments are for the width and height of the rectangle, last is the radius of the corners.

roundedSquare : Basics.Float -> Basics.Float -> Shape

A square with rounded corners.

Of course this is equal to using roundedRectangle with the same width and height:

roundedSquare size == roundedRectangle size size

ellipse : Basics.Float -> Basics.Float -> Shape

An ellipse with given horizontal and vertical radii.

circle : Basics.Float -> Shape

A circle of given radius.

As with a square, using circle is the same as using ellipse with the same x and y radii:

circle radius == ellipse radius radius

polygon : List Point -> Shape

Create an arbitrary polygon by specifying its corners in order.

polygon will automatically close all shapes, so the given list of points does not need to start and end with the same position.

ngon : Basics.Int -> Basics.Float -> Shape

A regular polygon with n sides. The first argument specifies the number of sides and the second is the radius.

Some ngon's with radius 50:

ngon 3 50 -- triangle

ngon 5 50 -- pentagon

ngon 8 50 -- octogon

triangle : Basics.Float -> Shape

An equilateral triangle pointing upwards with given base.

Note the difference between using triangle and ngon 3. Both produce a triangle pointing upwards with its origin in the center, however:

Turning shapes into collages

filled : FillStyle -> Shape -> Collage msg

Adds a fills to a shape, turning it into a collage.

The argument specifies the style of the fill. The outline is left invisible. To draw a red circle of radius 50 you say:

circle 50
  |> filled (uniform red)

See below for possible fill styles.

outlined : LineStyle -> Shape -> Collage msg

Adds an outline to a shape, turning it into a collage.

The arguments specify the style of the outline. The fill is left transparent. To draw a square with edge length 30 with a thin black dashed outline you say:

square 30
  |> outlined (dot thin (uniform black))

See below for the possible line styles.

styled : ( FillStyle, LineStyle ) -> Shape -> Collage msg

Adds a fill and an outline to a shape, turning it into a collage.

The tuple argument contains a fill style and a line style. To draw a thick black outlined green triangle with base 30 you say:

triangle 30
  |> styled
      ( uniform green
      , solid thick (uniform black)
      )

The tuple form helps in defining your own reusable styles. For example, if you want more of you shapes to have a thick black outline, you could rewrite above example to:

thickOutlinedAndFilled fillColor =
  ( uniform fillColor, solid thick (uniform black) )

triangle 30
  |> styled (thickOutlinedAndFilled green)

See below for all possible fill and line styles.

Paths

Please fill in an issue if you want support for curves and arcs (aka Bézier paths). I like to know if people want this before implementing it.

Drawing paths


type alias Path =
Core.Path

A 2D line or curve that can be traced.

Paths only describe the shape of the line. Position, color, thickness, etc. are all specified later. Paths can only be traced by a line style, not filled. If you like to fill a path, you have to close it. This will turn a path it into a shape, which can be filled and outlined.

line : Basics.Float -> Path

Draw a horizontal line with a given length.

The origin of the line will be (0,0). Here is a thick dotted yellow horizontal line of length 20:

line 20
  |> traced (dot thick (uniform yellow))

segment : Point -> Point -> Path

Create a path along a given line segment. Takes the start and end points of the segment as arguments.

To draw a sloped blue line from (0,5) to (5,0) you say:

segment ( 0, 5 ) ( 5, 0 )
  |> traced (uniform blue)

path : List Point -> Path

Create a path that follows a sequence of points.

It can be thought of as drawing a “connect-the-dots” line through a list of points.

Turning paths into collages or shapes

traced : LineStyle -> Path -> Collage msg

Trace a path with a given line style.

Here is a red zig-zag:

path [ ( 0, 5 ), ( 5, 0 ), ( 5, 5 ) ]
  |> traced (solid thin (uniform red))

Paths can only be traced. If you like to fill a path, you have to turn it into a shape by closing it first.

close : Path -> Shape

Close a path so that it also can be filled.

Note: Does not draw a line from start to end point for you. If you really want this, you have two options:

  1. Draw it yourself
  2. Use a polygon

Text

To create and style text, take a look at the Collage.Text module.

rendered : Text -> Collage msg

Render a chunk of styled text and turn it into a collage.

Text.fromString "Hello Collage!"
  |> Text.shape Text.Italic
  |> Text.size huge
  |> rendered

See the Collage.Text module for all the possibilities to create and style text.

Images and Html

image : ( Basics.Float, Basics.Float ) -> String -> Collage msg

Create an image given a width, height, and image source.

image 100 100 "elm-logo.jpg"

html : ( Basics.Float, Basics.Float ) -> Html msg -> Collage msg

Create a collage from an arbitrary Html element.

The resulting collage is subject to all of the regular transformations.

Styling

There are three kinds of styles:

Fill styles are used to fill a shape or color a line. Therefore, line styles contain a fill style. Line styles can be used to trace paths or outline shapes. Text styles are defined in the Collage.Text module, you can read all about them there.


type alias Style =
( FillStyle, LineStyle )

Convenience shorthand for styling.

Fill styles

For now, we have only uniform fillings and a transparent filling.

Please fill in an issue if you want support for gradients and patterns. I like to know if people want this before implementing it.


type alias FillStyle =
Core.FillStyle

Describes the fill of a shape or line.

For now, it can only be a uniform color or no fill at all.

transparent : FillStyle

Transparent fill.

uniform : Color -> FillStyle

Uniform color fill.

Line styles


type alias LineStyle =
{ fill : FillStyle
, thickness : Basics.Float
, cap : LineCap
, join : LineJoin
, dashPattern : List ( Basics.Int
, Basics.Int )
, dashPhase : Basics.Int 
}

All of the attributes of a line style.

This lets you build up a line style however you want. You can also update existing line styles with record updates.

To define a red, dashed line style with a thickness of 5px:

{ color = rgb255 255 20 20
, thickness = 5
, cap = Flat
, join = Sharp
, dashing = [ 8, 4 ]
, dashOffset = 0
}

invisible : LineStyle

Invisible line.

defaultLineStyle : LineStyle

The default line style, which is solid black with flat caps and sharp joints.

You can use record updates to build the line style you want. For example, to make a thicker line, you could say:

{ defaultLineStyle | thickness = verythick }

Line dashing

solid : Basics.Float -> FillStyle -> LineStyle

A line style representing a solid line of given thickness and color.

broken : List ( Basics.Int, Basics.Int ) -> Basics.Float -> FillStyle -> LineStyle

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

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

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

dot : Basics.Float -> FillStyle -> LineStyle

A dotted line type with the given thickness.

Calculates the length of the dots based on the given line thickness.

dash : Basics.Float -> FillStyle -> LineStyle

A dashed line type with the given thickness.

Calculates the length of the dashes based on the given line thickness.

longdash : Basics.Float -> FillStyle -> LineStyle

A dashed line type with the given thickness, where the dashes are longer than normal.

Calculates the length of the dashes based on the given line thickness.

dashdot : Basics.Float -> FillStyle -> LineStyle

A dashed line type with the given thickness, including alternating dots and dashes.

Calculates the length of the dashes based on the given line thickness.

Line thickness

We provide some sensible defaults for line thickness. They are bluntly stolen from TikZ.

ultrathin : Basics.Float

0.5 px

verythin : Basics.Float

1 px

thin : Basics.Float

2 px

semithick : Basics.Float

3 px

thick : Basics.Float

4 px

verythick : Basics.Float

6 px

ultrathick : Basics.Float

8 px

Line caps and joins


type LineCap
    = Flat
    | Round
    | Padded

The shape of the end of a line.

Flat capped lines have no endings, Padded capped lines have flat endings that extend slightly past the end of the line, and Round capped lines have hemispherical endings.

In TikZ and Css these options are called butt, rect, and round.


type LineJoin
    = Smooth
    | Sharp
    | Clipped

The shape of the “joints” of a line, where each line segment meets.

In TikZ and Css these options have the nondescriptive names round, miter, and bevel.