HTML キャンバスでいくつかの作業を行っていますが、線を描いたときに、線をクリアしたり上に描いたりすることができません。
だから私がやっていること:各セルがそれ自体を描画するグリッド(ページの読み込み時に行われる塗りつぶされた長方形)を持つキャンバスがあります。キャンバス上では他の再描画はありません)。マウスが別のセルに移動すると、新しいセルは (以前のように) アウトライン化され、以前にアウトライン化されたセルはもはやアウトライン化されません (セルを再描画して、線の上に描画することを意図していました)。問題であることが証明されているのは、セルの「アウトライン化」です。
キャンバスに描かれた最後のものが見えるだろうが、私が得ている効果は、塗りつぶされた形状と線がより高いレイヤーの線で別々に処理されることを示唆していますか?
これを示すスタンドアロン ページのソースを次に示します。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
var CANVAS_DIMENSION = 200;
var CANVAS_WIDTH = 10;
var CANVAS_HEIGHT = 10;
var GRID_CELL_WIDTH = CANVAS_DIMENSION/CANVAS_WIDTH;
var GRID_CELL_HEIGHT = CANVAS_DIMENSION/CANVAS_HEIGHT;
var canvas;
var context;
var grid;
var mouseCellColumn = -1;
var mouseCellRow = -1;
function init()
{
canvas = document.getElementById("myCanvas");
context = canvas.getContext("2d");
canvas.addEventListener('mousemove', updateMousePosition, false);
grid = new Array(CANVAS_WIDTH);
for (var i = 0; i < CANVAS_WIDTH; ++i)
{
grid[i] = new Array(CANVAS_HEIGHT);
for (var j = 0; j < CANVAS_HEIGHT; ++j)
{
grid[i][j] = "#0000FF";
}
}
renderScene()
}
function updateMousePosition(event)
{
var initialColumn = mouseCellColumn;
var initialRow = mouseCellRow;
var objectPosition = findPos(this);
var gridPosition = new Point(event.pageX - objectPosition.x, event.pageY - objectPosition.y);
mouseCellColumn = getColumn(gridPosition.x);
mouseCellRow = getRow(gridPosition.y);
var cell_position = getCellPosition(mouseCellColumn, mouseCellRow);
// outline the current cell
drawRectangleOutlineWithColour(cell_position.x,
cell_position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#FF0000");
// if mouse has moved cell redraw
if (((initialColumn != mouseCellColumn) ||
(initialRow != mouseCellRow)) &&
(initialColumn > -1) &&
(initialRow > -1))
{
renderGridCell(initialColumn, initialRow);
}
}
function renderScene()
{
for (var i = 0; i < CANVAS_WIDTH; ++i)
{
for (var j = 0; j < CANVAS_HEIGHT; ++j)
{
renderGridCell(i, j);
}
}
}
function renderGridCell(Column, Row)
{
var position = getCellPosition(Column, Row);
drawRectangleWithColour(position.x,
position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
grid[Column][Row]);
}
function drawRectangleWithColour(minX, minY, width, height, colour)
{
context.fillStyle = colour;
context.fillRect(minX,
minY,
width,
height);
}
function drawRectangleOutlineWithColour(minX, minY, width, height, colour)
{
context.strokeStyle = colour;
context.moveTo(minX, minY);
context.lineTo(minX + width, minY);
context.moveTo(minX + width, minY);
context.lineTo(minX + width, minY + height);
context.moveTo(minX + width, minY + height);
context.lineTo(minX, minY + height);
context.moveTo(minX, minY + height);
context.lineTo(minX, minY);
context.stroke();
}
function Point(x, y)
{
this.x = x;
this.y = y;
}
function getColumn(xPosition)
{
if (xPosition < 0)
{
xPosition = 0;
}
if (xPosition > CANVAS_DIMENSION)
{
xPosition = CANVAS_DIMENSION;
}
return Math.floor(xPosition/GRID_CELL_WIDTH);
}
function getRow(yPosition)
{
if (yPosition < 0)
{
yPosition = 0;
}
if (yPosition > CANVAS_DIMENSION)
{
yPosition = CANVAS_DIMENSION;
}
return Math.floor(yPosition/GRID_CELL_HEIGHT);
}
function getCellPosition(column, row)
{
if (row < 0)
{
row = 0;
}
if (row > CANVAS_HEIGHT)
{
row = CANVAS_HEIGHT - 1;
}
if (column < 0)
{
row = 0;
}
if (column > CANVAS_WIDTH)
{
column = CANVAS_WIDTH - 1;
}
var result = new Point(column * GRID_CELL_WIDTH, row * GRID_CELL_HEIGHT);
return result;
}
function findPos(obj)
{
var result = new Point(0, 0);
if (obj.offsetParent)
{
do
{
result.x += obj.offsetLeft;
result.y += obj.offsetTop;
} while (obj = obj.offsetParent);
}
return result;
}
</script>
</head>
<body onload="init()">
<div id="test" style="width: 200px; height:200px; margin: 0px auto;">
<canvas id="myCanvas" width="200" height="200">
Your browser does not support the canvas element.
</canvas>
</div>
</body>
</html>
違反エリアはこちら:
// outline the current cell
drawRectangleOutlineWithColour(cell_position.x,
cell_position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#FF0000");
// if mouse has moved cell redraw
if (((initialColumn != mouseCellColumn) ||
(initialRow != mouseCellRow)) &&
(initialColumn > -1) &&
(initialRow > -1))
{
renderGridCell(initialColumn, initialRow);
}
これは効果がなく、アウトラインが蓄積されます。
キャンバスの再描画を掘り下げると、「clearRect」が示唆されますが、これは役に立たないようです。アウトラインは持続します:
// outline the current cell
drawRectangleOutlineWithColour(cell_position.x,
cell_position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#FF0000");
// if mouse has moved cell redraw
if (((initialColumn != mouseCellColumn) ||
(initialRow != mouseCellRow)) &&
(initialColumn > -1) &&
(initialRow > -1))
{
context.clearRect(position.x,
position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT);
renderGridCell(initialColumn, initialRow);
}
アウトライン領域を別の色で具体的に再描画しましょう。
// outline the current cell
drawRectangleOutlineWithColour(cell_position.x,
cell_position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#FF0000");
// if mouse has moved cell redraw
if (((initialColumn != mouseCellColumn) ||
(initialRow != mouseCellRow)) &&
(initialColumn > -1) &&
(initialRow > -1))
{
var position = getCellPosition(initialColumn, initialRow);
drawRectangleWithColour(position.x,
position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#00FF00");
}
いいえ、グリッドは再描画されますが、線には影響しません。グリッド全体を再描画しますか?
renderScene();
// outline the current cell
drawRectangleOutlineWithColour(cell_position.x,
cell_position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#FF0000");
/*
// if mouse has moved cell redraw
if (((initialColumn != mouseCellColumn) ||
(initialRow != mouseCellRow)) &&
(initialColumn > -1) &&
(initialRow > -1))
{
var position = getCellPosition(initialColumn, initialRow);
drawRectangleWithColour(position.x,
position.y,
GRID_CELL_WIDTH,
GRID_CELL_HEIGHT,
"#00FF00");
}
*/
キャンバスがこれをどのように処理しているかについての適切な説明が見つからないようです。MacOSX の Safari と Windows7 の Chrome および Firefox で同じ動作が得られます。