#### Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

#### Categories

```		local blue = math.min((b_step * step) + rgb1, 255)
gradient[step + 1] = {red, green, blue}
end
end
local colored_text = ""
for pos, color in ipairs(gradient) do
colored_text = colored_text .. "<" .. color .. "," .. color .. "," .. color .. ">" .. string.sub(text, pos, pos)
end
return colored_text
local clamp = function (num) return math.max(math.min(num, 255), 0) end
local rgb1 = {clamp(rgb1), clamp(rgb1), clamp(rgb1)}
local rgb2 = {clamp(rgb2), clamp(rgb2), clamp(rgb2)}
if #text == 1 then
local rgb = {}
for color = 1, 3 do rgb[color] = (rgb1[color] + rgb2[color]) / 2 end
return "<" .. rgb .. "," .. rgb .. "," .. rgb .. ">" .. text
end
if #text == 2 then
else
local length = #text - 1
local r_step = math.floor(((rgb2 - rgb1) / length) + 0.5)
local g_step = math.floor(((rgb2 - rgb1) / length) + 0.5)
local b_step = math.floor(((rgb2 - rgb1) / length) + 0.5)
for step = 1, length do
local red = math.min((r_step * step) + rgb1, 255)
local green = math.min((g_step * step) + rgb1, 255)
```

This expects to get two tables of numbers between 0-255 in {red, green, blue} format and the text you want formatted. It will return a string formatted for use with decho() in Mudlet. If you want it to just spit out the echo itself, change "return colored_text" to "decho(colored_text)". I hadn't seen this around and needed it for my system, so I threw it together at lunch, figured someone might find it neat.

Tagged:

• Member Posts: 41 Apprentice
How's it look like with a screenshot?
• Found a bug with negative steps, fixed version:
```function gradient(rgb1, rgb2, text)
local clamp = function (num) return math.max(math.min(num, 255), 0) end
local rgb1 = {clamp(rgb1), clamp(rgb1), clamp(rgb1)}
local rgb2 = {clamp(rgb2), clamp(rgb2), clamp(rgb2)}
if #text == 1 then
local rgb = {}
for color = 1, 3 do rgb[color] = (rgb1[color] + rgb2[color]) / 2 end
return "<" .. rgb .. "," .. rgb .. "," .. rgb .. ">" .. text
end
if #text == 2 then
else
local length = #text - 1
local r_step = ((rgb2 - rgb1) / length) + 0.5
local g_step = ((rgb2 - rgb1) / length) + 0.5
local b_step = ((rgb2 - rgb1) / length) + 0.5
if r_step < 0 then r_step = math.ceil(r_step) else r_step = math.floor(r_step) end
if g_step < 0 then g_step = math.ceil(g_step) else g_step = math.floor(g_step) end
if b_step < 0 then b_step = math.ceil(b_step) else b_step = math.floor(b_step) end
for step = 1, length do
local red = clamp((r_step * step) + rgb1, 255)
local green = clamp((g_step * step) + rgb1, 255)
local blue = clamp((b_step * step) + rgb1, 255)
gradient[step + 1] = {red, green, blue}
end
end
local colored_text = ""
for pos, color in ipairs(gradient) do
colored_text = colored_text .. "<" .. color .. "," .. color .. "," .. color .. ">" .. string.sub(text, pos, pos)
end
return colored_text
end```

• Hey @Sylphas

Do you mind if I port and share your function for Nexus? • edited December 2017
Sorry meant to include the code

A bit verbose but works.
• Uni said:
Hey @Sylphas

