Draw shapes and text
Draw shapes and text on a canvas that keeps them: create each shape once, then move, recolor and group it while your app runs.
Make a canvas and show it
draw.new creates a canvas, a surface for shapes measured in canvas
pixels. A canvas shows nothing until you place it in your UI with
DrawCanvas:mount. You can mount one canvas in several places.
The origin is the center of the canvas, and Y points up. A shape's pos
counts canvas pixels from the center: vec2(-100, 50) is left of the
center and above it. Coordinates and units
compares this with the UI and with images.
This program draws a hill at dusk with the sun half behind it, a house that drifts back and forth, and a caption in two colors:
local color = datumhue.color
local vec2 = datumhue.math.vec2
local vec3 = datumhue.math.vec3
local canvas = datumhue.draw.new({
width = 480,
height = 320,
background = color("#2d353b"),
})
canvas:mount({ width = 480, height = 320 })
canvas:ellipse({
pos = vec2(0, -170),
rx = 320,
ry = 120,
color = color("#a7c080"),
})
-- Drawn after the hill, but z = -1 puts the sun behind it.
canvas:circle({
pos = vec3(140, -62, -1),
radius = 50,
color = color("#dbbc7f"),
})
-- A house of three shapes that move as one.
local walls = canvas:rect({
pos = vec2(-40, -60),
width = 80,
height = 60,
color = color("#e67e80"),
})
local roof = canvas:polygon({
points = { vec2(-52, 0), vec2(52, 0), vec2(0, 44) },
color = color("#d699b6"),
})
local door = canvas:rect({
pos = vec2(-10, -60),
width = 20,
height = 34,
color = color("#475258"),
})
local house = canvas:group({ walls, roof, door })
house:animate({
pos = vec2(-140, 0),
duration = 2,
easing = "sine_in_out",
looping = true,
})
canvas:text({
pos = vec2(-220, 140),
text = "Home, ",
font_size = 28,
color = color("#d3c6aa"),
spans = {
{ text = "sweet", color = color("#7fbbb3") },
{ text = " home" },
},
})
In this example: datumhue.color datumhue.math.vec2 datumhue.math.vec3 datumhue.draw.new DrawCanvas:mount DrawCanvas:ellipse DrawCanvas:circle DrawCanvas:rect DrawCanvas:polygon DrawCanvas:group DrawPrimitive:animate DrawCanvas:text
Change a shape instead of redrawing it
Each constructor, such as DrawCanvas:circle or DrawCanvas:polygon,
returns a DrawPrimitive. The shape stays on the canvas, frame after
frame, until you call DrawPrimitive:remove. You never clear and redraw
a canvas each frame.
To change a shape, change its handle: assign DrawPrimitive.pos,
DrawPrimitive.rotation or DrawPrimitive.opacity, pass new values to
DrawPrimitive:update, or tween them with DrawPrimitive:animate, as
the house does.
Put one shape in front of another
Shapes you create without a z stack in creation order: each new shape
draws on top of the ones before it. Give pos a vec3 to set the depth
yourself. An explicit z wins over creation order, and a larger z draws
in front. The sun is created after the hill, but its z of -1 puts it
behind.
Move shapes together
DrawCanvas:group gathers shapes into a group, itself a
DrawPrimitive. Moving, hiding or fading the group moves, hides or
fades every shape in it, and removing it removes them all. Groups nest.
DrawPrimitive.parent names the group a shape belongs to; assign it to
move the shape into another group.
Draw text
DrawCanvas:text draws text from its top-left corner. Its spans add
runs with their own color, size, weight or face after the main text, as
the caption's "sweet" shows. draw.measure_text tells you how large
text will be before you draw it, to center it or fit it in a box, and
max_width wraps long lines.
Blend shapes
Shapes blend with ordinary transparency: a lower opacity, or a color
with alpha, lets what is behind show through. For additive glow,
multiply or screen, draw into an image instead, where Picture:blit
takes a blend mode (Pixel art and sprites), or give
the shape a shader as its material (Shaders).
Draw shapes or draw pixels
DatumHue has two ways to draw in 2D. Pick the one that matches how you think about the picture:
| Draw canvas | Image and picture | |
|---|---|---|
| You work with | shapes you create once and change | commands you record and replay onto pixels |
| Origin and Y | center, Y up | top-left corner, Y down |
| Each frame | change the shapes that move | rebuild the picture and apply it |
| Use it for | moving objects, diagrams, physics | pixel art, retro framebuffers, painting |
The two meet: DrawCanvas:image draws a whole image on a canvas, and
DrawCanvas:sprite draws one cell of a sprite sheet.
See also
- Draw and animate, the ball pit's first drawing
- Pixel art and sprites
- Bodies, joints and collisions
- Shaders
- Coordinates and units
Reference used on this page: datumhue.color datumhue.math.vec2 datumhue.math.vec3 datumhue.draw.new DrawCanvas:mount DrawCanvas:ellipse DrawCanvas:circle DrawCanvas:rect DrawCanvas:polygon DrawCanvas:group DrawPrimitive:animate DrawCanvas:text datumhue.image.new datumhue.scene.new DrawPrimitive:remove DrawPrimitive.pos DrawPrimitive.rotation DrawPrimitive.opacity DrawPrimitive:update DrawPrimitive.parent datumhue.draw.measure_text Picture:blit DrawCanvas:image DrawCanvas:sprite