【问题标题】:Arbitrary shape getting drawn in HTML5 canvas在 HTML5 画布中绘制任意形状
【发布时间】:2013-04-24 18:08:49
【问题描述】:

我正在尝试使用 HTML5 画布元素绘制图形。该图由顶点和连接这些顶点的边组成。我用小圆圈表示顶点,用连​​接圆圈的线表示边缘。

在我的项目中,我想在按下“下一步”按钮时更改顶点的位置。下图是页面首次加载时画布的状态:

单击“下一步”按钮时,将根据顶点的新坐标重新绘制图形。但是,渲染似乎有错误,如下所示:

奇怪的是,我没有在任何地方使用 fill() 函数,所以我无法理解填充部分出现的原因。以下是用于绘制图形的 draw() 函数的代码:

function draw(position)
{
    var canvas_elem = document.getElementById('drawing');

    // Check the element is in the DOM and the browser supports canvas
    if(canvas_elem.getContext)
    {
        // Initaliase a 2-dimensional drawing context
        var canvas = canvas_elem.getContext('2d');

        // Clear canvas
        canvas.clearRect(0, 0, canvas_elem.width, canvas_elem.height);

        var data = data_array[num_vertices+1+position].split(",");

        // Draw all vertices
        for( var i=0; i<num_vertices; i++)
        {
            canvas.arc(data[2*i], data[2*i+1], radius, 0, 2 * Math.PI, false);
            canvas.fillStyle = 'black';
            canvas.fill();
        }

        // Connect vertices by lines according to adjacency matrix
        for(var i=0;i<num_vertices; i++)
        {
            for(var j=i; j<num_vertices; j++)
            {
                if(adjacency[i][j]==1)
                {
                    canvas.beginPath();
                    canvas.moveTo(data[2*i],data[2*i+1]);
                    canvas.lineTo(data[2*j],data[2*j+1]);
                    canvas.stroke();
                }
            }
        }
    }
    else
    {
        alert("Please use an HTML5 compatible browser.");
    }
}

关于这里可能发生的事情有什么线索吗?


获取这些变量的以下值进行调试:

data_array=[
"10",
"0,1,1,0,0,0,0,0,0,0",
"1,0,0,1,0,0,0,0,0,1",
"1,0,0,0,1,0,0,0,0,1",
"0,1,0,0,0,1,0,0,1,1",
"0,0,1,0,0,0,1,0,1,1",
"0,0,0,1,0,0,0,1,1,0",
"0,0,0,0,1,0,0,1,1,0",
"0,0,0,0,0,1,1,0,0,0",
"0,0,0,1,1,1,1,0,0,0",
"0,1,1,1,1,0,0,0,0,0",
"10,2,35.4,23.3,88.9,100,210,350,70,500,412,208,336,112,45,32,89,92,102,23",
"30,4,19.4,35.3,80.9,90,230,310,120,440,400,220,330,105,40,29,80,89,90,18"
]

num_vertices=10

【问题讨论】:

  • 你能告诉我们data_arraynum_vertices里面的信息吗?检查这个小提琴是否有缺失的部分; jsfiddle.net/Allendar/AZLqp
  • 嗨....请在我对帖子所做的编辑中找到您询问的信息。感谢您的帮助!

标签: javascript html html5-canvas


【解决方案1】:

好吧,一个愚蠢的错误。画完每条线后忘记调用 closePath() 了。

【讨论】:

  • 您只在 Chrome 中进行测试吗?因为,在我在 IE 和 FireFox 中的测试中,如果你不为弧线调用 beginPath(),则整个路径都会被填充为黑色。 jsfiddle.net/PAPr5/2
【解决方案2】:

.arc() 方法将点添加到当前路径,.fill() 方法填充当前路径。如果您继续调用.arc(),您将重复使用相同的路径,因此它最终会被填满。使用.beginPath() 开启新路径:

// Draw all vertices
for( var i=0; i<num_vertices; i++)
{
    canvas.beginPath();
    canvas.arc(data[2*i], data[2*i+1], radius, 0, 2 * Math.PI, false);
    canvas.fill();
}

http://jsfiddle.net/PAPr5/2/

或者,使用.moveTo() 开始一个新的子路径。这让您只需调用 .fill() 即可一次绘制所有点。

// Draw all vertices
for (var i = 0; i < num_vertices; i++) {
    var x = data[2 * i];
    var y = data[2 * i + 1]
    canvas.moveTo(x, y);
    canvas.arc(x, y, radius, 0, 2 * Math.PI, false);
}
canvas.fill();

http://jsfiddle.net/PAPr5/5/

According to the spec.arc() 不应创建新路径或子路径。 Google Chrome 中.arc() 的实现不符合规范。在 Chrome 中,每次调用 .arc() 都会创建一个新的子路径。这种行为是非标准的。

【讨论】:

  • 对不起,这没有帮助。据我所知,如果使用了 fill() 方法,那么您不需要显式关闭路径。它是自动完成的。在这里阅读:developer.mozilla.org/en-US/docs/HTML/Canvas/Tutorial/…
  • @aakashbhowmick - .fill() 执行 implicit closePath,但实际上并没有通过将路径标记为关闭或添加点来修改路径。即使是对closePath() 的显式调用也不够好,因为它只会关闭当前的子路径。对arc() 的下一次调用将在您的路径中添加一条从最后一个弧到新弧的线。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多