Использование фильтров смешивания (умножение более конкретно) с использованием SVG

У меня есть эталонное изображение эффекта, которого я пытаюсь добиться с помощью SVG.

Растровое эталонное изображение

В Photoshop этого эффекта можно достичь, используя 100% непрозрачность с режимом наложения, установленным на «умножение».

Цвета имеют шестнадцатеричные значения:

красный: #EA312F, синий: #3A5BA6 и перекрывающаяся область: #35111F

Я пробовал несколько подходов с использованием фильтров SVG для достижения аналогичного эффекта, но я изо всех сил пытаюсь понять, как режимы наложения вычисляют значения.

SVG пытается сопоставить исходную графику

  1. Исходное растровое изображение Photoshop
  2. SVG с использованием только фигур без фильтров
  3. SVG с использованием множественного фильтра на вертикальной полосе
  4. SVG с использованием множественного фильтра и непрозрачности на вертикальной полосе

Вы можете увидеть код SVG для каждого из них в http://jsbin.com/iPePuvoD/1/edit

Я действительно изо всех сил пытаюсь понять, как лучше всего подобрать синий цвет вертикальной полосы и цвет перекрывающейся области.

Каждую из этих фигур я также хотел бы анимировать с помощью такой библиотеки, как http://snapsvg.io/, поэтому Я надеюсь полагаться исключительно на фильтры, а не на кадрирование или другие операции для достижения желаемых результатов, но я открыт для предложений.

По сути, SVG для последней попытки (4.) таков:

<svg viewBox="0 0 96 146" version="1.1" id="f-multiply-opacity" preserveAspectRatio="xMinYMin meet">
  <defs>
    <filter id="f_multiply" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
      <feBlend in="SourceGraphic" mode="multiply"/>
      <feBlend in="SourceGraphic" mode="multiply"/>
    </filter>
  </defs>
  <g id="f_shape">
    <rect x="0" y="0" width="96" height="32" fill="#EA312F" />
    <rect x="0" y="50" width="96" height="32" fill="#EA312F" />
    <rect x="0" y="50" width="32" height="96" opacity="0.8" fill="#3A5BA6" filter="url(#f_multiply)" />
  </g>
</svg>

Буду очень признателен за совет по этому поводу, я нашел несколько хороших ресурсов по SVG, но в этой области все еще довольно сложно получить хорошую информацию.

Спасибо!


person Chris    schedule 10.12.2013    source источник


Ответы (3)


Это не будет работать на ряде уровней. Feblend принимает два входа, а не один. С чем вы смешиваете исходную графику? Если вы хотите смешаться с фоном, вам нужно использовать backgroundImage в качестве вашего in2. Если вы хотите смешать с другой формой, вы должны импортировать эту форму в фильтр с помощью feimage. Следующая проблема На данный момент BackgroundImage работает только в IE, а feImage правильно работает только для ссылочных фигур в Chrome и Safari (обновление: вы можете преобразовать ссылочные фигуры во встроенный SVG data-URI, и это будет работать в разных браузерах).

Если вы используете только цветные прямоугольники, вы можете сгенерировать их внутри фильтра с помощью feflood и смешать их там. Что-то вроде следующего:

<svg x="800px" height="600px" viewBox="0 0 200 100" version="1.1" id="f-multiply-opacity" preserveAspectRatio="xMinYMin meet">
  <defs>
    <filter id="f_multiply" filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
      <feFlood x="0" y="0" width="96" height="32" flood-color="#EA312F" result="a"/>
      <feFlood x="0" y="50" width="96" height="32" flood-color="#EA312F" result="b"/>
      <feFlood rect x="0" y="50" width="32" height="96" flood-opacity="0.8" flood-color="#3A5BA6" result="c"/>
      <feBlend in="a" in2="b" result="ab" mode="multiply"/>
      <feBlend in="ab" in2="c" mode="multiply"/>
     </filter>
  </defs>
  <g id="f_shape">
    <rect filter="url(#f_multiply)" x="0" y="0" width="200" height="200"/>
  </g>
</svg>

Обновление: межплатформенный способ использования фигур в фильтре — кодировать их как URI данных SVG/XML в feImage. Это поддерживается кросс-браузером (хотя это делает код довольно трудным для чтения).

person Michael Mullany    schedule 10.12.2013
comment
Спасибо - приведенный вами пример кода дает отличное представление о том, как работает feBlend, на самом деле эффект, который вы демонстрируете, - это именно то, что я ищу. Я стремлюсь смешать примитивные формы, которые, как я думаю, можно нарисовать с помощью заливки (надеюсь). Теперь он отлично работает в Chrome для меня. Это определенно поставило меня на правильный путь, так что еще раз спасибо. - person Chris; 10.12.2013
comment
Просто быстрое обновление — похоже, я столкнулся с той же проблемой Firefox, о которой вы уже упоминали здесь: bugzilla.mozilla.org/show_bug.cgi?id=455986 и добавил свою поддержку для решения этой проблемы, мне нужно нарисовать некоторые фигуры, которые не являются просто прямоугольниками, чтобы получить окончательный желаемый эффект. - person Chris; 11.12.2013
comment
Я смог показать вам анимацию, но она по-прежнему несовместима с Firefox. :( http://jsfiddle.net/9AgDm/11/ - person ifugu; 20.08.2014

См. спецификацию компоновки и смешивания, уровень 1. Он позволяет указать композитинг и смешивание для использования при рендеринге веб-контента (включая svg). Его можно протестировать в ряде браузеров путем переключения флага среды выполнения. Инструкции см. здесь. Актуальную информацию о поддержке браузером mix-blend-mode см. в разделе caniuse.

<svg>
  <style>
    circle { mix-blend-mode: multiply; }
  </style>
  <circle cx="40" cy="40" r="40" fill="#EA312F"/>
  <circle cx="80" cy="40" r="40" fill="#3A5BA6"/>
</svg>

Как jsfiddle здесь.

person Erik Dahlström    schedule 16.12.2013
comment
Привет, Эрик - большое спасибо, и да, я видел кое-какую информацию об этом - очень интересные вещи, которые сделают мою жизнь намного проще. НО... я пытаюсь настроить таргетинг на максимально возможное количество браузеров, поэтому не думаю, что это будет применимо... пока. Еще раз спасибо за предложение. - person Chris; 17.12.2013
comment
Я тебя люблю. Это здорово! - person Darth Egregious; 05.12.2014

Для всех режимов feBlend итоговая непрозрачность вычисляется следующим образом:

qr = 1 - (1-qa)*(1-qb)

Для приведенных ниже формул композитинга применяются следующие определения:

cr = Result color (RGB) - premultiplied 
qa = Opacity value at a given pixel for image A 
qb = Opacity value at a given pixel for image B 
ca = Color (RGB) at a given pixel for image A - premultiplied 
cb = Color (RGB) at a given pixel for image B - premultiplied 
The following table provides the list of available image blending modes:

Формула режима наложения изображения для вычисления результирующего цвета

normal  cr = (1 - qa) * cb + ca
multiply    cr = (1-qa)*cb + (1-qb)*ca + ca*cb
screen  cr = cb + ca - ca * cb
darken  cr = Min ((1 - qa) * cb + ca, (1 - qb) * ca + cb)
lighten cr = Max ((1 - qa) * cb + ca, (1 - qb) * ca + cb)

Из http://www.w3.org/TR/SVG/filters.html#feBlendElement

person john ktejik    schedule 13.01.2015