How to do a clean light/dark changing for UI?

I’ve made kind of a start. I’ve got the presets down, so both Light and Dark mode have a Primary and Secondary color I use. The idea would be when switching, I could just check if the frame is using the Lights primary, then change to Darks primary and vice versa. But I’m struggeling to figure out how to do it in an efficient way without having to do a ton of if statements

local ColorMode = {}

local Players = game:GetService("Players")

local Player = Players.LocalPlayer
local PlayerGui = Players:WaitForChild("PlayerGui")
local HUD = PlayerGui:WaitForChild("HUD")

local ColorPresets = {
	["Light"] = {
		Primary = Color3.fromRGB(255, 255, 255),
		Secondary = Color3.fromRGB(205, 205, 205)
	},
	["Dark"] = {
		Primary = Color3.fromRGB(50, 50, 50),
		Secondary = Color3.fromRGB(100, 100, 100)
	}
}

local CurrentMode = "Light"

function ColorMode.Change()
	-- Change all the UI's
	for _, v in pairs(HUD:GetDescendants()) do
		if v:IsA("Frame") then
			if v.BackgroundColor3 == ColorPresets[CurrentMode].Primary then
				
			end
		end
	end
	
	CurrentMode = CurrentMode == "Light" and "Dark" or "Light"

	--// Update on server
end

function ColorMore.ReturnMode()
	return ColorPresets[ColorMode]
end

return ColorMode
1 Like

Its simple. Color3 starts at 0 being the darkest and 255 being the brightest.
the whitest would be (255,255,255) and the darkest would be (0,0,0)

So the colours should be proportional. Heres a rough draft:

local UIs = game.Players.Player.PlayerGui:GetDescendants()
for i = 1,#UIs do
    local C = UIs.Color3
    local R = 255 - C.R
    local G = 255 - C.G
    local B = 255 - C.B
    C = Color3.new(R,G,B)
end

This will basically invert the brightness every time it is ran, It should also invert colours if I am correct, I am not sure as I haven’t tested it.

You would need to check for text as well but that can be inverted the same way so ill leave the rest to you.

You have clearly skipped over everything I wrote :upside_down_face: Please read the question in its entirety before racing to answer :upside_down_face:

If you want check the colors before setting, I don’t think you can reduce the number of checks. But to reduce if statements, you could turn the two if statements in the for loop into one by using the and keyword between the checks. It probably won’t make the code more efficient, though. Another thing you could do is store the value that is compared into a variable before than the loop starts to get rid of unnecessary indexing.

function ColorMode.Change()
	-- Change all the UI's
	local currentPrimary = ColorPresets[CurrentMode].Primary
	for _, v in pairs(HUD:GetDescendants()) do
		if v:IsA("Frame") and v.BackgroundColor3 == currentPrimary then
				
		end
	end
	
	CurrentMode = CurrentMode == "Light" and "Dark" or "Light"

	--// Update on server
end