bgrins / tinycolor Goto Github PK
View Code? Open in Web Editor NEWFast, small color manipulation and conversion for JavaScript
Home Page: https://bgrins.github.io/TinyColor/
License: MIT License
Fast, small color manipulation and conversion for JavaScript
Home Page: https://bgrins.github.io/TinyColor/
License: MIT License
It would be nice if these methods returned this
. Would allow things like this:
var color = tinycolor('red').setAlpha(0.2).toString('rgb');
The latest package.json indicates the version's at 0.9.16, but the one on npm is at 0.9.9.
I know that is possible to do this with the API already provided but would be nice to have this. For example I have a list of possible colors and I would like to get the first one that is readable above a certain threshold.
I figured out why. You're using a non-standard way to get a character from a string.
Array-like character access (the second way above) is not part of ECMAScript 3. It is a JavaScript and ECMAScript 5 feature.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#Character_access
// Return a 3 character hex if possible
if (hex[0][0] == hex[0][1] && hex[1][0] == hex[1][1] && hex[2][0] == hex[2][1]) {
return hex[0][0] + hex[1][0] + hex[2][0];
}
should be
// Return a 3 character hex if possible
if (hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
}
Thanks for the plugin, it's pretty awesome.
Hi, it's possible to add function getContrast
to show contrast color like less :
Example
p {
a: contrast(#bbbbbb);
b: contrast(#222222, #101010);
c: contrast(#222222, #101010, #dddddd);
d: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 30%);
e: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 80%);
}
Output
p {
a: #000000 // black
b: #ffffff // white
c: #dddddd
d: #000000 // black
e: #ffffff // white
}
This library is great, using it to validate and preview user-entered colors in a theming UI.
One issue I ran into:
A possible solution for me would be to post-process these when the form is saved. I'd prefer to restrict the input to valid values though. I had a read of TinyColor js to see if I had missed any obvious options for this, but didn't spot any.
Is there an option I'm missing? Or would you consider providing these, either for TinyColour object init, or for the isValid() function. NP if this is a weird use case and the answer is no. Workarounds would be found :)
-- EDIT --
I wrote additional validation using the private _format property of TinyColor object. Using the private var might break in future, but it was a lightweight solution that works nicely.
var color_is_valid = false;
if (color.isValid() == true) {
if (color._format == 'hex') {
if (input_value.charAt(0) == '#') {
color_is_valid = true;
}
} else if (color._format == 'rgb' || color._format == 'rgba') {
if (input_value.charAt(input_value.length-1) == ')') {
color_is_valid = true;
}
} else {
color_is_valid = true;
}
}
http://css-tricks.com/rebbeccapurple-663399/
Sass already supports it (not sure about LESS), and (last I saw) patches were already in browser nightly builds and may to close to reaching (if not already in) stable releases.
Hy, I opened a pull-request to distribute your lovely library in cdnjs.com. Just wanted to let you know, so you could add personal information (e.g. your email), contributors, new updates.
Thanks again for sharing
On npm is still 1.0.0 but the current version of tinycolor is 1.1.0.
Disclaimer: I understand that not all of these are necessarily supposed to be documented
The following properties of the static tinyclor
object are missing from the documentation:
The following methods are missing from the instance object:
Lines from the README:
t.toHsv() // {"h":0,"s":1,"v":1}
tinycolor({ h: 0, s: 100, v: 100 });
In the first case, s
and v
have a range [0,1], while in the second they have a range of [0-100]. This makes converting back and forth between HSV a pain in the butt.
...
Excellent stuff, but times move on (!)...
The latest W3C draft on CSS colour has the alpha channel of hex8 defined by the last two characters. So "00" is transparent, "80" is 50%, "FF" is opaque, etc.
http://dev.w3.org/csswg/css-color-4/#hex-notation
tinyColor formats this the other way around, with the alpha channel as the first two characters. I think that was the previous assumption.
So that also means that if we can have tinyColor accepting hex6 as shorthand for hex6, then will it be able to accept hex4 as shorthand for hex8 at some point in the future.
If anyone has a code fix for doing this NOW, you will magically appear on my Christmas Card list.
Thanks.
I would expect it to recognize a range of [0-1] if all numbers are decimal and bound to 0-1, as in older version (this result is from v0.5):
tinycolor('rgb(0.9, 0.0, 0.0)').toRgbString()
"rgb(230, 0, 0)"
But it now seems to only work when there's a 1.0 somewhere (at least after 0.9.14):
tinycolor('rgb(0.9, 0.0, 0.0)').toRgbString()
"rgb(1, 0, 0)"
tinycolor('rgb(1.0, 0.0, 0.0)').toRgbString()
"rgb(255, 0, 0)"
Am I doing it wrong? Should I try to fix it?
What is the license for TinyColor?
var a = tinycolor('hsl(11, 100%, 96%)')
console.log(a.toString()); // "hsl(11, 100%, 96%)"
a.lighten(10);
console.log(a.toString()); // "hsl(0, 0%, 100%)"
I would expect to be
console.log(a.toString()); // "hsl(11, 100%, 100%)"
In your docs you say "Providing 100 will always return white." but I think is a good idea to keep the data anyway, in this case I need to darken and instead of being red again, is grey.
IMO a.lighten(10)
and then a.darken(10)
should reverse to the initial color.
This is more of a feature request / offer
Using tinycolor to compliment a LESS/bootstrap variable configuration page I'm working on, I implemented the spin code that is found in LESS (and SASS as adjust-hue)
tinycolor.spin = function(color,amount) {
var hsl = tinycolor(color).toHsl();
var hue = (hsl.h + amount) % 360;
hsl.h = hue < 0 ? 360 + hue : hue;
return tinycolor(hsl);
}
Is toRgbString but your doc seems to not support it
toRgbString
var color = tinycolor("red");
color.toRgbString(); // "rgb(255, 0, 0)"
please add another example
toRgbString
var color = tinycolor("red").setAlpha(0.5);
color.toRgbString(); // "rgba(255, 0, 0, 0.5)"
I've created a testing page for your awesome code:
http://codepen.io/vsync/pen/LnIhd
it's pretty minimal now. later I might add more methods
Hi there goodfellow Grinstead :). Super stoked to see your lib. I have tested a few others and was leaning toward writing my own, until I found TinyColor. You have saved me tons of time, so thanks!
My goal is to have a lib that provides feature rich color manipulation, color scheme generation and manipulation, and some nice utilities. It looks like you are largely doing this and I'd like to help. I am also curious as to your future plans for TinyColor, what you'd like it to do and not do, your plans for contributors, etc.
I need your library. I am building a Bootstrap customizer called Bootstyle www.usebootstyle.com (project page). Bootstyle aims to be a robust designer tool for developers.
As mentioned, I have been trying to crack the color manipulation and scheme generation nut. These are the libs I've previously reviewed, used, and/or wrapped:
My hope after all this is to plant myself with TinyColor. I really felt at home with the philosophy I see in how TinyColor works. In order to do this, there are a few features I'd love to get merged. I have started a couple just to kick things off but feel I need to discuss larger plans with you before really diving in. In the meantime, I have submitted a PR for brightness methods and am mostly done knocking out #18 spin.
I have lots more I'd like to discuss and hear from you on. What is the best way for us to do that?
Thanks again, really looking forward to your response.
I would like to start by saying that this script is awesome! Thank you very much!
I have implemented a lighten method on a hex color and noticed that after a certain amount, the color is white (#fff), though way before the lighten value makes it to 100. It seems to create white when you pass in an argument that is 50. The same holds true if you use the .darken() method. Is the lighten argument a % value as to how much to lighten the color? Please see below and let me know when you can. I'm using the meteor version of this if that helps.
It seems that a lot of colors other than black will turn to white (#fff) once the lighten argument hits 50.
tinycolor("#f00").lighten(50).toString(); // new hex value for red is white (#fff)
It seems that a lot of colors other than black will turn to black (#000) once the darken argument hits 50.
tinycolor("#f00").darken(50).toString(); // new hex value for red is black (#000)
Black on the other hand seems to take a lighten value all the way up to 100
tinycolor("#000").lighten(100).toString(); // Only when the value is 100 does this new value make it to white (#fff)
After testing a few other colors, it seems inconsistent behavior. See another example below:
tinycolor("#00CC00").lighten(60).toString(); // creates white (#fff)
tinycolor("#00CC00").darken(40).toString(); // creates black (#000)
Any help with this would be awesome. Thank you again! -Chris
Not sure if you are implementing something like this, though want to share:
http://stackoverflow.com/questions/5560248/programmatically-lighten-or-darken-a-hex-color-or-rgb-and-blend-colors
In this code:
if (secondColor) {
var s = tinycolor(secondColor);
secondHex = s.toHex();
secondAlphaHex = Math.round(parseFloat(s.alpha) * 255).toString(16);
}
I'm not sure what it's supposed to be referencing, but secondColor isn't defined there (opts.secondColor?)
It would be useful to be able to get a random (non-ugly) colour like https://github.com/davidmerfield/randomColor
Could you add the ability to preserve the case of the input value when toString()
is called? For (an highly simplistic and silly) example, if I run tinycolor("RGB(39, 39, 39)")
though TinyColor then call toString()
in it without converting it, I get rgb(39, 39, 39)
in return. I'm trying to implement an uppercase-lowercase converter in a program I can't change much of that uses TinyColor, and the always-lowercase return is making it a bit difficult.
Bower uses semver-compatible git tags to determine what version users should download.
To register a new package, there must be a valid manifest JSON in the current working directory, your package must be available at a Git endpoint (e.g., GitHub), and it should use semver Git tags.
In the absence of tags, it uses 'head'. It is generally better to have tags.
I find your library useful thanks you. But for my purposes there is a one little bug with negative hue value, please fix them it's line 784:
var m1 = Number(match[1]);
return { h: ( m1 > 0 ? (m1 > 360 ? m1 - 360 : m1 ) : 360 + m1 ), s: match[2], l: match[3] };
Best Regards,
Vladimir Minkin
ok, this is quite tricky, at first I thought you had a bug in your lighten
function but it appears to be just right to the "standard": http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness
but what I was really looking for was brighten
function (according to the wikipedia page).
given the hex code of black #000000
brighten by 50% should be #7f7f7f
(while lighten
gives back #808080
)
here, this tool: hexcolortool.com uses lighten like this.
the brighten
function is the "standard" lighten
function in many places, for example in sass
(which is why I was confused) and many, many standard libraries (e.g, even the Java library: http://www.java2s.com/Code/Java/2D-Graphics-GUI/Lightensacolorbyagivenamount.htm )
brighten
function is really necessary, and should be explained to differentiate from the current lighten
IMO. thanks.
In having adobe/brackets#9596 reviewed, @redmunds brought out an interesting observation:
(Me)
tinycolor.toString()
actually works as the author intended. It does not ignore the original case, but rather normalizes (to lowercase) it before returning it. There was actually no way to get the original input (it wasn't even stored) until I suggested it and sent a patch in the form oftinycolor.getOriginalInput()
.Yes, but since you added
tinycolor.getOriginalInput()
, I think it changes expectations. I would expect that method to be called something liketoNormalizedString()
.
I am wondering what your thoughts are on this, @bgrins. I know toString()
is a long-standing method and removing/renaming it would be a huge breaking change, but would it be possible to better document the normalization it performs and/or rename getOriginalInput()
to something that better describes it's actions vs toString()
? I mention renaming as it is a very recent edition to TinyColor and probably isn't used much yet.
This is an excellent library! Thank you.
Reading the annotated source code, I see that the readability routines refer to http://www.w3.org/TR/AERT#color-contrast, which in turn is based on the Web Content Accessibility Guidelines Version 1.0.
I have previously incorporated the slightly different WCAG Version 2.0 algorithm (http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef) in a VBA project, and will probably update my downloaded copy of this library to use it. I am unfamiliar with working in the Open Source world, but if someone could give me a brief description of what I would need to do to port that work back (assuming anyone is interested!) I would be happy to contribute.
Looks like some useful new functions got added. Maybe call it 1.2.0?
Hi first of all thanks for this amazing library. I'm using it for the next release of bootstrap-colorpicker and I am trying to guess how to implement or emulate these methods correctly. It would be interesting to have them.
What I do now is convert the original tinycolor object with toHsv()
, and create a new one compounding and passing an object like {h:360,v:100,s:100,a:1}
. I don't know if this is the proper way or there is any better solution. May I loss color information?
The current integration with colorpicker is buggy yet, but If you download the tinycolor
branch you can see it in action.
Thank you again
Is it correct that the complement of white is white and of black is black?
If I for instance do this: tinycolor("#f00").darken()
I get:
undefined is not a function
I have tried to iterate through tinycolor and it seems that it do have the function `darken``
The doc gives this example: tinycolor("#88f0f0f6")
, but it doesn't work:
tinycolor("#88f0f0f6").toRgb() # => {a: 1, b: 0, g: 0, r:0}
Hi All,
The TC readability function returns the contrast ratios of two colours. But even is an alpha colour is passed in the param the ratio returned is only for solid colours.
So passing:
"rgba(0, 102, 161, 0.5)", "fff"
and
"rgb(0, 102, 161)", "fff"
yields the same ratio (6.15).
I come up against designers that use alpha an awful lot, and working out the effective contrast ratio to meet with WCAG is a real pain.
Can TC please be made to support alpha colours? A bit like this one:
https://github.com/LeaVerou/contrast-ratio
If anyone knows how to do this, you will be on my Christmas card list!
Cheers
would be very useful to do something like this:
tinycolor.lighten('#FF0000', 20).desaturate(20); // and so on
so the color manipulation functions should check the this
, and if it's a tinycolor object, then work with it. make all methods a prototype of the object instance, so they will be available. now they are not..
On the demo page at http://bgrins.github.com/TinyColor/ switching between colors "red" and "0f0" don't seem to produce different colors for lighten, darken, saturate, or desaturate. Is something wrong there?
tinycolor.splitcomplements()
"is not a function" error.
This is one of the most confusing / problematic parts of the plugin. People are expecting / looking for 6 char hexes. Allow an override to allow it to be coerced to 3 characters instead of assuming this as the default.
If you create a new tinycolor('#ffffff')
, the result of .toHexString()
is '#fff'
and does not match the input. See this fiddle for an example: http://jsfiddle.net/2va59/3/
This causes problems if you happened to be keying an object by hex value, for example, and depend on the output of TinyColor (via the Spectrum color picker, btw) to look up the correct values.
{"#e55731":{"field":"9","detail":"386"},"#ffffff":{"field":"15","detail":"387"})
The simple solution is to disable this if() statement entirely, but I could see an argument for an alternative .toFullHexString()
method or an passing an optional argument (in pseudo-code) along the lines of .toHexString(bool shortenHexIfPossible = false)
as well.
I would like to copy or clone a color so any changes will not mess the source.
Your values for h in hsv is 0-360 in range.
h = bound01(h, 360) * 6;
In your main doc you say
All commas, percentages, parenthesis are optional, and most input allow either 0-1, 0%-100%, or 0-n (where n is either 100, 255, or 360 depending on the value).
But right below you say:
HSL and HSV both require either 0%-100% or 0-1.
It should be
HSL and HSV both require either 0%-100% or 0-1. H can have values between 0-1 or 0-360.
I very much love this little package, however for my purposes I need to modify a lot of alpha values for canvas rendering. While the tinycolor object has an alpha variable, it's not used really in the code, and I can't figure out any way to modify an existing color's alpha without casting into an RGB object, setting .a, and sending back into a tinycolor, or modifying the to*String results. Am I missing something?
The various transformation functions such as lighten, darken, saturate, and desaturate accept a second argument for the amount of change. If that argument is not provided, a default of 10% is used, e.g. for darken . The boolean test to see if that argument is present checks whether the amount argument is "falsy."
While a missing argument is falsy, so is 0, which I think should be a valid value to pass into this function. In particular, in iteration loops where gradients are being calculated over a collection of elements on a page, the color of the first item in the gradient will differ from the gradient start by 0, i.e. it will be identical to the gradient start. A natural way to code this might be (using underscore.js), something like:
var gradientStartColor = ....;
var darkeningAmount = ....;
var colors = _.map(_.range(numElements), function(elemNum) {
return tinycolor.darken(gradientStartColor, elemNum * darkeningAmount);
});
However, on the first iteration, elemNum will be 0, which means that the second argument to darken will be (intentionally) 0. This doesn't result in darken being the expected no-op on that iteration, however, since the default of 10% will be selected instead by darken because 0 is falsy.
Can the argument checks / defaults in the transformation functions account for the case of passing 0? I think that's a pretty natural way to code iterative transformations without special casing.
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.