it-swarm.com.ru

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

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

Bitmap reference image

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

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

красный: # 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, но в этой области все еще довольно сложно получить хорошую информацию.

Спасибо!

13
Chris

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

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

7
Michael Mullany

Смотрите спецификацию Составление и смешивание 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 здесь .

5
Erik Dahlström

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

0
john ktejik