Reference

Editor Controls

Run your sketch.

Save your sketch.

Open one of your saved sketches.

Create a new sketch.

Comment/uncomment the current line.

Haskell


Haskell has a built in library called Prelude which contains many useful functions and types. This library is automatically imported into every Haskell project, including your sketches on this site. You can find the documentation for the Prelude library here.

Notation


Please note that the following documentation makes use of Haskell type signatures to describe functions.
Haskell type signatures look like this: identifier :: Type1 -> Type2 -> ... -> TypeN.
The :: symbol is read as "has type", and the -> symbol is read as "to".
The identifier is the name of the function, and the TypeX values are the types of the arguments and the return value. The last TypeN is always the return value.
If an argument's type looks like this: (Type1 -> Type2), it means that that argument is a function that takes a Type1 and returns a Type2.
Infix operators in Haskell are defined the same way as functions, but with the operator name in parentheses.

Examples
add :: Int -> Int -> Int — A function that takes two integers and returns an integer (add 6 7 = 13).
(+) :: Int -> Int -> Int — The addition operator, which takes two integers and returns an integer (6 + 7 = 13).

map :: (a -> b) -> [a] -> [b] — A function that takes another function, which converts from type a to type b, and a list of as and returns a list of bs, by applying the given function to each element of the list (map (add 5) [1, 2, 3, 4, 5] = [6, 7, 8, 9, 10]).

Canvas

The Canvas is the main component of the editor. It is a 2D drawing surface using uses a cartesian coordinate system, with the origin at the top-left corner. The x-axis increases to the right, while the y-axis increases downwards. All lengths are measured in pixels, while all angles are measured clockwise in radians. These are denoted by the Length and Radians types, respectively, which are both aliases for Float.

To set up the canvas, use the createCanvas :: Int -> Int -> Canvas function, providing a width and a height. Once you've created the canvas, you can set a background color using the background :: Color -> Canvas -> Canvas function, providing a color, and the canvas you created earlier. By default, the canvas has a transparent background.

Finally, to render the canvas in the editor, use the render :: Canvas -> IO () function.

To create a 500 pixel square canvas and set the background color to white, you can use the following code:
canvas :: Canvas
canvas = background White (createCanvas 500 500)

Images and Animations

An image is just an animation with a single frame. A frame is just a shape, or multiple shapes combined using the (&) :: Shape -> Shape -> Shape operator.

To append a frame to the canvas, you can use the (<<<) :: Canvas -> Shape -> Canvas operator. As this operator returns the canvas, you can chain multiple frames together by using it multiple times. You can append a list of frames by using the (<<<:) :: Canvas -> [Shape] -> Canvas operator.

Frames will be rendered in the order they are appended to the canvas. You can use the fps :: Int -> Canvas -> Canvas function to set the frames rate of the animation. By default, the fps is 24.

To create a 500 pixel square canvas, set the background color to white and set the FPS to 60, you can use the following code:
canvas :: Canvas
canvas = fps 60 (background White (createCanvas 500 500))


It should be noted that animations will automatically loop when they reach the end. Attempting to render an infinite animation will cause the editor to slow down and eventually crash, so this is not recommended.

Vectors

To represent a point, you use the Vector data type, which stores an x and a y value. To create a vector, you call the Vector constructor directly, like this: Vector 1 2.

Vectors support the following operators:
  • (^+^) :: Vector -> Vector -> Vector — Adds the second vector to the first.
  • (^-^) :: Vector -> Vector -> Vector — Subtracts the second vector from the first.
  • (^*^) :: Vector -> Float -> Vector — Multiplies each component of the vector by the given scalar value.
  • (^/^) :: Vector -> Float -> Vector — Divides each component of the vector by the given scalar value.
and the following functions:
  • mag :: Vector -> Float — Calculates the magnitude (length) of the vector.
  • arg :: Vector -> Float — Calculates the argument (angle) of the vector.
  • norm :: Vector -> Vector — Calculates the normal (unit) vector.
  • dot :: Vector -> Vector -> Float — Calculates the dot product of the two vectors.
  • cross :: Vector -> Vector -> Float — Calculates the cross product of the two vectors.

Shapes


2D Primitives


To draw 2D shapes, you can use any of the functions in this section. They all return the Shape data type. By default, all shapes are drawn at the top left corner of the canvas, have a stroke color of black, a stroke weight of 1, and no fill color.

line
lineThe line :: Length -> Shape function takes a length and returns a line.

The line extends in the positive x-direction.

ellipse
ellipseThe ellipse :: Length -> Length -> Shape function takes a horizontal axis and a vertical axis and returns an ellipse.

Just like circles, the ellipse's origin is at its center.

