Comment calculer la tonalité requise pour générer une couleur spécifique?

j'ai une image blanche que j'utilise comme arrière-plan pour une div, Et je voudrais colorer pour correspondre aux thèmes couleur principale. Je suis conscient que je peux faire:

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

et en cycle hue-rotate pour trouver une couleur, mais est-il possible de calculer cette valeur à l'avance? Étant donné que la valeur hex spécifiée est assez sombre, j'imagine que je vais avoir besoin d'inclure le invert(%) filtre.

Donné une valeur hexadécimale #689d94 qu'est-ce que je dois faire en maths pour calculer la valeur désirée hue-rotate et invert valeur pour convertir mon image de fond blanc dans la même couleur?

Modifier

Voici un extrait d'un div avec une image de fond blanche filtrée en vert. Le truc ici, c'est l'ensemble de l' div filtrée, non seulement l'image. Si j'étais à entrer du texte dans le div la couleur du texte deviendrait aussi verte.

css lang-css prettyprint-override">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>
41
demandé sur Richard Parnaby-King 2015-03-13 19:12:10

3 réponses

La clé dans ce cas, c'est définir une couleur initiale. Blanc ou noir ou n'importe quelle échelle de gris est techniquement une couleur réelle-vous ne pouvez pas saturer ou tourner. Vous devrez "coloriser" en quelque sorte, et le filtre sépia est le seul filtre qui font une certaine forme de colorisation.

ce serait plus facile si votre image était 100% rouge. Ensuite, vous pouvez juste ajouter le degré cible directement et ajuster la saturation et la légèreté en utilisant HSL pour cible. Pour une couleur blanche Point de départ de la première étape est de convertir et de définir une couleur intermédiaire de sorte que nous pouvons saturer et tourner plus tard.

assombrissons d'abord l'image blanche et appliquons la sépia pour obtenir une couleur" de base " avec laquelle nous pouvons travailler:

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

cela produira une valeur de couleur RVB d'environ:

rgb(178, 160, 128)

la deuxième étape consiste à convertissez cela en HSL color-space ce qui nous donne:

hsl(38, 24.5%, 60%);

couleur de Base résultat

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>

conversion de la couleur de base en couleur cible

Ces deux premières étapes sont statiques et son résultat sera réutilisé à chaque fois que nous avons besoin de trouver un ajustement cible (la valeur réelle de sépia est défini à spécification des filtres SVG).

maintenant nous devons calculer ce que nous devons appliquer à cette couleur de base pour obtenir la couleur cible. Première conversion couleur cible, par exemple #689d94 comme indiqué dans la question, à HSL:

hsl(170, 21.3%, 51.2%);

Ensuite, nous devons calculer la différence entre ceux-ci. La teinte est calculée en soustrayant simplement la base de la cible. La même chose pour la Saturation et la légèreté, mais comme nous supposons 100% de la valeur de base, nous devons soustraire le résultat de 100% pour finir avec une diff pour les valeurs accumulées:

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

convertissez ces valeurs en chaîne de filtrage en les ajoutant au filtre existant, puis réglez-les sur le div:

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

Et pour le régler, vous devriez probablement faire quelque chose comme ceci en supposant que le filtre et divElement sont déjà déclarés:

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

notez qu'il y a probablement des erreurs d'arrondi car RGB est représenté comme entier, alors que HSL est un point flottant, donc le résultat réel peut ne pas être exact, mais il devrait être assez proche.

Live exemple

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>

options alternatives viables sont:

  • SVG prédéfini avec la couleur déjà définie.
  • travailler avec HSL/RGB directement en JavaScript et modifier L'arborescence SVG avec la couleur directement pour la forme plutôt qu'en utilisant des filtres. Les filtres sont coûteux de performance sage, surtout si beaucoup sont enchaînés comme ici et ils sont en outre une partie dominante d'une page. Ils ne sont ni pris en charge dans tous les navigateurs.
49
répondu epistemex 2017-05-23 10:31:35

la réponse acceptée est fausse. Hue-rotate ne conserve pas la saturation ou la luminosité et vous devez faire des maths folles pour venir avec les valeurs correctes. La manière la plus simple - qui aboutira à un résultat correct - est de faire un filtre CSS qui renvoie à un filtre SVG. La primitive feColorMatrix dans les filtres SVG vous permet de choisir une couleur directement - comme ainsi. Prenez votre couleur #424242 - divisez la valeur hexadécimale de chaque couleur par #FF (.257) et les mettre dans la cinquième colonne, les trois premières lignes de votre couleur matrice. Comme ceci:

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>
7
répondu Michael Mullany 2017-10-03 02:22:27

si svg est utilisé alors ...

vous pouvez ouvrir des fichiers svg avec un éditeur de texte Copier et coller dans le fichier html puis changer la couleur du chemin selon les besoins.

dans le code d'exemple ci-dessous... Je viens de changer la couleur de l'anneau central. Espérons que cette aide..

        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>

Pour l'image de fond

        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
répondu Azi 2017-06-28 17:52:03