Javascript HTML5画布在刷新时闪烁
我需要每隔两三秒刷新一次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
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文件。。。