hsvLib: Simple Color Manipulation

hsvLib

simple yet efficient color manipulation

hsvLib is a really simple library to manipulate color.

you should be able to understand its source code with ease. I think that even a beginner can understand its code.

Docs:

colorLib.opacity(color: Color3 | BrickColor, amount: number)

change the opacity of a color or a brickColor
if the parameter amount if 1 its going to error as it need to be between 1 and 0

colorLib.saturate(color: Color3 | BrickColor, amount: number)

saturate the color
if 1 is putted, its going to be fully saturated.
!!!: if the parameter amount if 1 its going to error as it need to be between 1 and 0

colorLib.hue(color: Color3 | BrickColor, amount: number)

change the hue of a color while keeping its saturation and brightness

the parameter amount must between 0 and 360

Download

You can find my module here:

local colorLib = {}

function colorLib.opacity(color: Color3 | BrickColor, amount: number)
  if amount < 0 or amount > 1 then error("The amount parameter should have a number between 0 or 1") end

  local isBrickColor = false
  if typeof(color) == "BrickColor" then
    isBrickColor = true
    color = Color3.fromRGB(color.R, color.G, color.B)
  end
  
  local h, s, v = color:ToHSV()
  local converted = Color3.fromHSV(h, s, amount)
  if isBrickColor then
    return BrickColor.new(converted)
  else
    return converted
  end
end

function colorLib.saturate(color: Color3 | BrickColor, amount: number)
  if amount < 0 or amount > 1 then error("The amount parameter should have a number between 0 or 1") end
  local isBrickColor = false
  if typeof(color) == "BrickColor" then
    isBrickColor = true
    color = Color3.fromRGB(color.R, color.G, color.B)
  end
  
  local h, s, v = color:ToHSV()
  local converted = Color3.fromHSV(h, amount, v)
  if isBrickColor then
    return BrickColor.new(converted)
  else
    return converted
  end
end

-- change the hue
function colorLib.hue(color: Color3 | BrickColor, amount: number)
  if amount < 0 or amount > 360 then error("The amount parameter should have a number between 0 or 360") end
  
  amount = amount / 100 * 360  
  local isBrickColor = false
  if typeof(color) == "BrickColor" then
    isBrickColor = true
    color = Color3.fromRGB(color.R, color.G, color.B)
  end
  
  local h, s, v = color:ToHSV()
  local converted = Color3.fromHSV(amount, s, v)
  if isBrickColor then
    return BrickColor.new(converted)
  else
    return converted
  end
end

return colorLib
2 Likes

if amount is 1 or 0 it will error
use < and > instead

2 Likes

thanks I didn’t noticed that cLOL

also I noticed you aren’t even checking if the value is a BrickColor in colorLib.saturate and colorLib.hue

you are only checking in colorLib.opacity

yw

Can you please correct it for me? I am doing my college homework

local colorLib = {}

-- get the color’s data
function getData(color)
    color = Color3.fromRGB(color.R, color.G, color.B)

    local h, s, v = color:ToHSV()

    return {
        Check = typeof(color) == "BrickColor",
        H = h,
        S = s,
        V = v
    }
end

-- change the opacity
function colorLib.opacity(color: Color3 | BrickColor, amount: number)
    assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

    local data = getData(color)
    local converted = Color3.fromHSV(data.H, data.S, amount)

    return data.Check and BrickColor.new(converted) or converted
end

-- change the saturation
function colorLib.saturate(color: Color3 | BrickColor, amount: number)
    assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

    local data = getData(color)
    local converted = Color3.fromHSV(data.H, amount, data.V)

    return data.Check and BrickColor.new(converted) or converted
end

-- change the hue
function colorLib.hue(color: Color3 | BrickColor, amount: number)
    assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

    local data = getData(color)
    local converted = Color3.fromHSV(amount * 3.6, data.S, data.V)

    return data.Check and BrickColor.new(converted) or converted
end

I made some changes in the code, but this should work

EDIT:
instead of doing amount / 100 * 360 we can instead do amount * 3.6

2 Likes

well done. I would not have come up with a solution like this

2 Likes

the code isn’t working with brick color

local colorLib = {}

-- get the color’s RGB
function getRGB(color)
	if typeof(color) == "Color3" then
		return color.R, color.G, color.B
	else
		return color.r, color.g, color.b
	end
end

-- get the color’s data
function getData(color)
	color = Color3.fromRGB(getRGB(color))
	
	local h, s, v = color:ToHSV()

	return {
		Check = typeof(color) == "BrickColor",
		H = h,
		S = s,
		V = v
	}
end

-- change the opacity
function colorLib.opacity(color: Color3 | BrickColor, amount: number)
	assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

	local data = getData(color)
	local converted = Color3.fromHSV(data.H, data.S, amount)

	return data.Check and BrickColor.new(converted) or converted
end

-- change the saturation
function colorLib.saturate(color: Color3 | BrickColor, amount: number)
	assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

	local data = getData(color)
	local converted = Color3.fromHSV(data.H, amount, data.V)

	return data.Check and BrickColor.new(converted) or converted
end

-- change the hue
function colorLib.hue(color: Color3 | BrickColor, amount: number)
	assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

	local data = getData(color)
	local converted = Color3.fromHSV(amount * 3.6, data.S, data.V)

	return data.Check and BrickColor.new(converted) or converted
end

return colorLib

I just fixed it, tested and everything

1 Like

I modified your code so it has type check for better intelisense and so it has less redundant useless comment

local colorLib = {}

-- get the color’s RGB
function getRGB(color)
  if typeof(color) == "Color3" then
    return color.R, color.G, color.B
  else
    return color.r, color.g, color.b
  end
end

function getData(color: BrickColor | Color3)
  color = Color3.fromRGB(getRGB(color))

  local h, s, v = color:ToHSV()

  return {
    Check = typeof(color) == "BrickColor",
    H = h,
    S = s,
    V = v
  }
end

function colorLib.opacity(color: Color3 | BrickColor, amount: number)
  assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

  local data = getData(color)
  local converted = Color3.fromHSV(data.H, data.S, amount)

  return data.Check and BrickColor.new(converted) or converted
end

function colorLib.saturate(color: Color3 | BrickColor, amount: number)
  assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

  local data = getData(color)
  local converted = Color3.fromHSV(data.H, amount, data.V)

  return data.Check and BrickColor.new(converted) or converted
end

-- change the hue but keep the opacity & saturation
function colorLib.hue(color: Color3 | BrickColor, amount: number)
  assert(amount >= 0 and amount <= 1, "The amount parameter should have a number between 0 or 1")

  local data = getData(color)
  local converted = Color3.fromHSV(amount * 3.6, data.S, data.V)

  return data.Check and BrickColor.new(converted) or converted
end

return colorLib

I made the comments because you had them there before, great improvement though!

1 Like

I Still dont understand this, is there any documentation?

did you read the post? there’s a documentation right at the top