Rounded corners
natiny.render.rounded_rectangle takes a radius per corner - top-left,
top-right, bottom-right, bottom-left, as in CSS. One call covers a card, a tab,
a pill and a leaf.
The square's corners each keep their own rhythm, and the blue dots mark their arc centres. Radii too large for the box are scaled down together, not clamped at one corner.
local natiny = require("natiny")
local demo = require("common.modules.demo")
-- Shared examples palette.
local BG = { 21 / 255, 30 / 255, 44 / 255 } -- #151E2C
local OBJECT = { 169 / 255, 179 / 255, 197 / 255 } -- #A9B3C5
local ACCENT = { 248 / 255, 249 / 255, 253 / 255 } -- #F8F9FD
local function color(c, a)
natiny.render.set_color(c[1], c[2], c[3], a or 1.0)
end
natiny.backend.init()
local win = natiny.window.create("Rounded corners", 900, 600)
natiny.window.set_scale_mode(win, natiny.window.SCALE_MODE_STRETCH)
local t = 0.0
local function frame(dt)
natiny.window.bind(win, function()
t = t + dt
natiny.render.clear(BG[1], BG[2], BG[3], 1.0)
-- ── One square, four corners, four rhythms ──────────────────
local size = 220
local x, y = 90, 60
local r = {}
for i = 1, 4 do
-- each corner a quarter of a turn behind the one before it
local phase = t * 1.3 + (i - 1) * math.pi * 0.5
r[i] = (0.5 + 0.5 * math.sin(phase)) * (size * 0.5)
end
color(ACCENT, 0.14)
natiny.render.rounded_rectangle(x, y, size, size, r[1], r[2], r[3], r[4])
color(ACCENT)
natiny.render.rounded_rectangle_outline(x, y, size, size,
r[1], r[2], r[3], r[4], 3)
-- the centre of each corner's arc, so which radius is which is
-- never in doubt
color(OBJECT)
natiny.render.circle(x + r[1], y + r[1], 4)
natiny.render.circle(x + size - r[2], y + r[2], 4)
natiny.render.circle(x + size - r[3], y + size - r[3], 4)
natiny.render.circle(x + r[4], y + size - r[4], 4)
-- ── The vocabulary: one call, three shapes ──────────────────
local vx, vw = 420, 400
color(OBJECT) -- a tab
natiny.render.rounded_rectangle(vx, 70, vw, 90, 16, 16, 0, 0)
color(ACCENT)
natiny.render.rounded_rectangle_outline(vx, 70, vw, 90, 16, 16, 0, 0, 3)
color(OBJECT) -- a pill
natiny.render.rounded_rectangle(vx, 180, vw, 60, 30)
color(ACCENT)
natiny.render.rounded_rectangle_outline(vx, 180, vw, 60, 30, 30, 30, 30, 3)
color(OBJECT) -- a leaf
natiny.render.rounded_rectangle(vx, 260, vw, 60, 0, 30, 0, 30)
color(ACCENT)
natiny.render.rounded_rectangle_outline(vx, 260, vw, 60, 0, 30, 0, 30, 3)
-- ── A wave of corners ───────────────────────────────────────
-- One radius given to rounded_rectangle stands for all four, which
-- is what this row wants: nine tiles, one phase apart.
local n, tile, gap = 9, 76, 14
local row = (900 - (n * tile + (n - 1) * gap)) * 0.5
for i = 0, n - 1 do
local squish = 0.5 + 0.5 * math.sin(t * 2.2 - i * 0.45)
color(ACCENT, 0.9)
natiny.render.rounded_rectangle(row + i * (tile + gap), 400,
tile, tile, squish * tile * 0.5)
end
color(OBJECT)
natiny.render.line(row, 500, row + n * tile + (n - 1) * gap, 500, 2)
end)
end
demo:run({
window = win,
title = "Rounded corners",
text = "Four radii per rectangle, one call",
loop = frame,
})
natiny.backend.shutdown()