How to calculate the necessary hue-rotation to generate a specific color?

I have a white image that I use as the background for the div, and I would like the color to match the main colors of the themes. I know that I can:

filter: sepia() saturate(10000%) hue-rotate(30deg); 

and go through hue-rotate to find the color, but is it possible to calculate this value in advance? Given that the specified hexadecimal value is rather dark, I suppose that I will need to enable the invert(%) filter invert(%) .

Given the hexadecimal value #689d94 , what math do you need to calculate the desired hue-rotate and invert value to convert my white background image to one color?

Edit

Shown here is a fragment of a div with a white background that is filtered in green. The trick here is that the entire div is filtered, not just the image. If I entered the text in a div , the text color would also turn green.

 div { background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat scroll 0 0 transparent; background-size:5em; width:5em; height:5em; -webkit-filter: invert(25%) sepia() saturate(100000%) hue-rotate(174deg); filter: invert(25%) sepia() saturate(100000%) hue-rotate(174deg); } 
 <div> </div> 
+29
css css-filters
Mar 13 '15 at 16:12
source share
3 answers

The key in this case is to determine the initial color. White or black or any gray color is technically the actual color - you cannot saturate or rotate it. You will have to β€œcolorize” it somehow, and the sepia filter is the only filter that performs some form of coloring.

It would be easier if your image was 100% pure red. Then you can simply add the target degree directly and adjust the saturation and lightness using HSL for the purpose. For the starting point of white, the first step is to convert and define an intermediate color so that we can saturate and rotate it later.

Allows you to first darken the white image and apply sepia to get the "base" color that we can work with:

 filter: brightness(50%) sepia(1); 

This will produce an RGB color value of approximately:

 rgb(178, 160, 128) 

Step two is to convert it to the HSL color space , which gives us:

 hsl(38, 24.5%, 60%); 

Base color result

 div { background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat; background-size:5em; width:5em; height:5em; -webkit-filter: brightness(50%) sepia(1); filter: brightness(50%) sepia(1); } 
 <div></div> 

Convert base color to target color

These first two steps are static, and its result will be reused every time we need to find the target setting (the actual sepia value is defined in the SVG Filter Specification ).

Now we need to calculate what we need to apply to this base color to get the target color. First convert the target color, for example # 689d94, as indicated in the question, to HSL:

 hsl(170, 21.3%, 51.2%); 

Then we must calculate the difference between the two. Hue is calculated by simply subtracting the base from the target. The same is for Saturation and Lightness, but since we accept 100% of the base value, we need to subtract the result from 100% in order to finally get diff for the accumulated values:

 H: 170 - 38 -> 132Β° S: 100 + (24.5 - 21.3) -> 103.2% (relative to base 100% = 3.2%) L: 100 + (51.2 - 60.0) -> 91.2% (relative to base 100% = -8.8%) 

Convert these values ​​to a filter string by adding it to an existing filter, then set it to a div:

 /* ------ base color ------ ------- new target -------------------------------*/ filter: brightness(50%) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%); 

And to set it, you are likely to do something like this, assuming the filter and divElement are already declared:

 ... filter = "brightness(0.5) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%)"; divElement.style.filter = filter; divElement.style.webkitFilter = filter; 

Please note that probable rounding errors, since RGB is represented as an integer and HSL is a floating point, so the actual result may not be accurate, but it should be pretty close.

Living example

 div { background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat; background-size:5em; width:5em; height:5em; -webkit-filter: brightness(50%) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%); filter: brightness(50%) sepia(1) hue-rotate(132deg) saturate(103.2%) brightness(91.2%); } 
 <div></div> <span style="font:14px sans-serif;padding:7px;color:#fff;background:#689d94"> Target color</span> 

Possible alternatives:

  • Predefine SVG with color already set.
  • Work with HSL / RGB directly in JavaScript and modify the SVG tree with color directly for the form, not with filters. Filters are expensive features, especially if many of them are related to each other, and they are also the dominant part of the page. They are not supported in all browsers.
+38
Apr 30 '15 at 3:21
source share
β€” -

