canvas – 2つの図形を重ねた際の描画について
2つの図形を重ねた場合の描画を試します。
図形を重ねた場合にcanvasで「ノンゼロワインディング規則」というルールが適用されます。
例えば図形1と図形2がパスで設定される時、図形1は時計回りに描画
図形2は反時計周りに描画をすると、内側の領域は塗りつぶされない仕様になります。
以下に簡単なサンプルを用意しました。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
// canvasのDOMを取得
const canvas = document.getElementById('canvas');
// getContextメソッドでコンテキストを取得
// ここでは2次元の平面的な図形を扱うので、引数に「2d」を指定
const ctx = canvas.getContext('2d');
// コンテキストのstyleを定義
// パスの開始
ctx.beginPath();
// 図形1を時計周りで指定
ctx.moveTo(10, 10);
ctx.lineTo(90, 10);
ctx.lineTo(90, 50);
ctx.lineTo(10, 50);
// 図形2を反時計回で指定
ctx.moveTo(15, 15);
ctx.lineTo(15, 45);
ctx.lineTo(85, 45);
ctx.lineTo(85, 15);
// パスを塗りつぶす
ctx.fill();
</script>
</body>
</html>
画面にアクセスすると長方形の線状の図形が描画されます。
これは図形1が外側の少し大きい長方形を描画し、図形2が少し小さい内側の長方形を描画する際、
内側の長方形の描画を反時計周りの順でパスを設定することにより、外側の長方形の塗りつぶしの領域が空白になった為です。
では、実験的に内側の図形2を時計回りに描画するとどうなるか試してみます。
以下に簡単なサンプルを用意しました。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>テストHTML</title>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
// canvasのDOMを取得
const canvas = document.getElementById('canvas');
// getContextメソッドでコンテキストを取得
// ここでは2次元の平面的な図形を扱うので、引数に「2d」を指定
const ctx = canvas.getContext('2d');
// コンテキストのstyleを定義
// パスの開始
ctx.beginPath();
// 図形1を時計周りで指定
ctx.moveTo(10, 10);
ctx.lineTo(90, 10);
ctx.lineTo(90, 50);
ctx.lineTo(10, 50);
// 図形2を反時計回で指定
ctx.moveTo(15, 15);
ctx.lineTo(85, 15);
ctx.lineTo(85, 45);
ctx.lineTo(15, 45);
// パスを塗りつぶす
ctx.fill();
</script>
</body>
</html>
画面にアクセスすると、今度は内側の長方形が時計回りの順でパスが設定されているため、
外側の長方形の塗りつぶしが、空白にならないことがわかります。