9

Web プロジェクトで JavaScript を使用してキャンバスを作成しています。

キャンバスには、xy 平面上にグラフィカルな表現があります。

キャンバスに横スクロール機能を追加しようとしています。

私はいくつかの方法論を調査しました:-

1) キャンバスに 12 か月分のデータを描画し、マウスを前方にスクロールすると 1 か月目のデータが消え、最後に新しい月のデータが追加され、新しいキャンバスが描画されます。

短所:-マウスがスクロールしてタイムラインをパンするたびに、新しい SQL クエリを作成する必要があり、Web アプリケーションが非常に遅くなります。

2) 1 つの SQL クエリでキャンバスに 10 年分のデータを描画できるかもしれませんが、12 か月分のデータしか表示できません。残りの9年間を隠します。クライアントがスクロールすると、スクロール イベントをキャプチャし、キャンバスの適切な部分に移動します。これは可能ですか?もしそうなら、どのように?

誰でもアドバイスできますか?

キャンバスの現在の表現 = 12 か月分のデータのみ

キャンバスの現在の表現 = 12 か月分のデータのみ

スクロールをより具体的にするために、クライアント側のスクロール アクションに次のようなウィジェットを使用したいと思います:-

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

4

3 に答える 3

12

これはかなり基本的な実装です: 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();
  }
}

グリッドを作成するには、次のようにします。

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);

これは次のように使用されます。

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();
  }
}

更新されたデモ: http://jsfiddle.net/CQPeU/2/

于 2013-01-16T23:07:14.350 に答える
2

@Shmiddty からの回答のすべてのマウス移動イベントで再描画を回避するには、キャンバス全体を特大サイズで描画してから、CSS マージン プロパティを変更します。これは、キャンバスのコンテンツがより複雑になると、パフォーマンスが大幅に向上します。

ここにデモがあります: 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);
于 2016-04-09T00:32:29.760 に答える
-1

次のプラグインで Phaser Framework を使用することをお勧めしますhttp://jdnichollsc.github.io/Phaser-Kinetic-Scrolling-Plugin/

于 2015-07-12T19:41:00.777 に答える