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

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

Bitmap reference image

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

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

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

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

SVG attempts to match original graphic

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

Вы можете увидеть SVG-код для каждого из них в этом JSBin 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, но эта область по-прежнему кажется довольно сложной для получения хорошей информации.

Благодарю!

Ответы

Ответ 1

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

Ответ 2

См. Спецификацию Compositing and Blending Level 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>

Как здесь.

Ответ 3

Для всех режимов 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