Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using blending filters (multiply more specifically) using SVG

I have a reference image of the effect that I am trying to achieve using SVG.

Bitmap reference image

In Photoshop the effect can be achieved by using 100% opacity with the blending mode set to 'multiply'

The colors have hex values of:

red: #EA312F, blue: #3A5BA6 and overlapping area: #35111F

I have tried a number of approaches using SVG filters to achieve a similar effect but am struggling to understand how the blending modes calculate the values.

SVG attempts to match original graphic

  1. Original Photoshop bitmap
  2. SVG using only shapes no filters
  3. SVG using multiply filter on vertical bar
  4. SVG using multiply filter and opacity on vertical bar

You can see the SVG code for each of these in this JSBin http://jsbin.com/iPePuvoD/1/edit

I'm really struggling to understand the best approach to match the blue of the vertical bar and the color of the overlapping area.

Each of these shapes i'd also like to animate using a library such as http://snapsvg.io/, so i'm hoping to rely purely on filters, rather than cropping or other operations to achieve the desired results - but am open to suggestions.

Effectively, the SVG for the final attempt (4.) is this:

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

Would much appreciate some advice on this, I have found some good resources on SVG, but this area still seems quite difficult to get good information on.

Thanks!

like image 804
Chris Avatar asked Dec 10 '13 11:12

Chris


People also ask

How do you set blending mode to multiply?

Setting "Blend mode: Multiply" To use it, right-click on a layer, select "Blending Options…" and then set "Blend Mode: Multiply". Or use the Layer > Layer Style > Blending Options… regular menu item. You will also want a layer below that one.

What does the blending mode multiply mode do to an image?

The Darken mode compares the colors of the blending layer and the base layers, and keeps the darker colors. The Multiply mode multiplies the colors of the blending layer and the base layers, resulting in a darker color. This mode is useful for coloring shadows.

What is the purpose of blending modes?

The Screen blend mode inverts both layers, multiplies them, and then inverts that result. The Color Dodge blend mode divides the bottom layer by the inverted top layer. This lightens the bottom layer depending on the value of the top layer: the brighter the top layer, the more its color affects the bottom layer.


2 Answers

This won't work on a number of levels. Feblend takes two inputs not one. What are you blending the sourcegraphic with? If you want to blend with the background you need to use backgroundImage as your in2. If you want to blend with another shape you have to import that shape into the filter with feimage. Next problem BackgroundImage only works in IE at the moment, and feImage only works properly for referenced shapes in Chrome and Safari (Update: you can convert referenced shapes to an inline SVG data-URI and this will work cross browser).

If you are only using colored rectangles then you can generate them inside the filter using feflood and blend them there. Something like the following:

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

Update: The cross platform way to use shapes within a filter is to encode them as a SVG/XML data URI within a feImage. This is supported cross browser (although it makes the code fairly hard to read.)

like image 33
Michael Mullany Avatar answered Nov 08 '22 14:11

Michael Mullany


See the Compositing and Blending Level 1 spec. It enables specifying the compositing and blending to use when rendering web content (including svg). It is testable in a number of browsers by a toggling a runtime flag, see here for instructions. For up-to-date browser support of mix-blend-mode see 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>

As jsfiddle here.

like image 99
Erik Dahlström Avatar answered Nov 08 '22 13:11

Erik Dahlström