# How to fill a gradient based on any amount of color values and positions

At the moment, I have this basic setup for coloring a gradient based on 4 given color values and positions

``````local ADDITION = 0.001

local Floors = {
[1] = {
Color = Color3.fromRGB(255, 0, 0),
Size = 30
},
[2] = {
Color = Color3.fromRGB(85, 255, 0),
Size = 25
},
[3] = {
Color = Color3.fromRGB(0, 85, 255),
Size = 10
},
[4] = {
Color = Color3.fromRGB(255, 170, 255),
Size = 40
}
}

-- Get total size of tower
for _, v in pairs(Floors) do
TotalSize += v.Size
end

-- Get the floor percentages
local Percentages = {}

for i, v in pairs(Floors) do
local Previous = Percentages[i - 1] or 0
Percentages[i] = Previous + (v.Size / TotalSize)
end

ColorSequenceKeypoint.new(0, Floors[1].Color),
ColorSequenceKeypoint.new(Percentages[1], Floors[1].Color),

ColorSequenceKeypoint.new(Percentages[2], Floors[2].Color),

ColorSequenceKeypoint.new(Percentages[3], Floors[3].Color),

ColorSequenceKeypoint.new(1, Floors[4].Color)
}
``````

and it works fine, however, I want it to be automatic, so if I have 2 floors, or 50 floors, it can automatically fill it in, without me having to write long lines of code. Is there anyway to fill it using a for loop or something?

Currently what it does, and the desired effect

You can loop through the table (`Percentages`) and use the code already demonstrated in your code to add in the same way. In a few minutes Iâ€™ll try and give you a code sample.

Iâ€™m unsure exactly what you mean? I tried something like this

``````-- Set floor color
for i, v in pairs(Percentages) do
if i == 1 then continue end -- Don't do bottom

if i == #Floors then continue end -- Don't do top

-- Set bottom
ColorSequenceKeypoint.new(0, Floors[1].Color),
ColorSequenceKeypoint.new(Percentages[1], Floors[1].Color),

-- Set between
ColorSequenceKeypoint.new(Percentages[i] + ADDITION, Floors[i + 1].Color),
ColorSequenceKeypoint.new(Percentages[i + 1], Floors[i + 1].Color),

-- Set top
ColorSequenceKeypoint.new(Percentages[#Floors - 1] + ADDITION, Floors[#Floors].Color),
ColorSequenceKeypoint.new(1, Floors[#Floors].Color)
})
end
``````

Well I think Iâ€™m about to be done with my solution so just give me a few minutes, because honestly Iâ€™m having a bit of trouble myself . I donâ€™t use UIGradients very often so this is new to me.

1 Like

Finally finished the script , and here it is:

``````local frame = script.Parent

local floors = {
{
Color = Color3.fromRGB(255,0,0),
Size = 30
},
{
Color = Color3.fromRGB(85, 255, 0),
Size = 25
},
{
Color = Color3.fromRGB(0, 85, 255),
Size = 10
},
{
Color = Color3.fromRGB(255, 170, 255),
Size = 40
}
}

local function calculatePercentage(number,full)
return (number/full)
end

local floorPercentages = {}

local totalFloorSize = 0

for i,v in ipairs(floors) do
totalFloorSize += v.Size
end

--yeah i know it might be inefficient to run through the table twice

for i,v in ipairs(floors) do
floorPercentages[i] = {Color = v.Color, Size = calculatePercentage(v.Size, totalFloorSize)}
end

{Color = Color3.new(0,0,0),Time=0}
}

local previousSize = 0
for i,v in ipairs(floorPercentages) do
previousSize += v.Size
end

local function TableToColorSequence(t)
local construct = {}
for i, info in ipairs(t) do
construct[i] = ColorSequenceKeypoint.new(info.Time, info.Color)
print(i, info.Time, info.Color)
end

return ColorSequence.new(construct)
end

``````

This code could probably be more efficient, but that isnâ€™t the point. So, when you modify this script to add/remove levels, all you need to change is the `floors` table.

Explanation

Explanation:

Iâ€™ll go through each part of the script one by one and explain how it works.

First, the two variables at the top define the frame that the UIGradient is applying to and the offset between levels to make the change more abrupt. The layout I made in the explorer looks like this:

â€śFullBarâ€ť is the frame being referenced to in the script.

Secondly, is the `floors` table. It simply uses a similar format to the one you made, with Color and Size being defined within each smaller dictionary. This is what you change to modify the stages/levels and such.

Next, the `calculatePercentage()` function. This function simply just takes the size of one level, divides it by the size of all of the levels combined, and creates a size value useable by the `UIGradient`.

Afterwards, the `floorPercentages` table is defined, and shortly after is filled with values from the `floors` table, but in the percentage form I mentioned before.

Then, the `gradientStepOne` table is defined. This table is the final table being used before it is converted to a `ColorSequence`. It starts defined with

``````{Color = Color3.new(0,0,0),Time=0}
``````

which is a part to prevent blending of the first stageâ€™s color with the black. Then the table is filled out with values that are doubled up to prevent blending, as shown in this `for` loop:

``````local previousSize = 0
for i,v in ipairs(floorPercentages) do
previousSize += v.Size
end
``````

(ignore the gray text, Iâ€™m pretty sure itâ€™s forum formatting for comments in some other coding language)

After the table is filled, it is converted to a color sequence by this function, actually using the code from this forum topic:

``````local function TableToColorSequence(t)
local construct = {}
for i, info in ipairs(t) do
construct[i] = ColorSequenceKeypoint.new(info.Time, info.Color)
print(i, info.Time, info.Color)
end

return ColorSequence.new(construct)
end
``````

At this point, all you have to do is set the `Color` value of the `UIGradient`, as done here:

``````local finishedGradient = TableToColorSequence(gradientStepOne)
``````

It ends up looking like this:

Have a nice day/night

1 Like