Do you mind if I port and share your function for Nexus? Feel free! I'm always happy to see someone getting use out my stuff. One note, after looking over it a bit more: you're better off not rounding until you apply the steps, it really smooths things out for certain cases, because the math all works perfectly fine without it, so you only need integers when you're ready to actually feed in the RGB values you've come up with.
• Update:
• Split the code into cgradient() and dgradient(), to work with cecho() or decho().
• Added the ability to generate the gradients as tables with cgradient_table() and dgradient_table(). This will output a table with integer keys corresponding to character number in the given string and values each being a table with the first index a three value table containing the RGB values and the second index the character itself, e.g. {{255, 255, 255}, "a"}.
• cgradient() and dgradient() will each accept a string argument followed by any number of color nodes formatted as tables of the form {r, g, b}.
Future plans:
• cgradient() works surprisingly well in my tests so far, but if anyone spots a way to smooth it out more, please let me know. Currently it's simply running a test against Mudlet's built-in color_table to find the closest named color, but there are plenty of gaps in that set of colors. I'm considering simply inserting the calculated values into color_table on the fly and just using their hex value as the key or something, but that seems messy without a good way to clean up later, since we don't know when the gradient will actually be displayed.
• I should probably implement memoization in the underlying _gradient() function, so that given the same length and color nodes it won't have to recalculate the gradient each time and can simply fetch the values it already has. I haven't noticed any processing issues with this so far, but given my eventual plans to integrate gradient color bars into my custom prompt, I figure any performance boost can't hurt.
• I may fiddle with the point at which I sanity check the inputs. Right now feeding it something like {-300, 0, 0} gets you the same {0,0,0} black you'd expect from being clamped to the RGB color boundaries, but the gradient between {-300,0,0} and {255,255,255} is not the same as it would be if it started at {0,0,0}, because the numbers aren't clamped until after all the steps have been calculated. That is, using numbers beyond the 0-255 boundary shouldn't break anything, but it will "shape" the gradient differently. I'm honestly not sure if I consider that a bug or a feature at this point. This is a comparison between dgradient() and cgradient(), respectively, over three different gradients. The middle is simple {255,0,0}-{0,0,255} red to blue, but the first shows off the ability to feed in multiple nodes, being an input of seven nodes: {255,0,0}, {255,128,0}, {255,255,0}, {0,255,0}, {0,255,255}, {0,128,255}, {128,0,255}. The final pair is simply {50,50,50}, {0,255,0}, {50,50,50}.

```function _clamp(num1, num2, num3)
local smaller = math.min(num2, num3)
local larger = math.max(num2, num3)
local minimum = math.max(0, smaller)
local maximum = math.min(255, larger)
return math.min(maximum, math.max(minimum, num1))
end

assert(length > 0)
if length == 1 then
return {rgb1}
elseif length == 2 then
return {rgb1, rgb2}
else
local color_range = {}
local step = {}
for color = 1, 3 do step[color] = (rgb2[color] - rgb1[color]) / (length - 2) end
for iter = 1, length - 2 do
for color = 1, 3 do
gradient[iter + 1][color] = math.ceil(rgb1[color] + (iter * step[color]))
end
end
for index, color in ipairs(gradient) do
for iter = 1, 3 do gradient[index][iter] = _clamp(color[iter], rgb1[iter], rgb2[iter]) end
end
end
end

local arg = {...}
if #arg == 0 then
return {}
elseif #arg == 1 then
return arg
elseif #arg == 2 then
else
local quotient = math.floor(length / (#arg - 1))
local remainder = length % (#arg - 1)
for section = 1, #arg - 1 do
local length = quotient
if section <= remainder then length = length + 1 end
for _, rgb in ipairs(gradient) do
end
end
end
end

function color_name(rgb)
local least_distance = math.huge
local color_name = ""
for name, color in pairs(color_table) do
color_distance = math.sqrt((color - rgb)^2 + (color - rgb)^2 + (color - rgb)^2)
if color_distance < least_distance then
least_distance = color_distance
color_name = name
end
end
return color_name
end

for character = 1, #text do
end
end

for character = 1, #text do
end
end

for character = 1, #text do
end
end

for character = 1, #text do
end
end```
The same code is attached as a text file if that's more convenient.

• Looking at that last gradient in my screenshot, the grey to green, I'm thinking of making a function that takes a line of text and highlights a given substring with a "glow" effect, implemented by finding the string you want and centering a subtle gradient on it, something like the greyish white default text to bright white and back.
• Sylphas: Thank you.
• for those like me that cannot wrap your head around how to use this properly