parameterized eases

This commit is contained in:
jill 2021-09-18 03:48:03 +03:00
parent 20830b96f2
commit cb71ecf991
6 changed files with 94 additions and 19 deletions

View file

@ -66,6 +66,13 @@ function self.createDropdowns()
name = 'mode' name = 'mode'
}) })
local param1 = {}
local param2 = {}
param1[1] = slider.kvalue('param11') or 1
param1[2] = slider.kvalue('param12') or 1
param2[1] = slider.kvalue('param21') or 1
param2[2] = slider.kvalue('param22') or 1
if d[dropdownId].selected == 1 then -- preview ease if d[dropdownId].selected == 1 then -- preview ease
insertDropdown(d, { insertDropdown(d, {
x = outerpadding + dropdownWidth + padding, x = outerpadding + dropdownWidth + padding,
@ -74,7 +81,10 @@ function self.createDropdowns()
options = skeys(ease.eases), options = skeys(ease.eases),
name = 'ease1' name = 'ease1'
}) })
ease.ease = ease.eases[d[dropdownId].options[d[dropdownId].selected]].f local _e = ease.eases[d[dropdownId].options[d[dropdownId].selected]].f
ease.ease = function(x)
return _e(x, param1[1], param1[2])
end
elseif d[dropdownId].selected == 2 then -- mix eases elseif d[dropdownId].selected == 2 then -- mix eases
insertDropdown(d, { insertDropdown(d, {
x = outerpadding + dropdownWidth + padding, x = outerpadding + dropdownWidth + padding,
@ -90,7 +100,7 @@ function self.createDropdowns()
options = skeys(ease.eases), options = skeys(ease.eases),
name = 'ease2' name = 'ease2'
}) })
ease.ease = ease.mixEase(ease.eases[d[dropdownId - 1].options[d[dropdownId - 1].selected]].f, ease.eases[d[dropdownId].options[d[dropdownId].selected]].f, mixpoint) ease.ease = ease.mixEase(ease.eases[d[dropdownId - 1].options[d[dropdownId - 1].selected]].f, ease.eases[d[dropdownId].options[d[dropdownId].selected]].f, slider.kvalue('mix'), param1, param2)
elseif d[dropdownId].selected == 3 then -- create eases elseif d[dropdownId].selected == 3 then -- create eases
insertDropdown(d, { insertDropdown(d, {
x = outerpadding + dropdownWidth + padding, x = outerpadding + dropdownWidth + padding,

View file

@ -2,14 +2,14 @@ local self = {}
local easelib = require 'easelib' local easelib = require 'easelib'
function self.mixEase(e1, e2, point) function self.mixEase(e1, e2, point, param1, param2)
if not point then point = 0.5 end if not point then point = 0.5 end
return function(a) return function(a)
if a < point then if a < point then
return e1(a / point) * point return e1(a / point, param1[1], param1[2]) * point
else else
return e2((a - point) / (1 - point)) * (1 - point) + point return e2((a - point) / (1 - point), param2[1], param2[2]) * (1 - point) + point
end end
end end
end end
@ -18,17 +18,25 @@ self.eases = {}
for i,v in pairs(easelib) do for i,v in pairs(easelib) do
local min = 0 local min = 0
local params = {}
for i = 3, #v do
if v[i] then
table.insert(params, {min = v[i][1], max = v[i][2], default = v[i][3], name = v[i][4]})
end
end
local q = 10 local q = 10
for i = 0, q do for i = 0, q do
local s = v[2](i / q) local s = v[2](i / q, (params[1] or {}).default, (params[2] or {}).default)
if s < 0 then min = -1 end if s < 0 and not v.overridemin then min = -1 end
end end
self.eases[v[1]] = { self.eases[v[1]] = {
f = v[2], f = v[2],
max = 1, max = 1,
min = min, min = min,
i = i i = i,
params = params
} }
end end

View file

@ -129,4 +129,16 @@ table.insert(self, {'inOutBounce', function(t)
end end
end}) end})
table.insert(self, {'inElastic', function(t, a, p)
return 1 - self.outElastic(1 - t, a, p)
end, {1, 4, 1, 'a'}, {0, 1, 0.3, 'p'}, overridemin = true})
table.insert(self, {'outElastic', function(t, a, p)
return a * pow(2, -10 * t) * sin((t - p / (2 * pi) * asin(1/a)) * 2 * pi / p) + 1
end, {1, 4, 1, 'a'}, {0, 1, 0.3, 'p'}, overridemin = true})
table.insert(self, {'inOutElastic', function(t, a, p)
return t < 0.5
and 0.5 * self.inElastic(t * 2, a, p)
or 0.5 + 0.5 * self.outElastic(t * 2 - 1, a, p)
end, {1, 4, 1, 'a'}, {0, 1, 0.3, 'p'}, overridemin = true})
return self return self

View file

@ -21,6 +21,9 @@ function self.update(dt)
b = b / 2 + 0.5 b = b / 2 + 0.5
end end
graph[i] = mix(v, b, math.min(dt * 18, 1)) graph[i] = mix(v, b, math.min(dt * 18, 1))
if graph[i] ~= graph[i] then -- is nan
graph[i] = b
end
end end
self.touchtimer = mix(self.touchtimer, 0, dt * 2) self.touchtimer = mix(self.touchtimer, 0, dt * 2)

View file

@ -21,7 +21,7 @@ require 'util' -- exports into global table
padding = 14 padding = 14
outerpadding = 22 outerpadding = 22
margin = 6 margin = 6
dropdownWidth = 106 dropdownWidth = 128
fontHeight = love.graphics.getFont():getHeight() fontHeight = love.graphics.getFont():getHeight()
-- global for convinience's sake -- global for convinience's sake

View file

@ -19,7 +19,7 @@ function self.kget(key)
end end
function self.kvalue(key) function self.kvalue(key)
return self.kget(key).oldvalue return self.kget(key) and self.kget(key).oldvalue
end end
local sliderId local sliderId
@ -38,7 +38,7 @@ function self.createSliders()
if mode == 2 then -- mix eases if mode == 2 then -- mix eases
insertSlider(s, { insertSlider(s, {
x = outerpadding, x = outerpadding,
y = outerpadding + fontHeight + padding, y = outerpadding + fontHeight * 2.5 + padding,
width = dropdownWidth, width = dropdownWidth,
min = 0, min = 0,
max = 1, max = 1,
@ -48,12 +48,51 @@ function self.createSliders()
}) })
end end
local ease1 = ease.eases[dropdown.kselected('ease1')]
local ease2 = ease.eases[dropdown.kselected('ease2')]
local param1 = ease1 and ease1.params
local param2 = ease2 and ease2.params
if param1 then
for i,v in ipairs(param1) do
insertSlider(s, {
x = outerpadding + dropdownWidth + padding,
y = outerpadding + (fontHeight * 2.5 + padding) * i,
width = dropdownWidth,
min = v.min,
max = v.max,
default = v.default,
name = 'param1' .. i,
displayname = 'Parameter ' .. v.name
})
end
end
if param2 then
for i,v in ipairs(param2) do
insertSlider(s, {
x = outerpadding + dropdownWidth + padding + dropdownWidth + padding,
y = outerpadding + (fontHeight * 2.5 + padding) * i,
width = dropdownWidth,
min = v.min,
max = v.max,
default = v.default,
name = 'param2' .. i,
displayname = 'Parameter ' .. v.name
})
end
end
sliders = s sliders = s
end end
local function normalize(a, min, max)
return (a - min) / (max - min)
end
function self.update(dt) function self.update(dt)
for i, v in ipairs(sliders) do for i, v in ipairs(sliders) do
v.spintimer = mix(v.spintimer + math.abs(v.value - v.oldvalue), 0, math.min(dt * 8)) v.spintimer = mix(v.spintimer + math.abs(normalize(v.value, v.min, v.max) - normalize(v.oldvalue, v.min, v.max)), 0, math.min(dt * 8))
v.oldvalue = mix(v.oldvalue, v.value, math.min(dt * 20, 1)) v.oldvalue = mix(v.oldvalue, v.value, math.min(dt * 20, 1))
if v.spintimer > 2 then if v.spintimer > 2 then
@ -74,13 +113,16 @@ function self.render()
love.graphics.setColor(0.7, 0.7, 0.7, 0.4) love.graphics.setColor(0.7, 0.7, 0.7, 0.4)
love.graphics.line(x, y + h/2, x + w, y + h/2) love.graphics.line(x, y + h/2, x + w, y + h/2)
local sx, sy = x + w * v.oldvalue, y + h/2 local normalvalue = normalize(v.value, v.min, v.max)
local normaloldvalue = normalize(v.oldvalue, v.min, v.max)
local sx, sy = x + w * normaloldvalue, y + h/2
local ssize = h * 0.5 local ssize = h * 0.5
love.graphics.push() love.graphics.push()
love.graphics.translate(sx, sy) love.graphics.translate(sx, sy)
love.graphics.rotate((v.value - v.oldvalue) * 4 + v.spin * math.pi * 2) love.graphics.rotate((normalvalue - normaloldvalue) * 4 + v.spin * math.pi * 2)
local hovering = mx > sx - ssize/2 and mx < sx + ssize/2 and my > sy - ssize/2 and my < sy + ssize/2 and dropdown.openDropdown == 0 local hovering = mx > sx - ssize/2 and mx < sx + ssize/2 and my > sy - ssize/2 and my < sy + ssize/2 and dropdown.openDropdown == 0
local dragging = mx > x and mx < x + w and my > y and my < y + h and love.mouse.isDown(1) and dropdown.openDropdown == 0 local dragging = mx > x and mx < x + w and my > y and my < y + h and love.mouse.isDown(1) and dropdown.openDropdown == 0
@ -93,18 +135,18 @@ function self.render()
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.rectangle('line', -ssize/2, -ssize/2, ssize, ssize) love.graphics.rectangle('line', -ssize/2, -ssize/2, ssize, ssize)
love.graphics.rotate((v.value - v.oldvalue) * -2) love.graphics.rotate((normalvalue - normaloldvalue) * -2)
love.graphics.setColor(1, 1, 1, 1) love.graphics.setColor(1, 1, 1, 1)
love.graphics.printf(math.floor(v.value * 100)/100, -ssize * 6, ssize - 2, ssize * 12, 'center') love.graphics.printf(math.floor(v.value * 100)/100, -ssize * 6, ssize - 2, ssize * 12, 'center')
love.graphics.pop() love.graphics.pop()
love.graphics.printf(v.displayname, v.x + margin * 2 - ssize * 6, v.y - 5, ssize * 12, 'center') love.graphics.printf(v.displayname, v.x + margin * 2 - ssize * 6, v.y - 8, ssize * 12, 'center')
if dragging then if dragging then
v.value = (mx - x) / w v.value = ((mx - x) / w) * (v.max - v.min) + v.min
graph.touchtimer = 1 if v.name == 'mix' then graph.touchtimer = 1 end -- sorry !!!
createUI() createUI()
end end
end end