Използване на филтри за смесване (умножете по-конкретно) с помощта на 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>

Актуализация: Междуплатформеният начин за използване на фигури във филтър е да се кодират като SVG/XML URI данни в рамките на 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