Ticker

A headline that repeats every natiny.font.measure_text width, and a roll that moves by its measured height, both clipped with natiny.render.scissor_begin. Use Left / Right to change the scroll speed.


    
main.lua
local natiny = require("natiny")

natiny.backend.init()

local win = natiny.window.create("Ticker", 900, 600)
natiny.window.set_scale_mode(win, natiny.window.SCALE_MODE_STRETCH)

local res   = natiny.resource.load("data/common/fonts/roboto.ttf")
local font  = natiny.font.create(res, 30)
local small = natiny.font.create(res, 18)

local BG     = {  21 / 255,  30 / 255,  44 / 255 } -- #151E2C
local PANEL  = {  15 / 255,  22 / 255,  33 / 255 } -- #0F1621
local OBJECT = { 169 / 255, 179 / 255, 197 / 255 } -- #A9B3C5
local ACCENT = { 168 / 255, 194 / 255,  56 / 255 } -- #A8C238
local LIGHT_TEXT = { 243 / 255, 245 / 255, 250 / 255 } -- #F3F5FA

local HEADLINE = "measure_text says how long the line is  *  scissor says how much of it you may see  *  the rest is arithmetic"
local GAP = 90

local ROLL = "Roll\n\ndrawn once\nmoved every frame\nclipped to the box\n\nmeasure_text gives\nthe height it wraps\naround at"

local STRIP = { x = 70, y = 150, w = 760, h = 58 }
local BOX   = { x = 70, y = 280, w = 760, h = 230 }

local offset, roll, speed = 0, 0, 120

natiny.backend.loop(function(dt)
    natiny.window.bind(win, function()
        if natiny.input.get_key_down(natiny.input.KEY_RIGHT) then speed = speed + dt * 200 end
        if natiny.input.get_key_down(natiny.input.KEY_LEFT)  then speed = speed - dt * 200 end
        speed = math.max(0, math.min(600, speed))

        -- The line repeats every width + gap, so the scroll only ever has to
        -- count that far: two draws then cover the strip at any offset.
        local width = natiny.font.measure_text(font, HEADLINE)
        offset = (offset + speed * dt) % (width + GAP)

        local _, roll_height = natiny.font.measure_text(font, ROLL)
        roll = (roll + dt * 45) % (roll_height + BOX.h)

        natiny.render.clear(BG[1], BG[2], BG[3], 1)

        natiny.render.set_color(PANEL[1], PANEL[2], PANEL[3], 1)
        natiny.render.rectangle(STRIP.x, STRIP.y, STRIP.w, STRIP.h)
        natiny.render.scissor_begin(STRIP.x, STRIP.y, STRIP.w, STRIP.h, function()
            natiny.render.set_color(ACCENT[1], ACCENT[2], ACCENT[3], 1)
            local x = STRIP.x - offset
            natiny.render.text(font, x, STRIP.y + 12, HEADLINE)
            natiny.render.text(font, x + width + GAP, STRIP.y + 12, HEADLINE)
        end)
        natiny.render.set_color(OBJECT[1], OBJECT[2], OBJECT[3], 0.35)
        natiny.render.rectangle_outline(STRIP.x, STRIP.y, STRIP.w, STRIP.h, 2)

        natiny.render.set_color(PANEL[1], PANEL[2], PANEL[3], 1)
        natiny.render.rectangle(BOX.x, BOX.y, BOX.w, BOX.h)
        natiny.render.scissor_begin(BOX.x, BOX.y, BOX.w, BOX.h, function()
            natiny.render.set_color(LIGHT_TEXT[1], LIGHT_TEXT[2], LIGHT_TEXT[3], 1)
            natiny.render.text_box(font, BOX.x, BOX.y + BOX.h - roll, BOX.w, roll_height,
                       ROLL, natiny.render.ALIGN_CENTER)
        end)
        natiny.render.set_color(OBJECT[1], OBJECT[2], OBJECT[3], 0.35)
        natiny.render.rectangle_outline(BOX.x, BOX.y, BOX.w, BOX.h, 2)

        natiny.render.set_color(LIGHT_TEXT[1], LIGHT_TEXT[2], LIGHT_TEXT[3], 1)
        natiny.render.text(small, STRIP.x, 90, string.format(
            "left / right change the speed: %.0f px per second", speed))
    end)
end)

natiny.backend.shutdown()