Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/444.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML5画布在刷新时闪烁_Javascript_Jquery_Html_Html5 Canvas_Setinterval - Fatal编程技术网

Javascript HTML5画布在刷新时闪烁

Javascript HTML5画布在刷新时闪烁,javascript,jquery,html,html5-canvas,setinterval,Javascript,Jquery,Html,Html5 Canvas,Setinterval,我需要每隔两三秒刷新一次HTML5画布 setInterval(writeCanvas, 2000); 这个画布充满了点和线。每个横坐标和纵坐标都存储在一个XML文件中。因此,在更新画布之前,我对服务器上的文件执行异步请求 问题是画布会闪烁。我猜它在异步请求运行时消失了 我怎样才能避开这个问题呢 以下是writeCanvas的代码: function drawLines(ctx, back, front, width, xArray, yArray) { ctx.strokeStyle

我需要每隔两三秒刷新一次HTML5画布

setInterval(writeCanvas, 2000);
这个画布充满了点和线。每个横坐标和纵坐标都存储在一个XML文件中。因此,在更新画布之前,我对服务器上的文件执行异步请求

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

我怎样才能避开这个问题呢

以下是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');
                }
            });
        }
    });
}
功能绘图线(ctx、背面、正面、宽度、X线、Y线){
ctx.strokeStyle=返回;
ctx.fillStyle=前部;
ctx.lineWidth=宽度;
ctx.beginPath();
ctx.moveTo(xArray[0],yArray[0]);

对于(var i=1;i设置画布的维度会将其完全清除,因此行:

elem.setAttribute('width', canvasWidth);
elem.setAttribute('height', canvasHeight);
可能会使画布“闪烁”。GET请求是异步的,因此在计算和绘制点数据之前,画布会被清除


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

设置画布的尺寸会将其完全清除,因此行:

elem.setAttribute('width', canvasWidth);
elem.setAttribute('height', canvasHeight);
可能会使画布“闪烁”。GET请求是异步的,因此在计算和绘制点数据之前,画布会被清除


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

Crogo已经在回答中提到了可能的原因,但作为解决方法,您可以:

if (elem.width !== canvasWidth || elem.height !== canvasHeight) {
    // apply the final size to the canvas
    elem.setAttribute('width', canvasWidth);
    elem.setAttribute('height', canvasHeight);
}
画布大小仅在大小更改时设置

您还应尽量避免使用
setInterval
(如果客户端连接速度慢/不稳定,导致加载数据的时间超过2秒,该怎么办)。如果下载仍在进行,并且
setInterval
触发,则在第一个下载仍在下载的情况下,您将启动另一个下载。您还将面临被删除的风险当这些调用在事件队列中堆叠时,画布上会显示“双绘图”:

而是从
writeCanvas()内部触发
setTimeout


当然,如果必须每两秒钟加载一次数据,这将是不准确的(并不是说
setInterval
是..它们都只是给出了一个估计值)。

Crogo在回答中已经提到了可能的原因,但作为一项解决方法,您可以:

if (elem.width !== canvasWidth || elem.height !== canvasHeight) {
    // apply the final size to the canvas
    elem.setAttribute('width', canvasWidth);
    elem.setAttribute('height', canvasHeight);
}
画布大小仅在大小更改时设置

您还应尽量避免使用
setInterval
(如果客户端连接速度慢/不稳定,导致加载数据的时间超过2秒,该怎么办)。如果下载仍在进行,并且
setInterval
触发,则在第一个下载仍在下载时,您将启动另一个下载。您还将面临以下风险“当这些调用在事件队列中堆叠时,将“双绘图”添加到画布:

而是从
writeCanvas()内部触发
setTimeout


当然,如果必须每两秒钟加载一次数据,这将是不准确的(并不是说
setInterval
是..它们都只给出一个估计值).

你应该发布writeCanvas函数的代码在异步请求完成之前调用的
clearRect
的可能性有多大?我添加了代码。这有点复杂,但我正在尽最大努力处理现有的XML文件…你应该发布writeCanvas函数的代码他获得
clearRect在异步请求完成之前调用?我添加了代码。这有点复杂,但我正在尽最大努力处理现有的XML文件。。。