Skip to content
React Native Skia ガイドブック
Esc
navigateopen⌘Jpreview
On this page

マスクとブレンドモード

Maskコンポーネントによるアルファ・輝度マスク、BlurMaskによるぼかし、Paintのblendmodeによる合成モードの切り替えをまとめて解説します。

画像とマスクの合成、2つの色のブレンド、複数フィルターの合成を並べた図

マスクは見える範囲、ブレンドは重なり方、フィルターは描画後のピクセル変換を担当します。

前章のカラーフィルターは色そのものを変換するエフェクトでしたが、この章では「どこを見せるか」を制御するマスク(mask)と、「重なった色をどう混ぜるか」を制御するブレンドモード(blend mode)を扱います。

Mask: 一部だけを見せる

Maskは、あるコンテンツを別の描画内容でマスキングするコンポーネントです。Maskの最初の子要素がマスク定義、残りの子要素がマスクされるコンテンツになります。CSSのmaskと同じ考え方で、2つのモードがあります。

  • alpha: マスク画像の透明度(アルファチャンネル)を使う。不透明なピクセルが見え、透明なピクセルは見えなくなる。Figmaのマスクと同じ仕組み
  • luminance: マスク画像の輝度(luminance)を使う。白いピクセルが見え、黒いピクセルは見えなくなる。SVGのマスクと同じ仕組み
Name Type Description
mode? alpha | luminance 輝度マスクかアルファマスクか(デフォルトはalpha)
clip? boolean マスクをコンテンツの境界でクリップするか
mask ReactNode マスク定義
children ReactNode マスクされるコンテンツ
import { Canvas, Mask, Group, Circle, Rect } from "@shopify/react-native-skia";

const AlphaMaskDemo = () => (
  <Canvas style={{ width: 256, height: 256 }}>
    <Mask
      mask={
        <Group>
          <Circle cx={128} cy={128} r={128} opacity={0.5} />
          <Circle cx={128} cy={128} r={64} />
        </Group>
      }>
      <Rect x={0} y={0} width={256} height={256} color="lightblue" />
    </Mask>
  </Canvas>
);

このアルファマスクの例では、外側の円がopacity={0.5}なので半透明に、内側の円がデフォルトの不透明な黒(アルファ1)なので完全に見える円になります。円の外側は何も描かれていないためアルファ0、つまり完全に透明です。

輝度マスクにする場合は色そのものの明るさを使います。白は輝度1(完全に見える)、黒は輝度0(完全に見えない)です。

Skiaを読み込み中…

modeluminanceに切り替えると、内側の円の色が黒(輝度0で見えなくなる)、外側の円が白(輝度1で見える)という指定に変わります。同じ「内側をくり抜く」という結果でも、アルファマスクとは色の指定の仕方が逆になる点に注目してください。

BlurMask: マスクフィルターでぼかす

マスクフィルター(mask filter)は、図形のジオメトリとアルファチャンネルを操作するエフェクトです。代表的なものがBlurMaskで、図形の輪郭をガウスぼかしします。

Name Type Description
blur number ガウスぼかしの標準偏差。0より大きい値
style? BlurStyle normalsolidouterinnerのいずれか(デフォルトはnormal)
respectCTM? boolean trueの場合、現在の変換行列(CTM)に応じてぼかし量を調整する(デフォルトはfalse)
import { Canvas, Fill, Circle, BlurMask, vec } from "@shopify/react-native-skia";

const MaskFilterDemo = () => {
  return (
    <Canvas style={{ flex: 1 }}>
      <Circle c={vec(128)} r={128} color="lightblue">
        <BlurMask blur={20} style="normal" />
      </Circle>
    </Canvas>
  );
};

styleによって見た目が変わります。normalは輪郭を中心に内外両方向へぼかし、solidは図形の内側をそのまま残して外側だけぼかし、outerは図形の外側部分だけを描画してぼかし、innerは図形の内側だけをぼかします。用途としては、ボタンや円形アイコンの縁を柔らかく見せたいときによく使います。

Skiaを読み込み中…

前章までに登場したBoxShadowのぼかしはこのBlurMaskとは別の実装(角丸矩形専用の高速なシャドウ)なので、単純な影であればBoxShadow、任意の図形の輪郭をぼかしたい場合はBlurMask、というふうに使い分けます。

blendMode: 重なりの合成方法を変える

PaintblendModeプロパティは、描画する色(source)と、すでにキャンバスに描かれている色(destination)をどう合成するかを指定します。デフォルトはsrcOver(上から重ねて描く、最も一般的な合成)です。

指定できる値は次の通りです。

clearsrcdstsrcOverdstOversrcIndstInsrcOutdstOutsrcATopdstATopxorplusmodulatescreenoverlaydarkenlightencolorDodgecolorBurnhardLightsoftLightdifferenceexclusionmultiplyhuesaturationcolorluminosityplusDarkerplusLighter

数が多いので、代表的なものだけ実際に見比べてみましょう。以下は同じ2つの円に対して、後から描く円だけblendModeを切り替えたものです。

Skiaを読み込み中…

multiply(乗算)は暗い色同士が重なるほど暗くなり、影や汚れの表現に向きます。screen(スクリーン)はその逆で明るくなり、光の表現に向きます。difference(差)は色の差分を取るので、重なった部分がネガのように反転して見えます。hueは色相だけを差し替えるモードで、前章のBlendColorのmode="hue"とも同じ考え方です。

blendModePaint(あるいは各描画コンポーネント)に直接指定できるほか、Groupにまとめて指定して配下の描画すべてに適用することもできます。

注意点

Maskmaskpropに複雑な描画(グラデーションやテキストなど)を渡すこともできます。ただし、マスク自体の描画コストもかかるため、頻繁に再計算されるアニメーションでは処理負荷に注意してください。

blendModeは描画順に依存します。同じ2つの色でも、どちらを先に描くか(どちらがsourceでどちらがdestinationか)によって結果が変わるモード(srcIndstOutなど非対称なもの)があるので、意図した見た目にならない場合は描画順を疑ってみてください。

公式ドキュメントのMaskMask Filtersも参照してください。