2013-01-16 14 views
9

Tworzę płótno przez javascript na webproject.Przewijanie w poziomie na płótnie. HTML5

Obszar roboczy zawiera graficzne reprezentacje na płaszczyźnie XY.

Próbuję dodać funkcję przewijania poziomego do obszaru roboczego.

I zbadali kilka metod: -

1) opracowuje 12 miesięcy o wartości danych na płótnie, gdy przewija myszy do przodu, dane 1. miesiąc znika, a na końcu nowe dane miesięcy dodaje, rysuje się nowe płótno.

Con: - Za każdym razem, gdy mysz przesunie się, aby przesuwać się wzdłuż osi czasu - należy utworzyć nowe zapytanie SQL, dzięki czemu moja aplikacja internetowa będzie bardzo wolna.

2) może mogę narysować dane o wartości 10 lat na płótnie za pomocą 1 zapytania SQL, ale pokażę dane tylko na 12 miesięcy. maskowanie reszty z 9 lat. Teraz, gdy klient przewija, przechwytuję zdarzenie przewijania i przechodzę do odpowiedniej części kanwy. czy to możliwe? Jeśli tak, to w jaki sposób?

Czy ktoś może doradzić?

My current representation of the canvas = with only 12 months worth of data

Moja obecna reprezentacja płótnie = tylko 12 miesięcy o wartości danych

Aby być bardziej szczegółowe na przewijanie, chciałbym mieć uczucie, takie jak następujący widget dla mojej stronie klienta działania przewijania: -

http://www.simile-widgets.org/timeline/

+1

SVG jest ogólnie uważane za bardziej odpowiednie narzędzie dla danych kreślenia, po prostu mówiąc. – Shmiddty

+0

Ale to, co chcesz zrobić, to użyć 'context.translate (-x, 0)' do symulacji efektu. W ten sposób nie będziesz musiał zmieniać współrzędnych x punktów danych. – Shmiddty

Odpowiedz

12

Oto dość podstawowy realizacja: http://jsfiddle.net/CQPeU/

var can = document.getElementById("can"), 
    ctx = can.getContext('2d'), 
    dragging = false, 
    lastX = 0, 
    translated = 0; 

// these two lines will make the y-axis grow upwards. 
ctx.scale(1,-1); 
ctx.translate(0, -400); 

can.onmousedown = function(e){ 
    var evt = e || event; 
    dragging = true; 
    lastX = evt.offsetX; 
} 

window.onmousemove = function(e){ 
    var evt = e || event; 
    if (dragging){ 
    var delta = evt.offsetX - lastX; 
    translated += delta; 
    ctx.translate(delta, 0); // translate the context. 
    lastX = evt.offsetX; 
    draw(); // redraw 
    } 
} 

window.onmouseup = function(){ 
    dragging = false; 
} 


function draw() { 
    ctx.clearRect(-translated, 0, 600, 400); // this is why we need to keep track of how much we've translated 
    for (var i = 0; i < plot.length; i++) { 
    ctx.beginPath(); 
    ctx.arc(plot[i].x, plot[i].y, 5, 0, 2 * Math.PI); // note we don't have to futz with the x/y values, and can use them directly. 
    ctx.fill(); 
    } 
} 

Aby utworzyć siatkę, można zrobić coś takiego:

var grid = (function(dX, dY){ 
    var can = document.createElement("canvas"), 
     ctx = can.getContext('2d'); 
    can.width = dX; 
    can.height = dY; 
    // fill canvas color 
    ctx.fillStyle = 'black'; 
    ctx.fillRect(0, 0, dX, dY); 

    // x axis 
    ctx.strokeStyle = 'orange'; 
    ctx.moveTo(.5, 0.5); 
    ctx.lineTo(dX + .5, 0.5); 
    ctx.stroke(); 

    // y axis 
    ctx.moveTo(.5, .5); 
    ctx.lineTo(.5, dY + .5); 
    ctx.stroke(); 

    return ctx.createPattern(can, 'repeat'); 
})(100, 50); 

który byłby stosowany następująco:

function draw() { 
    ctx.clearRect(-translated, 0, 600, 400); 
    ctx.rect(-translated, 0, 600, 400); 
    ctx.fillStyle = grid; 
    ctx.fill(); 
    ctx.fillStyle = "#fff"; 
    for (var i = 0; i < plot.length; i++) { 
    ctx.beginPath(); 
    ctx.arc(plot[i].x, plot[i].y, 5, 0, 2 * Math.PI); 
    ctx.fill(); 
    } 
} 

Updated demo: http://jsfiddle.net/CQPeU/2/

+0

w porządku w końcu !! – Philo

+0

dzięki temu podejściu pojawia się nowy problem - statyczne etykiety na osi Y. takich jak: - http://jsfiddle.net/WNpKE/10/ – Philo

+0

Proponuję umieścić je na osobnej warstwie (innym płótnie lub jako normalne elementy DOM). – Shmiddty

3

Aby uniknąć przerysowania w każdym zdarzeniu Mouse Move w odpowiedzi z @Shmiddty, możesz narysować całe płótno ponad rozmiar, a następnie zmienić właściwość CSS margin. Jest to znaczący wzrost wydajności, gdy zawartość płótna staje się bardziej złożona.

Oto demo: https://jsfiddle.net/ax7n8944/

HTML:

<div id="canvasdiv" style="width: 500px; height: 250px; overflow: hidden"> 
    <canvas id="canvas" width="10000px" height="250px"></canvas> 
</div> 

JS:

var canvas = document.getElementById("canvas"); 
var context = canvas.getContext('2d'); 
var dragging = false; 
var lastX; 
var marginLeft = 0; 

for (var i = 0; i < 1000; i++) { 
    context.beginPath(); 
    context.arc(Math.random() * 10000, Math.random() * 250, 20.0, 0, 2 * Math.PI, false); 
    context.stroke(); 
} 

canvas.addEventListener('mousedown', function(e) { 
    var evt = e || event; 
    dragging = true; 
    lastX = evt.clientX; 
    e.preventDefault(); 
}, false); 

window.addEventListener('mousemove', function(e) { 
    var evt = e || event; 
    if (dragging) { 
     var delta = evt.clientX - lastX; 
     lastX = evt.clientX; 
     marginLeft += delta; 
     canvas.style.marginLeft = marginLeft + "px"; 
    } 
    e.preventDefault(); 
}, false); 

window.addEventListener('mouseup', function() { 
    dragging = false; 
}, false); 
Powiązane problemy