Disons que j'ai une couleur d'arrière-plan avec un "ruban" qui passe dessus dans une autre couleur unie. Maintenant, je veux que le ruban soit partiellement transparent pour laisser certains détails se fondre, tout en gardant le ruban de la «même couleur» sur l'arrière-plan.
Existe-t-il un moyen de déterminer (facilement), pour une opacité / alpha donnée <100% de la couleur du ruban, quelles valeurs RVB il devrait avoir pour être identique à sa couleur avec une opacité de 100% sur l'arrière-plan?
Voici une image. Le fond est rgb(72, 28, 97)
, ruban rgb(45, 34, 70)
. Je veux un rgba(r, g, b, a)
pour le ruban afin qu'il apparaisse identique à cette couleur unie.
Réponses:
La fusion des couleurs n'est qu'une interpolation linéaire par canal, n'est-ce pas? Le calcul est donc assez simple. Si vous avez RGBA1 sur RGB2, le résultat visuel effectif RGB3 sera:
… Où le canal alpha est compris entre 0,0 et 1,0.
Vérification de l'intégrité: si l'alpha est 0, RGB3 est-il identique à RGB2? Oui. Si l'alpha est 1, RGB3 est-il identique à RGB1? Oui.
Si vous avez verrouillé uniquement la couleur d'arrière-plan et la couleur finale, il existe un grand nombre de couleurs RGBA (infinies, dans un espace à virgule flottante) qui pourraient satisfaire les exigences. Vous devez donc choisir soit la couleur de la barre, soit le niveau d'opacité souhaité, et découvrir la valeur de l'autre.
Choisir la couleur basée sur Alpha
Si vous connaissez RGB3 (la couleur finale souhaitée), RGB2 (la couleur d'arrière-plan) et A1 (combien d'opacité vous voulez), et que vous recherchez simplement RGB1, nous pouvons réorganiser les équations ainsi:
Certaines combinaisons de couleurs sont théoriquement possibles, mais impossibles compte tenu de la plage RGBA standard. Par exemple, si l'arrière-plan est d'un noir pur, que la couleur perçue souhaitée est le blanc pur et que l'alpha souhaité est de 1%, vous aurez besoin de:
r1 = g1 = b1 = 255/0.01 = 25500
… Un blanc ultra-brillant 100 fois plus brillant que tout autre disponible.
Choisir l'alpha en fonction des couleurs
Si vous connaissez RGB3 (la couleur finale souhaitée), RGB2 (la couleur d'arrière-plan) et RGB1 (la couleur dont vous souhaitez faire varier l'opacité), et que vous recherchez simplement A1, nous pouvons réorganiser le équations ainsi:
Si ceux-ci donnent des valeurs différentes, vous ne pouvez pas le faire correspondre exactement, mais vous pouvez faire la moyenne des alphas pour vous rapprocher le plus possible. Par exemple, il n'y a aucune opacité dans le monde qui vous permettra de mettre du vert sur du rouge pour obtenir du bleu.
la source
r1
,g1
etb1
également inconnus?J'ai fait un mixin MOINS en utilisant la réponse de Phrogz. vous entrez:
Voici le code:
.bg_alpha_calc (@desired_colour, @desired_alpha, @background_colour: white) { @r3: red(@desired_colour); @g3: green(@desired_colour); @b3: blue(@desired_colour); @r2: red(@background_colour); @g2: green(@background_colour); @b2: blue(@background_colour); // r1 = (r3 - r2 + r2 * a1) / a1 @r1: ( @r3 - @r2 + (@r2 * @desired_alpha) ) / @desired_alpha; @g1: ( @g3 - @g2 + (@g2 * @desired_alpha) ) / @desired_alpha; @b1: ( @b3 - @b2 + (@b2 * @desired_alpha) ) / @desired_alpha; background-color: @desired_colour; background-color: rgba(@r1, @g1, @b1, @desired_alpha); }
Utilisation comme ceci:
@mycolour: #abc; @another_colour: blue; .box_overlay { // example: .bg_alpha_calc (@mycolour, 0.97, @another_colour); // or (for white bg) just: .bg_alpha_calc (@mycolour, 0.97); }
Évidemment, cela ne fonctionne pas pour des combinaisons impossibles (comme mentionné par Phrogz), cela signifie que seuls des niveaux de transparence légers sont pris en charge. Voyez comment vous allez avec.
la source
Merci à Phrogz 's et Ephemer grandes réponses de, voici une fonction SASS qui automagiquement calcule la meilleure couleur RGBA équivalent.
Vous l'appelez avec la couleur souhaitée et l'arrière-plan existant, et il calculera la meilleure couleur RVBA équivalente (c'est-à-dire la plus transparente) qui donne le résultat souhaité à ± 1/256 de chaque composant RVB (en raison d'erreurs d'arrondi):
@function alphaize($desired-color, $background-color) { $r1: red($background-color); $g1: green($background-color); $b1: blue($background-color); $r2: red($desired-color); $g2: green($desired-color); $b2: blue($desired-color); $alpha: 0; $r: -1; $g: -1; $b: -1; @while $alpha < 1 and ($r < 0 or $g < 0 or $b < 0 or $r > 255 or $g > 255 or $b > 255) { $alpha: $alpha + 1/256; $inv: 1 / $alpha; $r: $r2 * $inv + $r1 * (1 - $inv); $g: $g2 * $inv + $g1 * (1 - $inv); $b: $b2 * $inv + $b1 * (1 - $inv); } @return rgba($r, $g, $b, $alpha); }
Je viens de le tester contre un certain nombre de combinaisons (tous les thèmes Bootswatch) et cela fonctionne un régal, à la fois pour les résultats sombre sur lumière et clair sur sombre.
PS: Si vous avez besoin d'une précision supérieure à ± 1/256 dans la couleur résultante, vous devrez savoir quel type d'algorithme d'arrondi les navigateurs appliquent lors du mélange de couleurs rgba (je ne sais pas si cela est normalisé ou non) et ajouter un condition à l'existant
@while
, de sorte qu'il continue d'augmenter$alpha
jusqu'à ce qu'il atteigne la précision souhaitée.la source
transparentify()
: stylus-lang.com/docs/bifs.html#transparentifytop-bottom-alpha ... que j'ai découvert après l'avoir porté manuellement sur Stylus ...De la réponse de @Phrogz:
r3 = r2 + (r1-r2)*a1 g3 = g2 + (g1-g2)*a1 b3 = b2 + (b1-b2)*a1
Donc:
r3 - r2 = (r1-r2)*a1 g3 - g2 = (g1-g2)*a1 b3 - b2 = (b1-b2)*a1
Donc:
r1 = (r3 - r2) / a1 + r2 g1 = (g3 - g2) / a1 + g2 b1 = (b3 - b2) / a1 + b2
Notez que vous pouvez choisir une valeur
a1
, et cela trouvera les valeurs de correspondantsr1
,g1
etb1
nécessaires. Par exemple, choisir un alpha de 1 vous indique que vous avez besoin de RGB1 = RGB3, mais choisir un alpha de 0 ne donne aucune solution (évidemment).la source
La solution la plus pratique que j'ai trouvée jusqu'à présent: il suffit de mesurer la couleur résultante avec un outil de sélection de couleur, puis d'utiliser la couleur mesurée pour la superposition. Cette méthode donne une correspondance de couleur parfaite.
J'ai essayé d'utiliser différents mixins mais en raison d'une erreur d'arrondi, j'ai toujours pu voir la différence à l'œil nu
la source
Pour développer la réponse de @ Tobia et permettre de spécifier l'opacité plus comme transparentify:
@function rgbaMorph($desired-color, $background-color: rgb(255,255,255), $desired-alpha: 0) { $r1: red($desired-color); $g1: green($desired-color); $b1: blue($desired-color); $r2: red($background-color); $g2: green($background-color); $b2: blue($background-color); $r: -1; $g: -1; $b: -1; @if ($desired-alpha != 0) { $r: ( $r1 - $r2 + ($r2 * $desired-alpha) ) / $desired-alpha; $g: ( $g1 - $g2 + ($g2 * $desired-alpha) ) / $desired-alpha; $b: ( $b1 - $b2 + ($b2 * $desired-alpha) ) / $desired-alpha; } @if (($desired-alpha == 0) or ($r < 0 or $g < 0 or $b < 0 or $r > 255 or $g > 255 or $b > 255)) { //if alpha not attainable, this will find lowest alpha that is $alpha: $desired-alpha; @while $alpha < 1 and ($r < 0 or $g < 0 or $b < 0 or $r > 255 or $g > 255 or $b > 255) { $alpha: $alpha + 1/256; $inv: 1 / $alpha; $r: $r1 * $inv + $r2 * (1 - $inv); $g: $g1 * $inv + $g2 * (1 - $inv); $b: $b1 * $inv + $b2 * (1 - $inv); } @debug "Color not attainable at opacity using alpha: " $alpha " instead of: " $desired-alpha; $desired-alpha: $alpha; } @return rgba($r, $g, $b, $desired-alpha); }
la source