rect
rectThe rect :: Length -> Length -> Shape function takes a width and height and returns a rectangle.

Just like squares, the rectangle's origin is at its top left corner.

polygon
polygonThe polygon :: [Vector] -> Shape function takes a list of points and returns a polygon.

The polygon's origin is at (0, 0).

bezier2
bezier2The bezier2 :: Vector -> Vector -> Shape function takes two points and returns a quadratic Bezier curve.

The curve starts at the shape's origin and ends at the second point. The first point is the control point.

bezier3
bezier3The bezier3 :: Vector -> Vector -> Vector -> Shape function takes three points and returns a cubic Bezier curve.

The curve starts at the shape's origin and ends at the third point. The first two points are the control points.

arc
arcThe arc :: Length -> Length -> Radians -> Radians -> Shape function takes a horizontal radius, a vertical radius, a start angle, and an end angle, and returns an elliptical arc.

As with ellipses, the arc's origin is at its center.

pie
pieThe pie :: Length -> Length -> Radians -> Radians -> Shape function takes a horizontal radius, a vertical radius, a start angle, and an end angle, and returns an elliptical arc with two straight lines connecting the center to the start and end points.

The pie's origin is at its center.

segment
segmentThe arc :: Length -> Length -> Radians -> Radians -> Shape function takes a horizontal radius, a vertical radius, a start angle, and an end angle, and returns an elliptical arc with a straight line connecting the start and end points.

As with ellipses, the arc's origin is at its center.

empty
The empty :: Shape function represents the empty shape.

This shape draws nothing.

Non-Primatives


The following functions create shapes using the 2D primitives above.

circle
circleThe circle :: Length -> Shape function is a shorthand for ellipse r r, where r is the radius of the circle.

square
squareThe square :: Length -> Shape function is a shorthand for rect s s, where s is the side length of the square.

regular
regularThe regular :: Int -> Length -> Shape function takes the number of sides and a radius and returns a regular polygon, with each point lying on a circle with the given radius.

The polygon's origin is at its center, just like circles and ellipses.

Combining Shapes

Shapes can be combined using the (&) :: Shape -> Shape -> Shape operator. The empty is the identity function for the & operator.

The resulting Shape is a list of Shapes that are drawn on top of each other, in the order they are combined. Applying transformations to a group of shapes applies the transformation to each shape individually. Given that the shapes may have different relative origin points, applying transformations such as a rotation or scaling may result in unexpected behavior.

Transformations


To modify a shape, you can use any of the functions in this section. They all take some argument, the shape to be transformed, and return the transformed shape.
By default, shapes are drawn at the top left corner of the canvas, with no rotation or scaling, have a stroke color of black, a stroke weight of 1, and no fill color.

fill

fillThe fill :: Color -> Shape -> Shape function sets the fill color of the shape.

stroke

strokeThe stroke :: Color -> Shape -> Shape function sets the stroke color of the shape.

strokeWeight

strokeWeightThe strokeWeight :: Float -> Shape -> Shape function sets the stroke thickness of the shape.

translate

translateThe translate :: Vector -> Shape -> Shape function translates the shape by the given offset.

This moves the shape's origin, so for circles and ellipses, it moves the center of the shape, for lines, it moves the starting point, and for squares and rectangles, it moves the top left corner. For polygons, each point moves with the origin, maintaining their same relative positions to each other.

rotate

rotateThe rotate :: Radians -> Shape -> Shape function rotates the shape clockwise by the given angle, in radians, around its origin.

As with translations, the rotation is applied about the shape's origin point.

scale

scaleThe scale :: Float -> Shape -> Shape function scales the shape by the given scale factor.

Once again, the scale factor is applied about the shape's origin point.

Shorthands


noFill
The noFill :: Shape -> Shape function is a shorthand for fill Transparent.

noStroke
The noStroke :: Shape -> Shape function is a shorthand for stroke Transparent.

translateX
The translateX :: Float -> Shape -> Shape function is shorthand for translate (Vector x 0).

translateY
The translateY :: Float -> Shape -> Shape function is shorthand for translate (Vector 0 y).

center
The center :: Canvas -> Shape -> Shape function is a more complex translation shorthand, which moves the shape's center to the center of the canvas.

For shapes who's origin is at their center, this is the same as using translate (Vector (width / 2) (height / 2)) where width, and height are the width and height of your canvas.

For other shapes, center calculates the required offset to account for the shape's origin point and current angle of rotation. As this function does more than just a simple translation, it is important to consider the order in which transformations are applied.

As this function requires the canvas as an argument, it is recommended that you write your code like this:
canvas :: Canvas
canvas = createCanvas 500 500

main :: IO ()
main = redner $ canvas <<< circle 100 >>> center canvas

