How to calculate required hue-rotate to generate specific colour?
The only way to get the exact match is to use an SVG color matrix filter.
For RGB color #689d94
, which is rgb(104, 157, 148)
, divide each primary color's value by 255:
Put these weights into the SVG <filter>
matrix (5ᵗʰ column in the first 3 rows):
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="689d94" color-interpolation-filters="sRGB">
<feColorMatrix type="matrix"
values="0 0 0 0 0.40784
0 0 0 0 0.61569
0 0 0 0 0.58039
0 0 0 1 0"/>
</filter>
</defs>
</svg>
The <filter>
has to have id (I used the RGB hex code 689d94
), so we can use it as a reference.
Since some browsers (e.g. Firefox) don't see/use the SVG filter if the display
property of the SVG element is set to none
, and having this SVG element in HTML code would inconveniently occupy some space, the best way is to convert this SVG into a pure inline CSS filter.
To get an inline filter value, take the above listed SVG code, transform it into a single line by remove line breaks and unnecessary spaces, then prepend url('data:image/svg+xml,
and append the previously mentioned id as #689d94')
:
div {
background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="71.063" height="60.938"><path d="M33.938 0l-16.97 19.906H1.625L0 21.781v8.781l1.25 1.407h4.781l5.875 28.969h46.969l6.188-28.97h4.687l1.313-1.343v-8.844L69.5 19.906H54.656L37.312 0h-3.375zm1.593 7.594l9.594 12.312H26.25l9.281-12.312zm-20.281 16s-.405 2.9 1.594 3.844c1.998.942 4.406.03 4.406.03-1.666 2.763-3.638 3.551-5.469 2.688-3.312-1.562-.531-6.562-.531-6.562zm41.188.031s2.749 4.969-.563 6.531c-2.487 1.162-4.848-1.541-5.438-2.656 0 0 2.377.88 4.375-.063 1.999-.942 1.625-3.812 1.625-3.812z"/></svg>') no-repeat; // optimized from http://richard.parnaby-king.co.uk/basket.svg
background-size: 100%;
display: inline-block;
height: 5em;
width: 5em;
}
#colored {
filter: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><defs><filter id="689d94" color-interpolation-filters="sRGB"><feColorMatrix type="matrix" values="0 0 0 0 0.40784 0 0 0 0 0.61569 0 0 0 0 0.58039 0 0 0 1 0"/></filter></defs></svg>#689d94');
margin-left: 20px;
}
<!-- No <svg> in HTML; pure CSS -->
<div></div><div id="colored"></div>
<p style="background: #689d94"></p>
Why is hue-rotate(180deg) not its own inverse?
hue-rotate(X) hue-rotate(X)
is not equivalent to hue-rotate(X+X)
as shown below:
.square {
height: 3rem;
padding: 1rem;
background: linear-gradient( 90deg, rgba(255, 0, 0, 1) 0%, rgba(255, 154, 0, 1) 10%, rgba(208, 222, 33, 1) 20%, rgba(79, 220, 74, 1) 30%, rgba(63, 218, 216, 1) 40%, rgba(47, 201, 226, 1) 50%, rgba(28, 127, 238, 1) 60%, rgba(95, 21, 242, 1) 70%, rgba(186, 12, 248, 1) 80%, rgba(251, 7, 217, 1) 90%, rgba(255, 0, 0, 1) 100%);
font-family: monospace;
font-weight: bold;
color: white;
}
.single-invert {
filter: hue-rotate(360deg);
}
.double-invert {
filter: hue-rotate(180deg) hue-rotate(180deg);
}
<div class="square">filter: none</div>
<div class="square single-invert">filter: hue-rotate(360deg) </div>
<div class="square double-invert">filter: hue-rotate(180deg) hue-rotate(180deg)</div>
Shift hue of an RGB Color
Edit per comment changed "are all" to "can be linearly approximated by".
Edit 2 adding offsets.
Essentially, the steps you want are
RBG->HSV->Update hue->RGB
Since these can be approximated by linear matrix transforms (i.e. they are associative), you can perform it in a single step without any nasty conversion or loss of precision. You just multiple the transform matrices with each other, and use that to transform your colors.
There's a quick step by step here http://beesbuzz.biz/code/hsv_color_transforms.php
Here's the C++ code (With the saturation and value transforms removed):
Color TransformH(
const Color &in, // color to transform
float H
)
{
float U = cos(H*M_PI/180);
float W = sin(H*M_PI/180);
Color ret;
ret.r = (.299+.701*U+.168*W)*in.r
+ (.587-.587*U+.330*W)*in.g
+ (.114-.114*U-.497*W)*in.b;
ret.g = (.299-.299*U-.328*W)*in.r
+ (.587+.413*U+.035*W)*in.g
+ (.114-.114*U+.292*W)*in.b;
ret.b = (.299-.3*U+1.25*W)*in.r
+ (.587-.588*U-1.05*W)*in.g
+ (.114+.886*U-.203*W)*in.b;
return ret;
}
Related Topics
HTML - How to Do a Confirmation Popup to a Submit Button and Then Send the Request
How to Properly Display German Characters in HTML
How to Make a Sticky Footer Using Flexbox in Ie11
Css: Why Background-Color Breaks/Removes the Box-Shadow
Why Do Overflow Clear Margin of P-Tag
Css: How to Get Browser Scrollbar Width? (For :Hover {Overflow: Auto} Nice Margins)
Move One Image Inside Other Image
Google Chrome Cannot Submit Form with Display:None
Scope External CSS File for Div(No CSS File Should Link Only )
How to Have Images in Line with Text in CSS
Float Puts Submit Button Outside of Div
CSS White-Space: Pre Not Working as Expected
How to Make Triangle Shape in Before a Div in Pure CSS
How to Underline All Rows in Textarea
Internet Explorer 9 Drag and Drop (Dnd)
How to Save the Content in Uiwebview for Faster Loading on Next Launch