Skip to content

Instantly share code, notes, and snippets.

@dingram
Last active November 13, 2020 09:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dingram/a66ea6c1fc97acaa211409b7b27d0b02 to your computer and use it in GitHub Desktop.
Save dingram/a66ea6c1fc97acaa211409b7b27d0b02 to your computer and use it in GitHub Desktop.
"message" effect for keyleds
-- Message effect for keyleds: lights up keys in order
--
-- Config:
--
-- color: the color that each key will use
-- group: the group of keys to light up, in order. Either this or "message"
-- must be set.
-- message: a string of space-separated key names to light up, in order. Each
-- key name may be followed by a colon and a number in ms to override the
-- time to light that key. For example, "t e s t:1000 i n g space t h i s"
-- will light each key for the default time, apart from the second "t" in
-- "test", which will light up for 1 second. Either this or "group" must
-- be set.
-- initialDelay: ms until the effect begins for the first time (default 0)
-- keyTime: ms that a given key is lit for, in total (default 400)
-- keyInterval: ms to wait before next key (default 0)
-- repeatInterval: ms between repeats of the message (default 2000)
-- attackPercent: percentage of time spent fading in (default 50)
-- decayPercent: percentage of time spent fading out (default 50)
function configMillis(setting, default, min)
min = min or 0
local val = (tonumber(keyleds.config[setting]) or default) / 1000
if val < min then
error("Config value for \"" .. setting .. "\" must not be less than " .. min .. "ms")
end
return val
end
function configPercent(setting, default)
local val = (tonumber(keyleds.config[setting]) or default) / 100
if val < 0 then
error("Config value for \"" .. setting .. "\" must not be negative")
end
return val
end
color = tocolor(keyleds.config.color) or tocolor('gray')
transparent = tocolor(color.red, color.green, color.blue, 0)
keys = keyleds.groups[keyleds.config.group]
keyTimes = {}
if not keys or #keys < 1 then
if not keyleds.config.message then
error("Need at least one key to animate; either a group or a message")
end
keys = {}
i = 1
for key in string.gmatch(keyleds.config.message, "%S+") do
print("Match: " .. key)
if key:match(":") then
keys[i] = keyleds.db:findName(key:match("^[^:]+"):upper())
keyTimes[i] = tonumber(key:match("[0-9]+$")) / 1000
else
keys[i] = keyleds.db:findName(key:upper())
end
i = i + 1
end
if #keys < 1 then
error("Message cannot be empty")
end
end
initialDelay = configMillis("initialDelay", 0)
keyTime = configMillis("keyTime", 400)
keyInterval = configMillis("keyInterval", 0)
repeatInterval = configMillis("repeatInterval", 2000)
fadeInFraction = configPercent("attackPercent", 50)
fadeOutFraction = configPercent("decayPercent", 50)
if fadeInFraction + fadeOutFraction > 1 then
error("Cannot fade for more than 100% of the time")
end
function renderKey(buffer, key, thisKeyTime)
local fadeInTime = fadeInFraction * thisKeyTime
local fadeOutTime = fadeOutFraction * thisKeyTime
if fadeInTime > 0 then
buffer[key] = fade(fadeInTime, transparent, color)
else
buffer[key] = color
end
wait(thisKeyTime - fadeOutTime)
if fadeOutTime > 0 then
buffer[key] = fade(fadeOutTime, color, transparent)
wait(fadeOutTime)
else
buffer[key] = transparent
end
end
function renderMessage(buffer)
wait(initialDelay)
while true do
for i = 1, #keys do
renderKey(buffer, keys[i], keyTimes[i] or keyTime)
if i ~= #keys then
wait(keyInterval)
end
end
wait(repeatInterval)
end
end
buffer = RenderTarget:new()
thread(renderMessage, buffer)
function render(ms, target)
target:blend(buffer)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment