Соответствие цвета в SVG с feColorMatrix

Я создал тень в SVG, используя SourceAlpha для тени, так что его простой черный. С помощью feColorMatrix Я немного уменьшил непрозрачность, но все-таки это выглядело не так, как я хотел - я хочу, чтобы цвет тени соответствовал определенному значению цвета. Итак, я более подробно взглянул на feColorMatrix,

Сейчас не пользуюсь SourceAlpha как источник для тени, но SourceGraphic, Как мое векторное изображение просто белый ака rgba(255, 255, 255, 1)Я могу рассчитать цвет тени следующим образом:

<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  "/>

Результат должен быть темно-синей тенью ака rgba(4, 78, 198, 1),

На самом деле это работает, и я считаю, что все расчеты верны, но при создании тени с CSS3, использующей тот же цвет, есть заметная разница: фильтр SVG, кажется, делает цвет слишком светлым. Есть ли способ это исправить?

2 ответа

Решение

feColorMatrix, как и большинство фильтров, работает в цветовом пространстве linearRGB. Если вам нужен цвет sRGB, попробуйте установить color-interpolation-filters = "sRGB" в качестве атрибута на 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>

На Firefox для меня это выглядит иначе.

Хотя мой ответ повторяет ту же идею, я должен добавить слишком много комментариев.

Я не знаю точно, что linearRGB в стандарте, но я ожидаю, что он будет, линейный. Т.е. белый цвет трансформируется (темнеет-дважды)

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

должен привести к тому же цвету, что и rgb(50%, 50%, 50%)не так ли?

Как и черный цвет, трансформируемый с помощью (Ligthen-дважды)

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

ожидается, что будет такой же 50% серый.

Но то, что я на самом деле вижу в результате, намного легче, чем ожидалось, показывает подборщик цветов #BCBCBC вместо #808080, С другой стороны, color-interpolation-filters="sRGB" корректирует результат (проверил macbook и ноутбук winus ASUS с настройками по умолчанию).

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

Другие вопросы по тегам