Skip to content

Instantly share code, notes, and snippets.

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 drakulaboy commented Mar 3, 2015

cool, will give it a try too


This comment has been minimized.

Copy link

@eclectic-tech 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 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