如何在HTML5 Canvas中强制线条在其他内容之后渲染

时间:2019-04-26 15:45:53

标签: javascript html5-canvas

我一直试图制作一个节点图可视化器,但是我很难使线条显示在节点后面。我已经尝试使用context.globalCompositeOperation,但无济于事。我尝试按照我希望绘制的顺序实施渲染。这是该项目的完整代码:

var canvas = document.querySelector('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var c = canvas.getContext('2d');

var nodes = [];


var has_clicked = false;
var user_has_picked_up_object = false;
var picked_up_id;

class Vector2 {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}

document.onmousemove = function(e){
    mouse_pos.x = e.pageX;
    mouse_pos.y = e.pageY;
}

document.onmousedown = function(e) {
    has_clicked = true;
}

document.addEventListener('mouseup', function(e) {
    has_clicked = false;
    user_has_picked_up_object = false;
})

var mouse_pos = new Vector2(0, 0);

class Connection {
    constructor(node1, node2) {
        this.node1 = node1;
        this.node2 = node2;
        this.isDrawn = false;
    }
}

function DistSQ(p1, p2) {
    return Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2);
}

class Node {
    constructor(pos, id) {
        this.pos = pos;
        this.radius = 10;
        this.radius_squared = 100;
        this.connections = [];
        this.id = id;
    }

    AddConnection(conn) {
        this.connections.push(conn);
    }
    RemoveConnection(conn) {
        return this.connections.pop(conn);
    }

    UpdatePosition() {
        if(DistSQ(this.pos, mouse_pos) < this.radius_squared && has_clicked) {
            if(user_has_picked_up_object && picked_up_id == this.id) {
                this.pos = mouse_pos;
            }
            else {
                user_has_picked_up_object = true;
                picked_up_id = this.id;
            }
        }
        else {
            this.pos = new Vector2(this.pos.x, this.pos.y);
        }
    }
}

function DrawLines(conns) {
    c.beginPath();
    c.lineWidth = 1;
    c.strokeStyle = 'black';
    conns.forEach(element => {
        c.moveTo(element.node1.pos.x, element.node1.pos.y);
        c.lineTo(element.node2.pos.x, element.node2.pos.y);
    });
    c.stroke();
}

function DrawCircles(nds) {
    c.beginPath();
    c.lineWidth = 1;
        nds.forEach(element => {
            c.strokeStyle = 'black';
            c.moveTo(element.pos.x+element.radius, element.pos.y);
            c.arc(element.pos.x, element.pos.y, element.radius, 0, 2 * Math.PI, false);
        });
    c.stroke();
}


function Update() {
    requestAnimationFrame(Update);

    c.clearRect(0, 0, window.innerWidth, window.innerHeight);
    for(var i = 0; i < nodes.length; i++) {
        nodes[i].UpdatePosition();
        DrawLines(nodes[i].connections);
    }
    DrawCircles(nodes);
}

function Initialize() {
    for(var y = 0, i = 0; y < 5; y++) {
        for(var x = 0; x < 5; x++, i++) {
            nodes.push(new Node(new Vector2(x*20+20, y*20+20), i));
        }
    }

    for(var i = 1; i < nodes.length; i++) {
        nodes[i].AddConnection(new Connection(nodes[i], nodes[i-1]));
    }
    Update();
}

Initialize();

1 个答案:

答案 0 :(得分:0)

感谢@enxaneta,为我提供了解决此问题的方法,因此我在此处复制了他的答案: 这些线在圆圈后面-在函数DrawCircles中添加c.fillStyle = "white";c.fill() –附件