Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Would love to add 'tint' to color functions #944

Closed
tyhatch opened this issue Sep 8, 2012 · 11 comments
Closed

Would love to add 'tint' to color functions #944

tyhatch opened this issue Sep 8, 2012 · 11 comments

Comments

@tyhatch
Copy link

tyhatch commented Sep 8, 2012

I've discovered that when I'm working with colors that the current color functions don't work well enough for me. Doing some research I found a nice little explanation of how to do RGB tints (http://j.mp/U17z3x) but don't have the knowledge to work it out.

As a designer, it would be great to go @color: tint(#ff6600, 20%); and get the expected result.

Here's a better explanation of what I found and what could work within RGB without needing to first convert to HSL:

Tint is calculated in each color channel. The following formula should work:

t = tint in decimal format
V = original value
N = new value

(t * V) + (1 - t)*255 = N, then round +/- depending on decimal
   
For example, to get a 13% tint of rgb(228,217,185) or #e4d9b9:
r: (.13 * 228) + (1-.13)*255 = 251.49 round to 251 (or fa)
g: (.13 * 217) + (1-.13)*255 = 250.06 round to 250 (of fb)
b: (.13 * 185) + (1-.13)*255 = 245.9 round to 246 (or f6)

Thus tint:(rgb(228,217,185), 13%); would result in a value of rgb(251,250,246) or #fbfaf6.

Thanks.

@tyhatch tyhatch closed this as completed Sep 8, 2012
@tyhatch tyhatch reopened this Sep 8, 2012
@matthew-dean
Copy link
Member

None of these color functions will do the same trick? #596 (Issue #596)

@tyhatch
Copy link
Author

tyhatch commented Sep 8, 2012

Those are color blending modes rather than a straight tint of color. As much as I'd like to say those would work, they don't address pure tints in RGB. That's what I'm looking for. Think a percentage of a single (or spot) color. Not blending with another color. It's an artifact from print that remains handy for creating a range of closely related colors. lighten() and darken() come close, but they only address the brightness and tints address more than that. This would address the individual values for each RGB channel in a consistent manner.

(I think this is a better explanation and solution for what #845 was asking for.)

@ricardobeat
Copy link
Contributor

@tyhatch where did you get your formula? Using the one given on the link (calculate (255 - previous value), multiply that by 1/4, 1/2, 3/4, etc. and add that to the previous value), tint:(rgb(228,217,185), 13%) should result in #e8dec2.

[228,217,185].map(function(val){ return ~~Math.min(255, (255-val) * 0.13 + val) })

Anyway, you got 0xfb / 251 and 0xfa / 250 switched, the color would be #fbfaf6. That could be achieved with:

div {
  @color: #e4d9b9;
  @m: .13;
  color: @color * rgb(@m, @m, @m) + ((1-@m) * 255);
}
// div { color: #fbfaf6; }

Or, using HSL:

color: hsl(hue(@color), saturation(@color), lightness(@color)+(100-lightness(@color))*0.13);

edit: scratch what I said. We already have a pretty clear way of achieving this:

mix(@color, white, 13%); // tint
mix(@color, black, 90%); // shade

As much as I would like to see a tint() method supersed lighten, this gives the same result and is more obvious. Case closed?

(I can still provide a patch/pull request if anybody really wants this implemented)

@tyhatch
Copy link
Author

tyhatch commented Sep 8, 2012

So I did mixup 0xfa and 0xfb. (I decided this week to learn hex to decimal, so I'm still rather new at it.)

Love that you have something figured out that would work with the current methods! I'll give that a shot. Been working on separating colors into their own .less file to make managing colors much simpler. Think something like

/* Base colors */
@101020: rgb(16,16,32);
@e4d9b9: rgb(228,217,185);

/* Tints */
@e4d9b9-20-tint: tint(@e4d9b9, 20%);
@e4d9b9-40-tint: tint(@e4d9b9, 40%);
@e4d9b9-60-tint: tint(@e4d9b9, 60%);

/* Site Colors */
@page-bg: @e4d9b9-20-tint;

Then in my main.less file I bring them in with @import

@import "-colors.less";
@import "-mixins.less";
@import "-normalize.less";

/* Site Styles */
body { background: @page-bg; }

That's why I'd love to have tint().

@tyhatch
Copy link
Author

tyhatch commented Sep 8, 2012

@ricardobeat As to where I got the formula, I played around with what was on the page and tinkered a bit on paper and with a calculator to check my math. I did look in on a help page for InDesign (http://j.mp/SrUNjy) which had some helpful hints too in guiding me in the right direction. (But CMYK is too easy to figure tints with...) I mean Adobe's got it figured out for their color palettes, so it can't be that difficult. ;)

As I said, I'm not a math guy and so it was a very rough guess. I'm really glad there are better mathematicians out there than me.

@tyhatch
Copy link
Author

tyhatch commented Sep 8, 2012

@ricardobeat Hadn't thought of using mix() that way. Excellent. That solves my dilemma. Agree with you about having tint() replace lighten() would be a better approach.

@lukeapage
Copy link
Member

Maybe we should advertise this way of doing it in the documentation? We can also consider adding tint/shade as helper functions..

@Synchro
Copy link
Member

Synchro commented Sep 10, 2012

Tint/shade is not the same thing as lighten/darken. Tint and shade are effectively mixing with white and black respectively, whereas lighten/darken are manuipulating the luminance channel independently of hue and saturation. The former can produce hue shifts, whereas the latter does not. That's not to say it's not useful, just that it's not the same thing. Mathematically it's that linear changes in RGB space do not necessarily correspond with linear changes in HSL space, though in practice they will produce fairly similar results.
I agree with @agatronic here - the mix function does what's needed, so it can be covered by docs, something that's in progress over here. Can less functions be called by each other, i.e. could a tint() function call mix() internally, or does it need its own implementation?

@lukeapage
Copy link
Member

In the js you could easily have a helper function that called mix

@Synchro
Copy link
Member

Synchro commented Sep 10, 2012

I've added these functions and tests in pull request #947 - I can't figure out how to attach a pull request to an existing issue.

@lukeapage
Copy link
Member

added and in 1.3.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants