picture : CanvasSize -> List Shape -> Platform.Program () () ()
Creates a picture using box-drawing characters.
For example, to get this:
┌─────────┐ ┌─────────┐
│ box 1 ╞════>│ box 2 │
└────┬────┘ └─────────┘
│
┌─────┴─────┐
│╔══════════╧╗
└╢ boxes ║
╚═══════════╝
You can write
import BoxDrawing exposing (..)
main : Program () () ()
main =
picture ( 28, 8 ) <|
[ group
[ rectangle 11 3 single
, words "box 1" |> move 3 1
, line 3 vertical single |> move 5 2
, arrow 6 horizontal double standard |> move 10 1
]
|> move 1 0
, group
[ rectangle 11 3 single
, words "box 2" |> move 3 1
]
|> move 17 0
, group
[ rectangle 13 3 single
, box 13 3 double ' ' |> move 1 1
, words "boxes" |> move 5 2
]
|> move 0 4
]
The first argument is the canvas size, the second is a list of Shape
.
The (0, 0) coordinates are at the top left corner of the screen. Positive quantities move objects toward the bottom right corner.
If you see gaps between characters, you need to adjust the style, for example, in CSS:
pre { line-height: 19px }
animation : CanvasSize -> (Basics.Int -> List Shape) -> Platform.Program () Basics.Int ()
Creates animated pictures using box-drawing characters.
For example, to draw a rectangle that expands like this:
╔═══╗
║ ║ ⇨
╚═══╝
⇩
You can write
import BoxDrawing exposing (..)
main =
animation
( 150, 40 )
(\counter ->
[ rectangle
(min 150 counter)
(min 40 counter)
double
]
)
The first argument is the canvas size, the second is a function that gets an Int
and returns a list of Shape
.
The Int
is a counter that increases by one 60 times per second making the drawing expand.
render : CanvasSize -> List Shape -> String
Transforms a list of Shape
into a String
using box-drawing characters.
This is what is used internally by picture
and animation
.
Use render
instead of picture
and animation
if you want to embed this library in a larger application so that you can control your "Elm Architecture".
These two examples are equivalent:
Example with picture
import BoxDrawing exposing (..)
main =
picture ( 5, 3 ) <|
[ rectangle 5 3 double ]
Example with render
import BoxDrawing exposing (..)
import Html
main =
Html.pre []
[ Html.text <|
render ( 5, 3 )
[ rectangle 5 3 double ]
]
move : Basics.Int -> Basics.Int -> Shape -> Shape
Move shapes around the canvas.
move
takes, in order, the horizontal and vertical quantity of how many characters the object should move.
Remember that the coordinates (0, 0) are at the top left corner of the screen.
Positive quantities move objects toward the bottom right corner.
group : List Shape -> Shape
Groups shapes together. Particularly useful when you need to move shapes of the same amount:
import BoxDrawing exposing (..)
main : Program () () ()
main =
picture ( 17, 3 ) <|
[ rectangle 7 3 single
, arrow 4 horizontal single standard
|> move 6 1
, group
[ box 7 3 double ' '
, words "box" |> move 2 1
]
|> move 10 0
]
Result:
┌─────┐ ╔═════╗
│ ├──>║ box ║
└─────┘ ╚═════╝
( Basics.Int, Basics.Int )
The size of the canvas
line : Basics.Int -> Direction -> Weight -> Shape
Make lines:
import BoxDrawing exposing (..)
main =
picture ( 10, 1 ) <|
[ line 10 horizontal double ]
Result:
════════
You give in order:
Direction
Weight
Direction
can be
horizontal
⇨vertical
⇩diagonalUp
⬀diagonalDown
⬂Weight
can be
none
single
─double
═arrow : Basics.Int -> Direction -> Weight -> ArrowDirection -> Shape
Make arrows:
import BoxDrawing exposing (..)
main =
picture ( 10, 1 ) <|
[ arrow 10 horizontal double standard ]
Result:
═══════>
An arrow
is similar to a line
but with a point at the end.
You give in order:
Direction
Weight
ArrowDirection
ArrowDirection
can be
standard
══>reversed
<══rectangle : Basics.Int -> Basics.Int -> Weight -> Shape
Make rectangles:
import BoxDrawing exposing (..)
main =
picture ( 5, 3 ) <|
[ rectangle 5 3 double ]
Result:
╔═══╗
║ ║
╚═══╝
You give in order:
Weight
box : Basics.Int -> Basics.Int -> Weight -> Char -> Shape
Make boxes:
import BoxDrawing exposing (..)
main =
box ( 5, 3 ) <|
[ rectangle 5 3 double '▒' ]
Result:
╔═══╗
║▒▒▒║
╚═══╝
You give in order:
Weight
Char
A box
is similar to a rectangle
but it also fills the inner area with a Char
. Useful if you want to cover something underneath. For example:
main =
picture ( 6, 4 ) <|
[ rectangle 5 3 single
, rectangle 5 3 double |> move 1 1
]
Result :
┌───┐
│╔══╪╗
└╫──┘║
╚═══╝
main =
picture ( 6, 4 ) <|
[ rectangle 5 3 single
, box 5 3 double ' ' |> move 1 1
]
Result:
┌───┐
│╔══╧╗
└╢ ║
╚═══╝
words : String -> Shape
Print words:
import BoxDrawing exposing (..)
main =
picture ( 13, 1 ) <|
[ words "Hello, World!" ]
Result:
Hello, World!
paragraph : String -> Shape
Print paragraphs:
import BoxDrawing exposing (..)
main =
picture ( 13, 1 ) <|
[ paragraph "Hello,\nWorld!" ]
Result:
Hello,
World!
label : String -> Weight -> Shape
Make labels. Labels are boxes with text inside:
import BoxDrawing exposing (..)
main =
picture ( 17, 3 ) <|
[ label " Hello, World! " single ]
Result:
┌───────────────┐
│ Hello, World! │
└───────────────┘
Internal.Shape.Shape
The building block of your pictures.
moving : { counter : Basics.Int, delay : Basics.Int, speed : Basics.Float, offset : Basics.Int, from : Basics.Int, to : Basics.Int } -> Basics.Int
Moves shapes.
Useful to move shapes during an animation.
counter
: An Int
that increase (tick) 60 times per seconddelay
: Delay in number of ticks before the movement startsspeed
: Smaller number: faster speed. Bigger number: slower speedoffset
: Offsetfrom
: Initial valueto
: Final valueFind examples of usage in the Robot animation:
blinking : { counter : Basics.Int, delay : Basics.Int, speed : Basics.Int, offset : Basics.Int, valueA : a, valueB : a, modBy : Basics.Int } -> a
Alternates two values.
For example, if you want to make the eye of a robot blinking:
import BoxDrawing exposing (..)
main : Program () Int ()
main =
animation
( 13, 7 )
(\counter ->
-- Head
[ rectangle 11 7 double |> move 1 0
-- Hears
, rectangle 2 2 single |> move 11 2
, rectangle 2 2 single |> move 0 2
-- Unibrow
, words "~~~/~~~" |> move 3 1
-- Eyes
, words
(blinking
{ speed = 5
, valueA = " _ _ "
, valueB = " o O "
, counter = counter
, modBy = 30
, delay = 0
, offset = 0
}
)
|> move 3 2
-- Nose
, words " └ " |> move 3 3
-- Mouth
, words " _ _ " |> move 3 4
, words " └───┘ " |> move 3 5
]
)
Result:
Internal.Weight.Weight
none : Weight
single : Weight
──────
double : Weight
══════
Internal.Direction.Direction
horizontal : Direction
══════
vertical : Direction
║
║
║
diagonalUp : Direction
/
/
/
diagonalDown : Direction
\
\
\
Internal.ArrowDirection.ArrowDirection
standard : ArrowDirection
───>
reversed : ArrowDirection
<───
To serialize a list of shapes.
Useful if you want to send a list of shapes via HTTP requests or to save them in the local storage.
The minified versions have a smaller footprint but are less human-readable.
shapesEncoder : List Internal.Shape.Shape -> Json.Encode.Value
shapesEncoderMinified : List Internal.Shape.Shape -> Json.Encode.Value
shapesDecoderMinified : Json.Decode.Decoder (List Internal.Shape.Shape)