2013-06-20 3 views
1

Я пытаюсь построить «бесконечный» график, идея состоит в том, что я буду перерисовывать холст в себя, перемещая его на один пиксель слева, а затем очищаю правый крайний столбец, рисуя пиксель в очищенном колонка. Но что-то не работает, и я не могу понять, что. Пример кода ниже:Полоса прокрутки горизонтально

var telemetryScreen, telemetryTimer; 

function displayUI() { 
    if (!telemetryScreen) { 
     telemetryScreen = document.createElement("div"); 
     telemetryScreen.className = "telemetry-screen"; 
     document.body.appendChild(telemetryScreen); 
    } 
    return telemetryScreen; 
} 

var plotFps = function(canvas) { 
    canvas.className = "telemetry-fps"; 
    canvas.width = 320; 
    canvas.height = 240; 
    canvas.getContext("2d").fillStyle = "red"; 
    if (!telemetryScreen) displayUI().appendChild(canvas); 
    return function (delta) { 
     var context = canvas.getContext("2d"); 
     context.drawImage(canvas, 1, 0, 319, 240, 0, 0, 319, 240); 
     context.clearRect(319, 0, 1, 240); 
     context.fillRect(319, 120 + delta, 1, 1); 
    }; 
}(document.createElement("canvas")); 

function startSampling() { 
    var now, delta, last, start = new Date().getTime(), 
    seconsPerFrame = 16; 
    if (telemetryTimer) clearInterval(telemetryTimer); 
    telemetryTimer = setInterval(
     function() { 
      last = now; 
      now = new Date().getTime(); 
      delta = now - last - seconsPerFrame; 
      plotFps(delta); 
     }, seconsPerFrame); 
    // We don't anticipate framerates 
    // higher then 60 fps 
} 

startSampling(); 

Я также попытался translate(), но она перестает работать после того, как полотно будет прокручивать более затем один из его ширины:/

ответ

1

Чтобы создать бесконечное панорамирование эффект:

  • Каждый кадр, нарисуйте изображение (или график) несколько пикселей слева от предыдущего кадра
  • Нарисуйте копию изображения (или график) справа в «пустых» пикселях

Вот базовый код для изображения (вы можете нарисовать свой график вместо):

var fps = 60; 
    var offsetLeft=0; 
    function pan() { 

     // increase the left offset 
     offsetLeft+=1; 
     if(offsetLeft>infiniteImageWidth){ offsetLeft=0; } 

     ctx.drawImage(infiniteImage,-offsetLeft,0); 
     ctx.drawImage(infiniteImage,infiniteImage.width-offsetLeft,0); 

     setTimeout(function() { 
      requestAnimFrame(pan); 
     }, 1000/fps); 
    } 

Вот код (вам нужно будет ввести свой собственный образ из-за глупой безопасности CORS):

Вы может игнорировать эффект «зеркального изображения», который использовался для создания плавного перехода на изображение горного пейзажа.

<!doctype html> 
<html> 
<head> 
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css --> 
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> 

<style> 
    body{ background-color: ivory; } 
    canvas{border:1px solid red;} 
</style> 

<script> 
$(function(){ 

    // thanks Paul Irish for this RAF fallback shim 
    window.requestAnimFrame = (function(callback) { 
     return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || 
     function(callback) { 
     window.setTimeout(callback, 1000/60); 
     }; 
    })(); 


    var canvas=document.getElementById("canvas"); 
    var ctx=canvas.getContext("2d"); 

    var infiniteImage; 
    var infiniteImageWidth; 
    var img=document.createElement("img"); 
    img.onload=function(){ 

     // use a tempCanvas to create a horizontal mirror image 
     // This makes the panning appear seamless when 
     // transitioning to a new image on the right 
     var tempCanvas=document.createElement("canvas"); 
     var tempCtx=tempCanvas.getContext("2d"); 
     tempCanvas.width=img.width*2; 
     tempCanvas.height=img.height; 
     tempCtx.drawImage(img,0,0); 
     tempCtx.save(); 
     tempCtx.translate(tempCanvas.width,0); 
     tempCtx.scale(-1,1); 
     tempCtx.drawImage(img,0,0); 
     tempCtx.restore(); 
     infiniteImageWidth=img.width*2; 
     infiniteImage=document.createElement("img"); 
     infiniteImage.onload=function(){ 
      pan(); 
     } 
     infiniteImage.src=tempCanvas.toDataURL(); 
    } 
    img.src="YourLandscapeImage.jpg"; 


    var fps = 60; 
    var offsetLeft=0; 
    function pan() { 

     // increase the left offset 
     offsetLeft+=1; 
     if(offsetLeft>infiniteImageWidth){ offsetLeft=0; } 

     ctx.drawImage(infiniteImage,-offsetLeft,0); 
     ctx.drawImage(infiniteImage,infiniteImage.width-offsetLeft,0); 

     setTimeout(function() { 
      requestAnimFrame(pan); 
     }, 1000/fps); 
    } 

}); // end $(function(){}); 
</script> 

</head> 

<body> 
    <canvas id="canvas" width=500 height=143></canvas><br> 
</body> 
</html> 
+0

Спасибо, я думаю, что в конце концов я решил это по-другому, но это тоже работает. (Я заменил 'clearRect' на' drawRect', который использовал цвет фона.) Все еще неудобно, что 'clearRect', похоже, не делает то, что он должен использовать, однако он не делает это последовательно в браузерах, поэтому он должен быть чем-то о своей цели, которую я не понимаю. –

Смежные вопросы