オクルージョン問題を解決するためのキャンバスのカスタム描画順序
1. 問題のシナリオ
キャンバス描画を使用して要素を重ね合わせる場合、先に描画したものが下、後から描画したものが上という順番でオーバーレイ表示されないことがよくあります。理由は、絵のサイズが異なるため、先に読み込んだものは先に描画され、読み込んだものは後から描画するため、描画時間や読み込み時間が異なるためです。
- 次の 4 つの要素をキャンバスの同じ領域に同時に描画するとします。
1. 長方形グリッド (600 x 600)
2. 赤い図 (400 × 400)
3. 緑の図 (200 × 200)
4. 青い線は
順番に描画されますが、最終的な描画効果は下の図に示されており、緑の図と青い線が描画されます。線は部分的に赤で影付けされています。つまり、線は望ましい順序で描かれていません。このうち、グリッド部分は描画時に最初にグリッドが描画されるため、部分的にもブロックされてしまいます。
では、描画時の順序の問題を解決して、絵が邪魔されずに希望の順序で描画できるようにするにはどうすればよいでしょうか。
2. 解決策
上記の問題が発生したため、キャンバス上で青い線と緑のグラフィックを描画する機能が最初に実行され、最後に赤い部分を描画する機能が実行され、その結果オクルージョンが発生していると考えられます。
- では、関数の実行順序を制御することはできるのでしょうか?
そこで、配列を定義し、実行するすべての関数とメソッドを配列にプッシュする、つまり関数を配列の要素として配列に格納し、これらの関数を配列のメソッドを通じて操作できるようにすることを考えました。次に、最初に実行する必要がある順序で並べ替え、後で実行するものを配置し、最後に関数配列を走査してその中の各関数を実行するに従って関数をカスタマイズできます。
3. コードを実装する
- 1. 描画順序をカスタマイズします。
const DrawIndex = {
red: 1,
green: 2,
mesh: 3,
line: 4,
};
注: ここでのグリッドの 3 番目の描画は、グリッドが隠れるのを防ぐためのものです。
- 2. 描画する必要があるすべての関数を保存するために、drawList 配列を定義します。
const drawList = [];
- 3. 描画する関数、対応するパラメータリスト、描画する順序を配列に追加します。
//1.添加绘制网格函数
drawList.push({
func: this.drawMesh, //绘制网格函数
value: [width, height], //绘制需要的参数列表
index: DrawIndex.mesh, //绘制顺序
});
//2.添加绘制红色部分函数
drawList.push({
func: this.drawRed,
value: [width, height, color],
index: DrawIndex.red, //绘制顺序
});
//3.添加绘制绿色部分函数
drawList.push({
func: this.drawGreen,
value: [width, height, color],
index: DrawIndex.green, //绘制顺序
});
//4.添加绘制蓝色线条函数
drawList.push({
func: this.drawLine,
value: [lineWidth, lineColor],
index: DrawIndex.line, //绘制顺序
});
- 4. 配列をソートする
drawList.sort((a, b) => a.index - b.index);
- 5. 関数配列を走査し、その中の関数を実行します。
drawList.forEach((draw) => {
draw.func.apply(this, draw.value);
});
最終効果