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:
The
The
If an argument's type looks like this:
Infix operators in Haskell are defined the same way as functions, but with the operator name in parentheses.
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 a
s and returns a list of b
s, 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
To set up the canvas, use the
Finally, to render the canvas in the editor, use the
To create a 500 pixel square canvas and set the background color to white, you can use the following code:
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
To append a frame to the canvas, you can use the
Frames will be rendered in the order they are appended to the canvas. You can use the
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:
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.
(&) :: 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
Vectors support the following operators:
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.
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

line :: Length -> Shape
function takes a length and returns a line.The line extends in the positive x-direction.
ellipse

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

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

polygon :: [Vector] -> Shape
function takes a list of points and returns a polygon.The polygon's origin is at (0, 0).
bezier2

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

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

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

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

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
This shape draws nothing.
empty :: Shape
function represents the empty shape.This shape draws nothing.
Non-Primatives
The following functions create shapes using the 2D primitives above.
circle

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

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

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
The resulting
(&) :: Shape -> Shape -> Shape
operator. The empty
is the identity function for the &
operator.The resulting
Shape
is a list of Shape
s 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.
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

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

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

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

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

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

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
For shapes who's origin is at their center, this is the same as using
For other shapes,
As this function requires the canvas as an argument, it is recommended that you write your code like this:
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.
The second is to use the
The following examples all produce the same result:
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.
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 theIO
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 >>>
render $ createCanvas 500 500 <<< circle 100 >>> translate (Vector 250 250) & square 200 >>> translate (Vector 250 250)