The accepted answer is incorrect. Hue-rotate does not preserve saturation or brightness, and you need to do crazy math to come up with the right values. An easier way β€” which will produce the correct result β€” is to make a CSS filter that references the SVG filter. The feColorMatrix primitive in SVG filters allows you to select a color directly - for example, like this. Take your color # 424242 - divide each hexadecimal color value by #FF (.257) and put them in the fifth column, the first three rows of your color matrix. For example:

 div { background:url(http://richard.parnaby-king.co.uk/basket.svg) no-repeat scroll 0 0 transparent; background-size:5em; width:5em; height:5em; -webkit-filter: url(#colorize); filter: url(#colorize); } 
 <div> </div> <svg> <defs> <filter id="colorize" color-interpolation-filters="sRGB"> <feColorMatrix type="matrix" values="0 0 0 0 .257 0 0 0 0 .257 0 0 0 0 .257 0 0 0 1 0"/> /filter> </defs> </svg> 
+2
Oct 03 '17 at 2:22 on
source share

If svg is used then ...

You can open svg files with some text editor, copy and paste into the html file, and then change the path color as needed.

In the code example below ... I just changed the color of the path of the center ring. Hope this helps.

  var imgg =document.getElementById("path"); imgg.style="fill:#424242"; 
 <html> <body> <?xml version="1.0" encoding="iso-8859-1"?> <!-- Generator: Adobe Illustrator 17.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg id="imgg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 296.838 296.838" style="enable-background:new 0 0 296.838 296.838;" xml:space="preserve" width="512px" height="512px"> <g> <path d="M58.733,64.566L41.763,47.596C14.832,74.526,0,110.333,0,148.419s14.832,73.893,41.763,100.823l16.971-16.971 C36.335,209.874,24,180.095,24,148.419S36.335,86.964,58.733,64.566z" fill="#91DC5A"/> <path d="M82.137,81.969c-17.75,17.748-27.525,41.348-27.525,66.45s9.775,48.702,27.525,66.45l16.971-16.971 c-13.218-13.216-20.496-30.788-20.496-49.479s7.278-36.264,20.496-49.48L82.137,81.969z" fill="#91DC5A"/> <path d="M255.075,47.596l-16.971,16.971c22.399,22.397,34.733,52.177,34.733,83.853s-12.335,61.455-34.733,83.852l16.971,16.971 c26.931-26.931,41.763-62.737,41.763-100.823S282.006,74.526,255.075,47.596z" fill="#91DC5A"/> <path d="M214.701,81.969L197.73,98.939c13.218,13.216,20.496,30.788,20.496,49.48s-7.278,36.264-20.496,49.479l16.971,16.971 c17.75-17.748,27.525-41.348,27.525-66.45S232.451,99.717,214.701,81.969z" fill="#91DC5A"/> <path id="path" d="M148.586,114.789c-8.607,0-17.212,3.284-23.78,9.851c-13.131,13.133-13.131,34.424,0,47.559 c6.568,6.566,15.174,9.851,23.78,9.851c8.606,0,17.212-3.284,23.779-9.851c13.131-13.135,13.131-34.426,0-47.559 C165.798,118.073,157.192,114.789,148.586,114.789z M155.395,155.228c-2.454,2.454-5.319,2.821-6.809,2.821 c-1.489,0-4.356-0.367-6.808-2.818c-3.755-3.756-3.755-9.867-0.003-13.619c2.455-2.455,5.321-2.822,6.811-2.822 c1.489,0,4.354,0.367,6.808,2.82C159.147,145.363,159.147,151.475,155.395,155.228z" fill="#91DC5A"/> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> <g> </g> </svg> </body> </html> 

For background image

  var myimg='url(\'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 296.838 296.838" style="enable-background:new 0 0 296.838 296.838;" xml:space="preserve" width="512px" height="512px"><g><path d="M58.733,64.566L41.763,47.596C14.832,74.526,0,110.333,0,148.419s14.832,73.893,41.763,100.823l16.971-16.971 C36.335,209.874,24,180.095,24,148.419S36.335,86.964,58.733,64.566z" fill="#91DC5A"/><path d="M82.137,81.969c-17.75,17.748-27.525,41.348-27.525,66.45s9.775,48.702,27.525,66.45l16.971-16.971 c-13.218-13.216-20.496-30.788-20.496-49.479s7.278-36.264,20.496-49.48L82.137,81.969z" fill="#91DC5A"/><path d="M255.075,47.596l-16.971,16.971c22.399,22.397,34.733,52.177,34.733,83.853s-12.335,61.455-34.733,83.852l16.971,16.971 c26.931-26.931,41.763-62.737,41.763-100.823S282.006,74.526,255.075,47.596z" fill="#91DC5A"/><path d="M214.701,81.969L197.73,98.939c13.218,13.216,20.496,30.788,20.496,49.48s-7.278,36.264-20.496,49.479l16.971,16.971 c17.75-17.748,27.525-41.348,27.525-66.45S232.451,99.717,214.701,81.969z" fill="#91DC5A"/><path d="M148.586,114.789c-8.607,0-17.212,3.284-23.78,9.851c-13.131,13.133-13.131,34.424,0,47.559 c6.568,6.566,15.174,9.851,23.78,9.851c8.606,0,17.212-3.284,23.779-9.851c13.131-13.135,13.131-34.426,0-47.559 C165.798,118.073,157.192,114.789,148.586,114.789z M155.395,155.228c-2.454,2.454-5.319,2.821-6.809,2.821 c-1.489,0-4.356-0.367-6.808-2.818c-3.755-3.756-3.755-9.867-0.003-13.619c2.455-2.455,5.321-2.822,6.811-2.822 c1.489,0,4.354,0.367,6.808,2.82C159.147,145.363,159.147,151.475,155.395,155.228z" fill="#91DC5A"/></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g><g></g></svg> \')'; document.getElementById("mydiv").style.backgroundImage =myimg ; //changing color according to theme .. new theme color :#424242 myimg=myimg.replace(/#91DC5A/g,"#424242"); document.getElementById("mydiv").style.backgroundImage =myimg ; 
  div { background-size:5em; width:5em; height:5em; } 
 <html> <body> <div id="mydiv"></div> <span style="font:14px sans-serif;padding:7px;color:#fff;background:#689d94"> Target color</span> </body> </html> 
-one
Jun 28 '17 at 13:30
source share



All Articles