New version after 51 days

I just published a new version with a few changes. Firstly, an incompatibility: creating an editor now requires a font, where it used to implicitly use the current font. I'm fixing one previous Devlog post that used this feature. Hopefully there won't be any further incompatibilities.
This version also makes 2 bugfixes:
- changing font within a script no longer messes up the font of the output editor
- tapping past the right of a wrapping screen line correctly positions cursor at right end
Finally, we have a new feature: a little helper called `run_screen` to load code from one screen into another. Many thanks to Ryan for the suggestion. I've been feeling the need for an escape hatch like this as some of my programs have gotten too large to edit on my phone. The shrinking scrollbar has gotten harder to grab while scrolling. And Ryan's idea is just what I need. For example, a few weeks ago I showed an equation plotter in Lua Carousel that let you pan and zoom around on an infinite surface. One thing I'd been wanting to add to this program was ticks along the x- and y-axis. But my attempts took my script too far away from the ideal size of 100 lines or so. Now I have it across two screens, and as a bonus the 'ticks' screen is easy to reuse from other scripts. Here's how it looks:
function ticks(lo, hi)
local om = order_of_magnitude(hi-lo)
return approximate(lo, om), approximate_up(hi, om)
end
function order_of_magnitude(n)
return floor(math.log(n)/math.log(10))
end
function approximate(n, zeros)
-- turn n into a number with n zeros
if zeros >= 0 then
for i=1,zeros do n = n/10 end
else
for i=zeros,0 do n = n*10 end
end
n = floor(n)
if zeros >= 0 then
for i=1,zeros do n = n*10 end
else
for i=zeros,0 do n = n/10 end
end
return n
end
function approximate_up(n, zeros)
-- turn n into a number with n zeros
if zeros >= 0 then
for i=1,zeros do n = n/10 end
else
for i=zeros,0 do n = n*10 end
end
n = ceil(n)
if n == 0 then n = 1 end
if zeros >= 0 then
for i=1,zeros do n = n*10 end
else
for i=zeros,0 do n = n/10 end
end
return n
end
To add ticks to my plotter -- that adapt to my panning and zooming -- I run this screen and then call `ticks()` for each axis with the appropriate bounds to get back a reasonably round number near the bounds to start or stop drawing ticks at. Here's how the plotter looks now:
run_screen('ticks')
v = {x=-5, y=-5*Safe_height/Safe_width}
v.w, v.h = -2*v.x, -2*v.y
v.zoom = Safe_width/v.w
f,s = nil -- ids of first and second touches
start, curr = {}, {} -- coords of touches
initzoom = nil
initpos = nil -- for panning
function car.draw()
draw_axes()
color(0,0,1)
plot(sin)
color(0,0.6,0)
plot(function(x) return sin(2*x) end)
color(0,0.8,1)
plot(function(x) return 2*sin(x) end)
color(0.8,0.6,0)
plot(function(x) return x^2 end)
draw_hud()
end
function plot(f)
local prev_vy = vy(f(sx(0)))
for vx=1,Safe_width do
local curr_vy = vy(f(sx(vx)))
line(vx-1, prev_vy, vx, curr_vy)
prev_vy = curr_vy
end
end
function draw_axes()
color(0.5,0.5,0.5)
line(0, vy(0), Safe_width, vy(0))
line(vx(0), 0, vx(0), Safe_height)
local xlo, xhi = ticks(sx(0), sx(Safe_width))
for i=0,10 do
local x = xlo+i/10*(xhi-xlo)
local vx, vy = vx(x), vy(0)
line(vx, vy, vx, vy+5)
g.print(x, vx-10, vy+10)
end
local ylo, yhi = ticks(sy(Menu_bottom), sy(Safe_height))
for i=0,10 do
local y = ylo+i/10*(yhi-ylo)
local vx, vy = vx(0), vy(y)
line(vx, vy, vx+5, vy)
g.print(y, vx+10, vy+5)
end
end
function draw_hud()
local w = App.width('sin(2*x)')
local y = Menu_bottom+10
color(0,0,1)
g.print('sin(x)', Safe_width-w-35, y)
y = y+Line_height
color(0,0.6,0)
g.print('sin(2x)', Safe_width-w-35, y)
y = y+Line_height
color(0,0.8,1)
g.print('2sin(x)', Safe_width-w-35, y)
y = y+Line_height
color(0.8,0.6,0)
g.print('x^2', Safe_width-w-35, y)
color(0.5, 0.5, 0.5)
for _,touch in ipairs(touches()) do
if curr[touch] then
circle('fill', curr[touch].x, curr[touch].y, 10)
end
end
end
function car.touchpressed(id, x,y, ...)
if f == nil then
f = id
initpos = {x=v.x, y=v.y}
else
s = id
initzoom = v.zoom
end
start[id] = {x=x, y=y}
curr[id] = {x=x, y=y}
end
function car.touchreleased(id, x,y, ...)
f,s = nil
start, curr = {}, {}
initzoom = nil
initpos = nil
end
function car.touchmoved(id, x,y, ...)
if start[id] then
curr[id] = {x=x, y=y}
if s then
local oldzoom = v.zoom
v.zoom = dist(curr[f], curr[s])/dist(start[f], start[s])*initzoom
adjust_viewport(oldzoom, v.zoom)
elseif f then
v.x = initpos.x + iscale(start[f].x - x)
v.y = initpos.y - iscale(start[f].y - y)
end end end
function adjust_viewport(oldzoom, zoom)
-- ensure centroid of fingers remains in view
local c = centroid(curr[f], curr[s])
v.x = v.x + c.x/oldzoom - c.x/zoom
v.y = v.y + c.y/oldzoom - c.y/zoom
end
function centroid(a, b)
return{x=(a.x+b.x)/2, y=(a.y+b.y)/2}
end
function dist(p1, p2)
return ((p2.x-p1.x)^2 + (p2.y-p1.y)^2) ^ 0.5
end
function vx(sx) return scale(sx-v.x) end
function vy(sy) return Safe_height - scale(sy-v.y) end
function scale(d) return d*v.zoom end
function sx(vx) return v.x + iscale(vx) end
function sy(vy) return v.y + iscale(Safe_height-vy) end
function iscale(d) return d/v.zoom end
If you try pasting this program into Lua Carousel, remember to first run 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, circle = g.line, g.circle color = g.setColor floor, ceil = math.floor, math.ceil sin = math.sin touches = love.touch.getTouches
Files
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 language67 days ago
- Lua Carousel: program on the device you have, with docs at your fingertipsMay 12, 2025
- Pong Wars, MMO editionFeb 16, 2025
- New version after 41 days, and stop-motion animationFeb 15, 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.