この記事は、前に以下の記事で書いていた「SVGフィルター」に関するものです。
●p5.js で SVGフィルターを使う(p5.js Web Editor上の HTML・JavaScript に手を加えて利用) - Qiita
https://qiita.com/youtoy/items/217bfe7e940f2a7e2626
もう少し補足すると、上記の記事では createCanvas()
で作成したキャンバスに、 style("filter", 'url()')
という形の style() を使ったやり方を用いましたが、今回の内容はそれとは少しだけ違う方法で SVGフィルターを適用する話です。
CanvasRenderingContext2D.filter を使う
「少しだけ違うやり方」と書いた部分の具体的な内容は、タイトルにも記載している「CanvasRenderingContext2D.filter」を使う方法になります。
なぜ CanvasRenderingContext2D.filter を使おうとしたか
今回の内容について、「冒頭の記事でも SVGフィルターをキャンバスに適用できているのに、なぜ別の方法を使うのだろう?」と思われた方がいらっしゃるかもしれません。
CanvasRenderingContext2D.filter
を使おうとした理由は、タイトルにも出てきている「 createGraphics()
と組み合わせる」というところが関係してきます。
createGraphics() と style() を用いた SVGフィルター適用を試す
本題である「 CanvasRenderingContext2D.filter
と createGraphics()
を組み合わせる話」に入る前に、これが必要になった理由を具体例を用いて示そうと思います。
そのために、「 createGraphics()
と組み合わせる」という話について、冒頭の記事で使った p5.js の style() を用いた方法だとどうなるかをここに示してみます。
p5.js Web Editor の index.html と sketch.js の内容と、それを実行した結果を以下に順番に掲載します。
let pg;
function setup() {
createCanvas(400, 400);
pg = createGraphics(width, height);
pg.style("filter", "url(#feGaussianBlur)");
pg.fill(100, 100, 150);
}
function draw() {
pg.background(220);
pg.circle((frameCount * 5) % width, frameCount % height, 50);
image(pg, 0, 0);
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.1/p5.js"></script>
<link rel="stylesheet" type="text/css" href="style.css" />
<meta charset="utf-8" />
</head>
<body>
<main></main>
<script src="sketch.js"></script>
<svg>
<filter id="feGaussianBlur">
<feGaussianBlur stdDeviation="10 3" />
</filter>
</svg>
</body>
</html>
この画像のとおり、SVGフィルターが適用されていない状態になります。
createGraphics() と CanvasRenderingContext2D.filter を用いた SVGフィルター適用を試す
それでは、 CanvasRenderingContext2D.filter
を利用した場合の内容を示します。
上記の style() を使った場合との違いは、 sketch.js のほうのみになるので、index.html の内容は省略して掲載します。
let pg;
function setup() {
createCanvas(400, 400);
pg = createGraphics(width, height);
pg.drawingContext.filter = "url(#feGaussianBlur)";
pg.fill(100, 100, 150);
}
function draw() {
pg.background(220);
pg.circle((frameCount * 5) % width, frameCount % height, 50);
image(pg, 0, 0);
}
今度は、描画した円にブラーフィルターがかかっているのが分かります。
今回の差が生じた理由
最後に上で試した 2つの内容の違いについて触れて終わろうと思います。
今回の、SVGフィルターを適用する 2つのやり方について上記の違いが生じた理由は以下だと思われます。
- style() を使った方法
- ブラウザでのレンダリング時にフィルターを適用(元の描画内容の画素には手が加えられていない)
- CanvasRenderingContext2D.filter を使った方法
- 描画されている画素の値自体を変化させている