Chaining Transformations

Transformations can be applied in two ways. The first is to simply apply the transformation function to the shape directly (e.g. fill Red (circle 50)).
The second is to use the (>>>) :: Shape -> (Shape -> Shape) -> Shape operator to chain transformations together (e.g. circle 50 >>> fill Red). The id function is the identity function for the >>> operator.

The following examples all produce the same result:
  • fill Red (translate (Vector 50 50) (rotate (radians 45) (circle 50)))
  • circle 50 >>> fill Red >>> translate (Vector 50 50) >>> rotate (radians 45)
  • circle 50 >>> (fill Red . translate (Vector 50 50) . rotate (radians 45))
  • circle 50 >>> (foldr (.) id [fill Red, translate (Vector 50 50), rotate (radians 45)])
  • foldl (>>>) (circle 50) [fill Red, translate (Vector 50 50), rotate (radians 45)]

Colors

Colors are represented using the Color data type, which has the following constructors:
  • RGB Float Float Float — Represents a color with red, green, and blue values.
  • RGBA Float Float Float Float — Represents a color with red, green, blue, and alpha values.
  • Hex String — Represents a color using a hexadecimal string. You can prefix the string with a hash (e.g. "#ff0000") or you can leave it out (e.g. "ff0000").
  • HSL Float Float Float — Represents a color with hue, saturation, and lightness values.
  • HSLA Float Float Float Float — Represents a color with hue, saturation, lightness, and alpha values.
  • Transparent — Represents a transparent color.
You can also use the following CSS named colors: AliceBlue AntiqueWhite Aqua AquaMarine Azure Beige Bisque Black BlanchedAlmond Blue BlueViolet Brown BurlyWood CadetBlue Chartreuse Chocolate Coral CornflowerBlue Cornsilk Crimson Cyan DarkBlue DarkCyan DarkGoldenRod DarkGray DarkGreen DarkGrey DarkKhaki DarkMagenta DarkOliveGreen DarkOrange DarkOrchid DarkRed DarkSalmon DarkSeaGreen DarkSlateBlue DarkSlateGray DarkSlateGrey DarkTurquoise DarkViolet DeepPink DeepSkyBlue DimGray DimGrey DodgerBlue FireBrick FloralWhite ForestGreen Fuchsia Gainsboro GhostWhite Gold GoldenRod Gray Green GreenYellow Grey HoneyDew HotPink IndianRed Indigo Ivory Khaki Lavender LavenderBlush LawnGreen LemonChiffon LightBlue LightCoral LightCyan LightGoldenRodYellow LightGray LightGreen LightGrey LightPink LightSalmon LightSeaGreen LightSkyBlue LightSlateGray LightSlateGrey LightSteelBlue LightYellow Lime LimeGreen Linen Magenta Maroon MediumAquaMarine MediumBlue MediumOrchid MediumPurple MediumSeaGreen MediumSlateBlue MediumSpringGreen MediumTurquoise MediumVioletRed MidnightBlue MintCream MistyRose Moccasin NavajoWhite Navy Oldlace Olive OliveDrab Orange OrangeRed Orchid PaleGoldenRod PaleGreen PaleTurquoise PaleVioletRed PapayaWhip PeachPuff Peru Pink Plum PowderBlue Purple Red RosyBrown RoyalBlue SaddleBrown Salmon SandyBrown SeaGreen SeaShell Sienna Silver SkyBlue SlateBlue SlateGray SlateGrey Snow SpringGreen SteelBlue Tan Teal Thistle Tomato Turquoise Violet Wheat White WhiteSmoke Yellow YellowGreen

Other


Angles

The following functions convert beetween degrees and radians (Degrees and Radians are aliases for Float):
  • degrees :: Radians -> Degrees — Converts radians to degrees.
  • radians :: Degrees -> Radians — Converts degrees to radians.

Random Numbers

The following functions can be used to generate random numbers:
  • randoms :: Int -> [Double] — Generates an infinite list of random numbers between 0 and 1, using the given seed.
  • seed :: IO Int — Returns a random seed value, which you can use to generate random numbers. The seed is generated using the current time, and is therefore wrapped in the IO monad. You can use the seed value as follows:
    main :: IO ()
    main = do
      s <- seed
      print $ take 10 (randoms s)

Operator Precedence

Precedence for the (<<<), (&), and (>>>) operators is defined as follows:
  • infixl 7 <<<:
  • infixl 7 <<<
  • infixr 8 &
  • infixl 9 >>>
This means that expressions such as the following do not require parentheses.
render $ createCanvas 500 500 <<< circle 100 >>> translate (Vector 250 250)
                                & square 200 >>> translate (Vector 250 250)