From cb71ecf9910f1d1856baef70d1e3f5e003734316 Mon Sep 17 00:00:00 2001 From: jill Date: Sat, 18 Sep 2021 03:48:03 +0300 Subject: [PATCH] parameterized eases --- dropdown.lua | 14 ++++++++++-- ease.lua | 22 +++++++++++++------ easelib.lua | 12 +++++++++++ graph.lua | 3 +++ main.lua | 2 +- slider.lua | 60 ++++++++++++++++++++++++++++++++++++++++++++-------- 6 files changed, 94 insertions(+), 19 deletions(-) diff --git a/dropdown.lua b/dropdown.lua index 1c65f72..d507b45 100644 --- a/dropdown.lua +++ b/dropdown.lua @@ -66,6 +66,13 @@ function self.createDropdowns() 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 insertDropdown(d, { x = outerpadding + dropdownWidth + padding, @@ -74,7 +81,10 @@ function self.createDropdowns() options = skeys(ease.eases), 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 insertDropdown(d, { x = outerpadding + dropdownWidth + padding, @@ -90,7 +100,7 @@ function self.createDropdowns() options = skeys(ease.eases), 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 insertDropdown(d, { x = outerpadding + dropdownWidth + padding, diff --git a/ease.lua b/ease.lua index ff73894..fd5dfec 100644 --- a/ease.lua +++ b/ease.lua @@ -2,14 +2,14 @@ local self = {} 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 return function(a) if a < point then - return e1(a / point) * point + return e1(a / point, param1[1], param1[2]) * point 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 @@ -17,18 +17,26 @@ end self.eases = {} for i,v in pairs(easelib) do 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 for i = 0, q do - local s = v[2](i / q) - if s < 0 then min = -1 end + local s = v[2](i / q, (params[1] or {}).default, (params[2] or {}).default) + if s < 0 and not v.overridemin then min = -1 end end self.eases[v[1]] = { f = v[2], max = 1, min = min, - i = i + i = i, + params = params } end diff --git a/easelib.lua b/easelib.lua index 8c89533..cf02e4b 100644 --- a/easelib.lua +++ b/easelib.lua @@ -129,4 +129,16 @@ table.insert(self, {'inOutBounce', function(t) 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 diff --git a/graph.lua b/graph.lua index f21efa6..30ae18f 100644 --- a/graph.lua +++ b/graph.lua @@ -21,6 +21,9 @@ function self.update(dt) b = b / 2 + 0.5 end graph[i] = mix(v, b, math.min(dt * 18, 1)) + if graph[i] ~= graph[i] then -- is nan + graph[i] = b + end end self.touchtimer = mix(self.touchtimer, 0, dt * 2) diff --git a/main.lua b/main.lua index 8fa34f8..be2fde8 100644 --- a/main.lua +++ b/main.lua @@ -21,7 +21,7 @@ require 'util' -- exports into global table padding = 14 outerpadding = 22 margin = 6 -dropdownWidth = 106 +dropdownWidth = 128 fontHeight = love.graphics.getFont():getHeight() -- global for convinience's sake diff --git a/slider.lua b/slider.lua index 1d24094..69da661 100644 --- a/slider.lua +++ b/slider.lua @@ -19,7 +19,7 @@ function self.kget(key) end function self.kvalue(key) - return self.kget(key).oldvalue + return self.kget(key) and self.kget(key).oldvalue end local sliderId @@ -38,7 +38,7 @@ function self.createSliders() if mode == 2 then -- mix eases insertSlider(s, { x = outerpadding, - y = outerpadding + fontHeight + padding, + y = outerpadding + fontHeight * 2.5 + padding, width = dropdownWidth, min = 0, max = 1, @@ -48,12 +48,51 @@ function self.createSliders() }) 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 end +local function normalize(a, min, max) + return (a - min) / (max - min) +end + function self.update(dt) 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)) 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.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 love.graphics.push() 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 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.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.printf(math.floor(v.value * 100)/100, -ssize * 6, ssize - 2, ssize * 12, 'center') 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 - v.value = (mx - x) / w - graph.touchtimer = 1 + v.value = ((mx - x) / w) * (v.max - v.min) + v.min + if v.name == 'mix' then graph.touchtimer = 1 end -- sorry !!! createUI() end end