Skip to content

Instantly share code, notes, and snippets.

@HakShak HakShak/BlendColor.lua
Last active Aug 29, 2015

What would you like to do?
Rainmeter LUA Script for blending multiple color scales
-- BlendColor is a LUA script for processing multiple color scales to output
-- RGBA notation within Rainmeter INIs.
--Each scale is composed of "Start Percentrage, End Percentage, Start Color Value, End Color Value" notation
--e.g.: Fade a color in gradually over 100% would be "0,100,0,255"
--You can add more scales via a pipe '|' delimiter
--The below examples are the equivalent of "0,100,0,255"
--There is no limit to how many scales provided per option
--Only RedScale, BlueScale, GreenScale, and AlphaScale options are available.
--The measure fed to the script must have a MinValue and MaxValue set as it is based on percentages.
--Scales support variables, however, scales are only evaluated at startup.
--So dynamic variables will not be updated. (This support could be added, but doesn't make practical sense.)
--The below example will keep the color green until 50%, then fade green down to 0 from 50% to 75%.
--It also fades red in starting at 50% and makes sure it's full red from 75% to 100%
--It also keeps the alpha level at 64 from 0-50%, then fades more in from 50-100%
--Using this measure is as simple as:
function Initialize()
RedScale = load_scales('RedScale')
GreenScale = load_scales('GreenScale')
BlueScale = load_scales('BlueScale')
AlphaScale = load_scales('AlphaScale')
function Update()
local inputMeterName = SELF:GetOption('MeasureToBlend')
local inputMeter = SKIN:GetMeasure(inputMeterName)
local meterValue = inputMeter:GetRelativeValue() * 100
local red = multi_scale_color(meterValue, RedScale)
local green = multi_scale_color(meterValue, GreenScale)
local blue = multi_scale_color(meterValue, BlueScale)
local alpha = multi_scale_color(meterValue, AlphaScale)
--Simplify since Color::MakeARGB doesn't really care about decimals
--Also makes printing these less painful to look at
red = math.floor(red + 0.5)
green = math.floor(green + 0.5)
blue = math.floor(blue + 0.5)
alpha = math.floor(alpha + 0.5)
local result = red .. ',' .. green .. ',' .. blue .. ',' .. alpha
return result
function load_scales(scaleOption)
local scaleString = SELF:GetOption(scaleOption)
scalestring = SKIN:ReplaceVariables(scaleString)
local result = {}
for i in string.gmatch(scaleString, "([^|]+)") do
local scale = {}
for x in string.gmatch(i, "([^,]+)") do
local number = tonumber(x)
if number == nil then
error('Value in ' .. scaleOption .. ' option is not a number. Expecting number within group "' .. i .. '" at "' .. x .. '"')
table.insert(scale, number)
table.insert(result, scale)
return result
function scale(value, oldMin, oldMax, newMin, newMax)
local oldRange = oldMax - oldMin
local newRange = newMax - newMin
local scaled = (((value - oldMin) * newRange) / oldRange) + newMin
return scaled
--Expects lower percentage bound, upper percentage bound, lower color bound, upper color bound
function multi_scale_color(percentage, colorScaleTable)
if type(colorScaleTable) ~= 'table' then
error('"' .. colorScaleTable .. '" is not a table.')
for i, value in ipairs(colorScaleTable) do
if type(value) ~= 'table' then
error('Value (' .. value ..') at key ' .. i .. ' is not a table.')
if table.getn(value) ~= 4 then
error('Four values are required in the table, key ' .. i .. ' has only ' .. table.getn(value) .. ' values.')
if percentage >= value[1] and percentage <= value[2] then
return scale(percentage, value[1], value[2], value[3], value[4])
--Nothing was found to do
return 0
function disable_me()
print('Disabling Measure: ' .. SELF:GetName())

This comment has been minimized.

Copy link

drakulaboy commented Mar 3, 2015

cool, will give it a try too


This comment has been minimized.

Copy link

eclectic-tech commented Mar 6, 2015

Nice script!

Only because I like to see simple numbers in the return vales, I wanted to suggest changing the 'result ...' line in the [Update] section, so the values are integers, to:

   local result = math.floor(red + 0.5) .. ',' .. math.floor(green + 0.5) .. ',' .. math.floor(blue + 0.5) .. ',' .. math.floor(alpha + 0.5)

I am a novice lua programmer, so you may know a better solution.

Thanks again for this script!


This comment has been minimized.

Copy link
Owner Author

HakShak commented Mar 7, 2015

Nice! Updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.