2013-02-02 7 views
6

Ho creato un'ombra esterna in SVG utilizzando SourceAlpha per l'ombra, quindi il suo nero semplice. Usando feColorMatrix ho ridotto un po 'l'opacità, ma ancora non sembrava come volevo: voglio che il colore dell'ombra corrisponda a un valore di colore specifico. Così ho dato un'occhiata più approfondita allo feColorMatrix.Corrispondenza di un colore in SVG con feColorMatrix

Ora non utilizzo SourceAlpha come origine per l'ombra, ma SourceGraphic. Come il mio immagine vettoriale è bianco normale aka rgba(255, 255, 255, 1), posso calcolare il colore dell'ombra così:

<feColorMatrix in="the-shadow" result="color-out" type="matrix" 
       values="0.0157 0  0  0 0 
         0  0.3059 0  0 0 
         0  0  0.7765 0 0 
         0  0  0  1 0 "/> 

Il risultato dovrebbe essere l'ombra blu scuro aka rgba(4, 78, 198, 1).

In realtà questo funziona e credo che i calcoli siano tutti corretti, ma quando si crea un'ombra con CSS3 usando lo stesso colore, c'è una differenza notevole: il filtro SVG sembra rendere il colore un po 'troppo leggero. C'è un modo per risolverlo?

risposta

9

feColorMatrix come la maggior parte dei filtri opera nello spazio colore linearRGB. Se si desidera un colore sRGB, provare a impostare color-interpolation-filters = "sRGB" come attributo su feColorMatrix.

<svg width="100%" xmlns:xlink="http://www.w3.org/1999/xlink" 
 
    
 
    viewBox="0 0 640 480" height="100%" 
 
    xmlns="http://www.w3.org/2000/svg"> 
 
    
 
    <filter id="cm"> 
 
    
 
    <feColorMatrix in="SourceGraphic" type="matrix" 
 
        values="0.0157 0  0  0 0 
 
          0  0.3059 0  0 0 
 
          0  0  0.7765 0 0 
 
          0  0  0  1 0 "/> 
 
    
 
    </filter> 
 
    
 
    <filter id="cmRGB"> 
 
    
 
    <feColorMatrix color-interpolation-filters="sRGB" in="SourceGraphic" type="matrix" 
 
        values="0.0157 0  0  0 0 
 
          0  0.3059 0  0 0 
 
          0  0  0.7765 0 0 
 
          0  0  0  1 0 "/> 
 
    
 
    </filter> 
 
    
 
    <rect width="100%" height="50%" fill="white" filter="url(#cm)"/> 
 
    
 
    <rect y="50%" width="100%" height="100%" fill="white" filter="url(#cmRGB)"/> 
 
    
 
    </svg>

Sembra certo diverso da me su Firefox.

+0

Buona idea, io non sapeva nemmeno su questo attributo, ma non cambia nulla ai miei occhi. – Sven

+0

Wow che schifo, ma grazie per le informazioni! – Sven

+0

Volevo solo dire che questo ha funzionato per me quando provavo ad usare feColorMatrix come colorante - impostando tutti gli in RGB su 0 e usando i quinti vals della colonna per impostare il colore. Sìì! – BoB3K

1

Mentre la mia risposta ripete la stessa idea, quello che devo aggiungere è troppo per un commento.

non lo so per certo, che cosa è linearRGB nella norma, ma mi aspetto che sia, ehm, lineari. Cioè colore bianco trasformato con (scurire-due volte)

R | ½ 0 0 0 0 
G | 0 ½ 0 0 0 
B | 0 0 ½ 0 0 
A | 0 0 0 1 0 

dovrebbe comportare lo stesso colore rgb(50%, 50%, 50%), non dovrebbe?

così come il colore nero trasformato con (ligthen-due volte)

R | ½ 0 0 0 ½ 
G | 0 ½ 0 0 ½ 
B | 0 0 ½ 0 ½ 
A | 0 0 0 1 0 

dovrebbe essere lo stesso grigio al 50%.

Ma quello che effettivamente vedo come risultato è molto più leggero del previsto, il selettore di colori mostra #BCBCBC anziché #808080. D'altra parte, color-interpolation-filters="sRGB" rende il risultato corretto (controllato un MacBook e un notebook ASUS win10 con le impostazioni predefinite).

https://jsfiddle.net/7wvy57fq/2/

+0

https://www.w3.org/TR/SVG/painting.html#ColorInterpolationProperties –

+0

Grazie, quindi è "[a] (luce energia lineare) spazio colore RGB linearizzato", che non è un nome molto buono, perché questo porta a un'astrazione che perde: come programmatore mi piacerebbe lavorare con l'astrazione RGB, senza pensare al colore percepito reale.Inoltre, questo è incoerente: tutti gli editor grafici funzionano linearmente in RGB (probabilmente dopo photoshop), tutte le altre matrici funzionano linearmente. – kirilloid