javascript - HTML5 Canvas 刷新时闪烁

标签 javascript jquery html html5-canvas setinterval

我需要每两到三秒刷新一次 HTML5 Canvas 。

setInterval(writeCanvas, 2000);

这 block Canvas 充满了点和线。每个横坐标和纵坐标都存储在 XML 文件中。因此,在更新 Canvas 之前,我对服务器上的文件执行异步请求。

问题是 Canvas 闪烁。我猜它会在异步请求运行时消失。

如何解决这个问题?

这是writeCanvas的代码:

function drawLines(ctx, back, front, width, xArray, yArray) {
    ctx.strokeStyle = back;
    ctx.fillStyle = front;
    ctx.lineWidth = width;
    ctx.beginPath();
    ctx.moveTo(xArray[0], yArray[0]);
    for (var i=1; i<xArray.length; i++) {
        ctx.lineTo(xArray[i],yArray[i]);
    }
    ctx.fill();
    ctx.stroke();
    ctx.closePath();
}

function drawPoint(ctx, back, front, x, y, radius, startAngle, endAngle) {
    ctx.strokeStyle = back;
    ctx.fillStyle = front;
    ctx.beginPath();
    ctx.arc(x,y,radius,startAngle,endAngle,endAngle);
    ctx.fill();
    ctx.stroke();
    ctx.closePath();
}

function writeLabel(ctx, color, font, x, y, text) {
    ctx.fillStyle = color;
    ctx.font = font;
    ctx.beginPath();
    if(x < 0) {
        x = 0;
    }
    ctx.fillText(text, x, y);
    ctx.fill();
    ctx.closePath();
}

function writeCanvas()
{
    var elem = document.getElementById('profileCanvas');
    if (!elem || !elem.getContext) {
        return;
    }

    var ctx = elem.getContext('2d');
    if (!ctx) {
        return;
    }

    // apply the final size to the canvas
    elem.setAttribute('width', canvasWidth);
    elem.setAttribute('height', canvasHeight);

    $.get('profileStatus.xml', function(xml) {
        if(xml) {
            var testPoints = new Array();
            $(xml).find('TP').each(function() {
                var selected = $(this).find('SELECTED:first').text();
                if(selected == "YES") {
                    var name = $(this).find('MODULE_NAME:first').text();
                    var state = $(this).find('STATE:first').text();
                    var tp = new ProfileTp(name, state, selected);
                    testPoints.push(tp);
                }
            });

            $.get('profile.xml', function(data) {
                if(data) {
                    profileWidth = parseFloat($(data).find('MAIN > PROFILE > DIM_W').first().text());
                    profileHeight = parseFloat($(data).find('MAIN > PROFILE > DIM_H').first().text());

                    var backgroundColor = '#ddd';
                    var color = '#323232';
                    ctx.translate(0,canvasHeight);

                    var xArray = new Array();
                    var yArray = new Array();

                    $(data).find('PROFILE > POINT > X').each(function(){
                        var x=parseFloat($(this).text());
                        xArray.push(x);
                    });
                    $(data).find('PROFILE > POINT > Y').each(function(){
                        var y=parseFloat($(this).text());
                        yArray.push(y);
                    });
                    drawLines(ctx, backgroundColor, color, 2, xArray, yArray);

                    var finalArray = new Array();
                    $(data).find('TESTPOINTS > TP').each(function() {
                        var labelName = $(this).find('MODULE_NAME:first').text();
                        var tp = $.grep(testPoints, function(obj){ return obj.NAME == labelName; });
                        if(tp.length == 1) {
                            $(this).find('IHM').each(function(){
                                tp[0].LABEL_X = parseFloat($(this).find('LABEL > X:first').text());
                                tp[0].LABEL_Y = parseFloat($(this).find('LABEL > Y:first').text());
                                tp[0].MARKER_X = parseFloat($(this).find('MARKER > X:first').text());
                                tp[0].MARKER_Y = parseFloat($(this).find('MARKER >Y:first').text());
                            });
                            finalArray.push(tp[0]);
                        }
                    });
                    for(var i=0; i<finalArray.length; i++) {
                        writeLabel(ctx, color, fontSize+"px Arial",(finalArray[i].MARKER_X+finalArray[i].LABEL_X),(finalArray[i].MARKER_Y+finalArray[i].LABEL_Y), finalArray[i].NAME);
                        drawPoint(ctx, backgroundColor, color, finalArray[i].MARKER_X, finalArray[i].MARKER_Y, 8, 0, 2*Math.PI);
                    }
                } else {
                    console.error('No XML test points returned');
                }
            });
        }
    });
}

有两个 XML 文件。其中一个包含所有的点、线和标签。第二个仅包含必须显示的点和标签。

最佳答案

设置 Canvas 的尺寸会完全清除它,因此线条:

elem.setAttribute('width', canvasWidth);
elem.setAttribute('height', canvasHeight);

可能会让你的 Canvas “闪烁”。 GET 请求是异步的,因此在计算和绘制点数据之前 Canvas 会被清除。

要解决此问题,请在绘制之前更改请求回调中的尺寸。

关于javascript - HTML5 Canvas 刷新时闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17151999/

相关文章:

javascript - 更新服务中的新值

javascript - jquery - 翻译国家名称并对其进行排序

javascript - 在 DIV 标记内显示 jquery 规则/验证器错误消息

javascript - 如何防止 jQuery 解析插入的 HTML?

javascript - 是否可以在 TypeScript 的嵌套结构中使用不同的类型参数?

javascript - javascript从字符串中提取链接

javascript - 使用 Java 脚本的依赖下拉列表仅适用于更改主下拉列表,如果已选择主下拉列表,则它必须在页面加载时工作

javascript - 窗口调整大小确定控件父级更小还是更大

javascript - 实现CSS日期输入

javascript - 在没有 Node/npm 的情况下构建 SPA 前端