New version after 41 days, and stop-motion animation
Lua Carousel » Devlog

Today's version has some minor bugfixes and API changes. Here's a list of key changes in the repository:
- https://git.sr.ht/~akkartik/carousel2.love/commit/d88c57e
- https://git.sr.ht/~akkartik/carousel2.love/commit/76dd4f2
- https://git.sr.ht/~akkartik/carousel2.love/commit/4f68cfd
- https://git.sr.ht/~akkartik/carousel2.love/commit/661dcb1
- https://git.sr.ht/~akkartik/carousel2.love/commit/a9d106e
Nothing very likely, but still worth an upgrade.
I found out recently that a nice UI for stop-motion animation is to show previous frame(s) overlaid when recording the next frame. Here's a program that demonstrates this idea:
run_screen('widgets')
local I = {}
local mode = 'record'
-- available modes
I.record = {widgets={}}
I.play = {widgets={}}
I.speed = 3 -- frames/s
function car.draw()
for name,w in pairs(I[mode].widgets) do
if w.draw then w.draw() end
end
if I[mode].draw then
I[mode].draw()
end
end
function car.mouse_press(x,y, b)
for name,w in pairs(I[mode].widgets) do
if w.ispress and w.ispress(x,y) and w.press then
return w.press()
end end
if I[mode].mouse_press then
I[mode].mouse_press(x,y, b)
end
end
function car.mouse_release(...)
if I[mode].mouse_release then
I[mode].mouse_release(...)
end
end
function car.mouse_move(...)
if I[mode].mouse_move then
I[mode].mouse_move(...)
end
end
function car.update(...)
if I[mode].update then
I[mode].update(...)
end
end
I.frames = {}
I.strokes = {}
function I.record.draw()
g.setLineWidth(3)
g.print(#I.frames, 100,100)
color(0.5,0.5,0.5)
for _,frame in ipairs(I.frames) do
for _,stroke in ipairs(frame) do
line(unpack(stroke))
end end
color(0,0,0)
for _,stroke in ipairs(I.strokes) do
line(unpack(stroke))
end
end
function I.record.mouse_press(x,y)
I.stroke = {x,y,x,y}
table.insert(I.strokes, I.stroke)
end
function I.record.mouse_release()
I.stroke = nil
end
function I.record.mouse_move(x,y)
if I.stroke == nil then return end
table.insert(I.stroke, x)
table.insert(I.stroke, y)
end
function I.add_next()
local x,y, w,h = 200, Menu_bottom+100, 20,20
local draw = function()
color(1,0,1)
g.print('>', x,y)
end
local ispress = function(x2,y2)
return x <= x2 and x2 <= x+w and y <= y2 and y2 <= y+h
end
local press = function()
table.insert(I.frames, I.strokes)
I.strokes = {}
end
return {draw=draw, ispress=ispress, press=press}
end
I.record.widgets.add_next = I.add_next()
function I.remove_previous()
local x,y, w,h = 160, Menu_bottom+100, 20,20
local draw = function()
color(1,0,1)
g.print('<', x,y)
end
local ispress = function(x2,y2)
return x <= x2 and x2 <= x+w and y <= y2 and y2 <= y+h
end
local press = function()
table.remove(I.frames)
end
return {draw=draw, ispress=ispress, press=press}
end
I.record.widgets.remove_previous = I.remove_previous()
function I.play_widget()
local x,y, w,h = 250, Menu_bottom+100, 20,20
local draw = function()
color(1,0,1)
poly('fill', x,y, x+w, y+h/2, x, y+h)
end
local ispress = function(x2,y2)
return x <= x2 and x2 <= x+w and y <= y2 and y2 <= y+h
end
local press = function()
print('play')
mode = 'play'
end
return {draw=draw, ispress=ispress, press=press}
end
I.record.widgets.play = I.play_widget()
function I.record_widget()
local x,y, w,h = 250, Menu_bottom+100, 20,20
local draw = function()
color(1,0,1)
circle('fill', x+w/2,y+h/2, min(w,h)/2)
end
local ispress = function(x2,y2)
return x <= x2 and x2 <= x+w and y <= y2 and y2 <= y+h
end
local press = function()
print('record')
mode = 'record'
end
return {draw=draw, ispress=ispress, press=press}
end
I.play.widgets.record = I.record_widget()
I.frame_index = 1
function I.play.draw()
g.setLineWidth(3)
color(0,0,0)
local f = floor(I.frame_index)
g.print(f, 100,100)
for _,stroke in ipairs(I.frames[f]) do
line(unpack(stroke))
end
color(0,0,0)
end
function I.play.update(dt)
I.frame_index = I.frame_index+dt*I.speed
if I.frame_index >= #I.frames+1 then
I.frame_index = 1
end
end
You'll also need the 'widgets' screen I showed a while ago:
-- helper screen for creating UI widgets on screen
widgets = {} -- global; clear stuff from any previous windows
-- still ugly, though; you'll see cruft when you switch screens. TODO
long_press_duration = 1
function widgets.__draw()
for name,w in pairs(widgets) do
if type(name) ~= 'string' or name:find('__') == nil and w.draw then
w.draw()
end end end
function widgets.__press(x,y, b)
for name,w in pairs(widgets) do
if type(name) ~= 'string' or name:find('__') == nil then
if w.ispress and w.ispress(x,y) and w.press then
return w.press()
end end end end
function widgets.__update(dt)
local x, y = App.mouse_x(), App.mouse_y()
local mouse_down = App.mouse_down(1)
for name,w in pairs(widgets) do
if name:find('__') == nil then
if w.update then w.update(dt, x,y) end
if w.long_press then
if mouse_down and w.ispress(x,y) then
if w.press_time == nil then
w.press_time = 0
else
w.press_time = w.press_time+dt
if w.press_time > long_press_duration then
w.long_press()
w.press_time = nil
end
end
else
w.press_time = nil
end
end end end end
function widgets.__release(x,y, b)
for name,w in pairs(widgets) do
if type(name) ~= 'string' or name:find('__') == nil then
if w.ispress and w.ispress(x,y) and w.release then
return w.release()
end end end end
Finally, you'll also need the abbreviations on one of the example screens. Or if you've deleted that screen, here are the abbreviations I used in this post:
g = love.graphics line = g.line poly = g.polygon circle = g.circle color = g.setColor min, max = math.min, math.max floor, ceil = math.floor, math.ceil
Files
carousel2-al.love 104 kB
Feb 15, 2025
Get Lua Carousel
Lua Carousel
Write programs on desktop and mobile
| Status | In development |
| Category | Tool |
| Author | Kartik Agaram |
| Tags | LÖVE |
More posts
- Programming on your device with your preferred language56 days ago
- Lua Carousel: program on the device you have, with docs at your fingertipsMay 12, 2025
- Pong Wars, MMO editionFeb 16, 2025
- Drawing with a pen on a pendulumJan 11, 2025
- New version after 16 daysJan 04, 2025
- New version after 9 daysDec 19, 2024
- New version after 3 daysNov 17, 2024
- New version after 40 daysNov 14, 2024
- Turn your phone or tablet into a chess clockNov 01, 2024
Leave a comment
Log in with itch.io to leave a comment.