简体   繁体   中英

Arbitrary shape getting drawn in HTML5 canvas

I am trying to draw a graph using HTML5 canvas element. The graph consists of vertices and edges connecting these vertices. I'm representing the vertices by small circles and edges by lines connecting the circles.

In my project, I want to change the position of vertices, when a 'Next' button is pressed. Shown below is a state of the canvas when the page is first loaded:

在此处输入图片说明

When the 'Next' button is clicked the graph is redrawn, based on the new coordinates of the vertices. However, there seems to be a error with the rendering as shown below:

在此处输入图片说明

Strangely, I am not using the fill() functions anywhere, so I am not able to understand why the filled portion is coming. Following is the code for draw() function that is used for drawing the graph:

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.");
    }
}

Any leads on what might be happening here?


Take following values of these variables for debugging:

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

The .arc() method adds points to the current path, and the .fill() method fills in the current path. If you keep calling .arc() , you are re-using the same path, so it eventually gets filled. Start a new path with .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/

Or, start a new sub-path using .moveTo() . This let's you paint all the points at once with a single call to .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() should not create a new path or sub-path. The implementation of .arc() in Google Chrome does not conform to the specification. In Chrome, each call to .arc() results in a new sub-path being created. This behavior is non-standard.

Okay, a silly mistake. I forgot to call closePath() after drawing each line.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM