web-dev-qa-db-ja.com

SVGを使用したブレンディングフィルターの使用(より具体的に乗算)

SVGを使用して達成しようとしている効果の参照画像があります。

Bitmap reference image

Photoshopでは、ブレンドモードを「乗算」に設定して100%の不透明度を使用することで、効果を実現できます。

色の16進値は次のとおりです。

赤:#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/ などのライブラリを使用してアニメーション化したいので、トリミングやその他の操作ではなく、純粋にフィルターに依存したいと考えています。望ましい結果を達成しますが、提案を受け入れます。

事実上、最後の試み(4.)のSVGは次のとおりです。

<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に関する優れたリソースをいくつか見つけましたが、この領域については、まだ十分な情報を得るのが非常に難しいようです。

ありがとう!

15
Chris

これは多くのレベルでは機能しません。 Feblendは1つではなく2つの入力を取ります。ソースグラフィックを何とブレンドしていますか?背景とブレンドしたい場合は、in2としてbackgroundImageを使用する必要があります。別のシェイプとブレンドする場合は、そのシェイプをfeimageでフィルターにインポートする必要があります。次の問題BackgroundImageは現時点ではIEでのみ機能し、feImageはChromeおよびSafari(更新:参照された形状をに変換できます)の参照された形状に対してのみ適切に機能しますインライン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>

更新:フィルター内で形状を使用するクロスプラットフォームの方法は、feImage内でそれらをSVG/XMLデータURIとしてエンコードすることです。これはクロスブラウザでサポートされています(ただし、コードはかなり読みにくくなります)。

7
Michael Mullany

合成およびブレンドレベル1仕様 を参照してください。これにより、Webコンテンツ(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

1
john ktejik