2012-07-20 154 views
2

我做的HTML画布一些工作,我发现,当我画一条线,我无法清除或绘制了呢?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"); 
    } 
*/ 

我似乎无法找到的画布是如何处理这个,我得到的Safari MacOSX上与Chrome和Firefox上的Windows7相同的行为一个很好的解释。

回答

4

有两件事情怎么回事。

第一个也是最重要的是,你永远不会调用context.beginPath()

你以为你是绘制一个新的红色轮廓,实际上是增加了上下文的当前路径,并使其不再每次。第一次的情况下只有一个矩形,然后它有两个,那么它有三个等

每次你打电话给你的抚摸着你曾经绘制每一个矩形的行程时间,因为上下文的当前路径包括他们所有。要解决此问题,您必须通过调用beginPath来重置当前路径。

的第二个问题是,你的线未被绘制上完美的像素,所以当你去清除它们,你会看到,由于反走样图形的问题。要解决这个问题,你需要画出完美的像素,并小心你正在擦除的矩形。欲了解更多关于此看到Loktar的答案在这里:HTML5 Canvas and Line Width

这里是你的代码,与这两个补丁来实现:

http://jsfiddle.net/QjKAp/

+0

感谢这个整理,并感谢完美像素的东西太多。 – Paddy 2012-07-20 21:31:40