Glyph wave
Uses natiny.font.get_glyph metrics and natiny.render.text_ex to position,
rotate, and color each glyph independently around its own center. The outlined
rectangles show the glyph bounds relative to the baseline.
local natiny = require("natiny")
natiny.backend.init()
local win = natiny.window.create("Glyph wave", 900, 600)
natiny.window.set_scale_mode(win, natiny.window.SCALE_MODE_STRETCH)
local res = natiny.resource.load("common/fonts/roboto.ttf")
local font = natiny.font.create(res, 72)
local small = natiny.font.create(res, 18)
local WORD = "natiny"
local BG = natiny.color.from_hex("#151E2C")
local OBJECT = natiny.color.from_hex("#A9B3C5")
local LIGHT_TEXT = natiny.color.from_hex("#F3F5FA")
local ascent = natiny.font.get_ascent(font)
local time = 0
local function rainbow(phase)
return natiny.color.from_rgba(
0.55 + 0.45 * math.sin(phase),
0.55 + 0.45 * math.sin(phase + 2.09),
0.55 + 0.45 * math.sin(phase + 4.19),
1.0)
end
natiny.backend.loop(function(dt)
natiny.window.bind(win, function()
time = time + dt
local width = 0
for _, code in utf8.codes(WORD) do
width = width + natiny.font.get_glyph(font, code)
end
natiny.render.clear(BG)
local pen, index = (900 - width) / 2, 0
local baseline = 320
natiny.render.set_color(OBJECT)
natiny.render.line(60, baseline, 840, baseline, 1)
for _, code in utf8.codes(WORD) do
local advance, gx, gy, gw, gh = natiny.font.get_glyph(font, code)
local phase = time * 3 - index * 0.6
local bob = math.sin(phase) * 34
local tilt = math.sin(phase) * 14
natiny.render.set_color(OBJECT)
natiny.render.rectangle_outline(pen + gx, baseline + gy + bob, gw, gh, 3)
natiny.render.set_color(rainbow(phase))
natiny.render.text_ex(font, pen + gx + gw / 2, baseline + gy + gh / 2 + bob,
utf8.char(code),
gx + gw / 2, ascent + gy + gh / 2, tilt)
pen = pen + advance
index = index + 1
end
natiny.render.set_color(LIGHT_TEXT)
natiny.render.text(small, 60, 500,
"each box is what get_glyph returns: the picture, relative to the pen")
end)
end)
natiny.backend.shutdown()