local ui = require("@neyuki/ui")
-- Gradients, shadows, clipping, group opacity and backdrop blur. A gradient
-- "wallpaper" moves behind a frosted glass sidebar with a clipped,
-- scrolling list of 500 rows, a card with a shadow, and a cached canvas.
-- Scroll over the list, press Escape to quit.
local win = ui.open({ title = "Neyuki canvas", width = 640, height = 400 })
local scroll = 0
local t = 0
-- A card rendered once on a canvas and drawn every frame.
local badge = ui.canvas(120, 48, { scale = win:scale() })
badge:fillRect(0, 0, 120, 48, "#ff7a59", { radius = 24, gradient = { from = "#ff7a59", to = "#7a5cff", angle = 0 } })
badge:text(24, 12, "Canvas", { size = 20, color = "#ffffff" })
local star = ui.path()
for i = 0, 9 do
local angle = math.rad(i * 36 - 90)
local radius = 40
if (i % 2 == 1) then radius = 18 end
local x = 500 + math.cos(angle) * radius
local y = 120 + math.sin(angle) * radius
if (i == 0) then star:moveTo(x, y) else star:lineTo(x, y) end
end
star:close()
ui.run(function(events: {Event}, dt: number)
for _, event in events do
if (event.kind == "keydown" and event.key == "escape") then
win:close()
return
elseif (event.kind == "scroll") then
scroll = math.max(0, math.min(500 * 28 - 300, scroll - event.dy * 28))
end
end
t += dt
local w, h = win:size()
-- Wallpaper: a slowly rotating gradient with a few shapes to blur.
win:fillRect(0, 0, w, h, "#000000", {
gradient = { from = "#1e3c72", to = "#e96443", angle = 30 + t * 20 },
})
win:circle(420 + math.sin(t) * 60, 120, 70, "#ffd166")
win:circle(500, 280 + math.cos(t) * 40, 50, "#06d6a0")
-- Frosted glass sidebar: blur the wallpaper, tint it, clip the rows.
win:blurRegion(16, 16, 240, h - 32, 18, { radius = 16 })
win:fillRect(16, 16, 240, h - 32, "#ffffff28", { radius = 16 })
win:strokeRect(16, 16, 240, h - 32, "#ffffff50", { radius = 16 })
win:pushClip(16, 16, 240, h - 32, { radius = 16 })
local first = math.floor(scroll / 28)
for i = first, first + 14 do
if (i >= 0 and i < 500) then
win:text(32, 28 + i * 28 - scroll, "Row " .. (i + 1), { size = 16, color = "#ffffff" })
end
end
win:popClip()
-- A card with a drop shadow, fading in and out as a group.
win:pushOpacity(0.6 + 0.4 * math.sin(t * 2))
win:fillRect(300, 60, 280, 120, "#ffffff", {
radius = 14,
shadow = { blur = 24, offsetY = 10, color = "#00000066" },
})
win:text(320, 80, "Group opacity", { size = 20, color = "#202030" })
win:fillPath(star, "#ff7a59", { gradient = { kind = "radial", from = "#ffd166", to = "#ff7a59" } })
win:popOpacity()
win:drawImage(badge, 300, 220)
win:present()
end)
badge:close()