web-dev-qa-db-ja.com

特定の色を生成するために必要な色相回転を計算する方法は?

Divの背景として使用している白い画像があり、テーマのメインカラーに合わせて色を付けたいと思います。私ができることを知っています:

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

そして_hue-rotate_を循環して色を見つけますが、この値を事前に計算することは可能ですか?指定された16進値が非常に暗い場合、invert(%)フィルターも含める必要があると思います。

16進数の_#689d94_が与えられた場合、白い背景画像を同じ色に変換するために必要な_hue-rotate_とinvertの値を計算するには何をする必要がありますか?

編集

以下は、divのスニペットで、白い背景画像が緑色にフィルターされています。ここでの秘、は、画像だけでなく、フィルタリングされるのはdiv全体であるということです。 divにテキストを入力すると、テキストの色も緑色に変わります。

_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>_
56

この場合のキーは、初期色を定義することです。白でも黒でも、グレースケールでも技術的には実際の色です-飽和させたり回転させたりすることはできません。何とか「色付け」する必要があり、セピア色のフィルターは、何らかの形の色付けを行う唯一のフィルターです。

画像が純粋な100%赤である場合は簡単です。次に、ターゲットの度合いを直接追加し、ターゲットのHSLを使用して彩度と明度を調整します。白色の開始点の場合、最初のステップは中間色を変換および定義して、後で飽和色と回転を可能にすることです。

最初に白い画像を暗くし、セピアを適用して、「ベース」カラーを取得します。

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

これにより、およそ次のRGBカラー値が生成されます。

rgb(178, 160, 128)

ステップ2は、 HSLカラースペースに変換する です。

hsl(38, 24.5%, 60%);

ベースカラー結果

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>

ベースカラーをターゲットカラーに変換する

これらの2つの最初のステップは静的であり、ターゲット調整を見つける必要があるたびに結果が再利用されます(sepiaの実際の値は- SVGフィルター仕様 )。

次に、ターゲットカラーを取得するためにこのベースカラーに適用する必要があるものを計算する必要があります。まず、質問にある#689d94などのターゲットカラーをHSLに変換します。

hsl(170, 21.3%, 51.2%);

次に、それらの差を計算する必要があります。色相は、ターゲットからベースを単純に差し引くことで計算されます。彩度と明度についても同じですが、ベース値の100%を想定しているため、100%から結果を減算して、累積値の差分を得る必要があります。

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%)

それらの値を既存のフィルターに追加してフィルター文字列に変換し、divに設定します。

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

そして、それを設定するには、おそらくfilterとdivElementが既に宣言されていると仮定して、次のようなことをするでしょう:

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

RGBは整数として表され、HSLは浮動小数点であるため、丸めエラーが発生する可能性が高いことに注意してください。そのため、実際の結果は正確ではないかもしれませんが、かなり近いはずです。

ライブ例

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>

実行可能な代替オプションは次のとおりです。

  • 既に設定されている色でSVGを事前定義します。
  • JavaScriptでHSL/RGBを直接操作し、フィルターを使用するのではなく、形状の色でSVGツリーを直接変更します。特に、多くのフィルターがこのようにチェーンされ、さらにそれらがページの主要な部分である場合、フィルターはパフォーマンスの面で高価です。すべてのブラウザでサポートされていません。
72
user1693593

受け入れられた答えは間違っています。色相回転では彩度や明るさが保存されないため、正しい値を得るにはクレイジーな計算が必要です。はるかに簡単な方法-正しい結果が得られる-は、SVGフィルターを参照するCSSフィルターを実行することです。 SVGフィルターのfeColorMatrixプリミティブを使用すると、色を直接選択できます。あなたの色#424242を取ります-各色の16進値を#FF(.257)で除算し、それらをカラーマトリックスの最初の3行の5列目に配置します。そのようです:

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>
16
Michael Mullany

Svgが使用されている場合...

いくつかのテキストエディターでsvgファイルをコピーして、htmlファイルに貼り付け、必要に応じてパスの色を変更できます。

以下のコード例では...センターリングのパスの色を変更しました。お役に立てれば..

        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>

背景画像用

        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>
0
Azi