2013-06-17 4 views
0

2 ~ 3 초마다 HTML5 캔버스를 새로 고침해야합니다.새로 고침하는 동안 HTML5 캔버스가 깜박입니다.

setInterval(writeCanvas, 2000); 

이 캔버스는 점과 선으로 채워져 있습니다. 각 가로 좌표와 세로 좌표는 XML 파일에 저장됩니다. 그래서 캔버스를 업데이트하기 전에 서버의 파일에 비동기 요청을합니다.

문제는 캔버스가 깜박이는 것입니다. 비동기 요청이 실행되는 동안 사라지는 것 같아요.

어떻게이 문제를 해결할 수 있습니까?

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 파일이 있습니다 : 여기

는 writeCanvas의 코드입니다. 하나는 모든 점, 선 및 레이블을 포함합니다. 두 번째는 표시해야하는 점과 레이블 만 포함합니다.

+1

writeCanvas 함수 –

+0

의 코드를 게시해야합니다. 비동기 요청이 완료되기 전에 _ 호출되는 'clearRect'가 무엇인지 알 수 있습니까? – Alnitak

+0

코드를 추가했습니다. 그것은 약간 복잡하지만 기존 XML 파일로 최선을 다하고 있습니다 ... – Maxbester

답변

0

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 트리거가 발생하면 첫 번째 다운로드가 계속 진행되는 동안 다른 다운로드가 시작됩니다. 이러한 호출이 이벤트 큐에 쌓아로 캔버스에 "이중 도면"을 얻을 위험합니다

은 오히려 내부에서 setTimeout를 트리거하여 writeCanvas() : 물론

function writeCanvas() 
{ 
    //... load and draw 

    setTimeout(writeCanvas, 1500); //compensate for time 
} 

, 데이터를해야하는 경우 2 초마다로드됩니다. 정확하지 않습니다. (setInterval은 아닙니다. 둘 다 예상치 만 제공합니다).

3

캔버스 설정 '차원은 완전히 지워 때문에 라인 :

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

가 캔버스 할 가능성이있다'깜박 '. GET 요청은 비동기 적이므로 포인트 데이터가 계산되고 그려지기 전에 캔버스가 지워집니다.

이 문제를 해결하려면 그리기 전에 요청 콜백 내의 크기를 변경하십시오.

관련 문제