HTML 5 キャンバスに描画されたベクトルに基づいて、最初のほぼ複雑なマップを作成しようとしています。
スケーリングを除いて、うまく機能します。次のことに気付きました。
- Firefox では、すべてが正常に動作します (マウスホイールを除くが、これはテスト用です)。
- Chrome では、マウスホイールを使用して倍率 < 1 にズームアウトすると、描画されるたびに画像が複製されるように見えます
- Android と iOS では、ズーム ジェスチャを使用すると、最大の問題があります。画像が再描画されるたびに画像が複製されます。
最初は私のせいだと思いました。キャンバスがクリアされないのかもしれません。しかし、いくつかのテストの後、「ゴースト」が消え、新しいゴーストが表示されます。
誰かが助けてくれたら最高です。
コード - HTML:
<div>
<div style="position:absolute;top:30px;z-index:102;">
<canvas id="canvas" width="1386" height="747" style="position:absolute;"></canvas>
</div>
<div style="position:absolute; top:30px;" id="debugText">Debug</div>
<div style="position:absolute;top:30px; visibility: hidden;">
<canvas id="debugCanvas" width="1386" height="747"></canvas>
</div>
<div style="position:absolute; left: 200px;z-index:99;" id="debugContols">
<a href="#" onClick="javascript:zoomIn(0, 0, 0.5);">Zoom 0.5</a>
<a href="#" onClick="javascript:zoomIn(0, 0, 2);">Zoom 2</a>
<a href="#" onClick="javascript:zoomIn(0, 0, 3);">Zoom 3</a>
</div>
</div>
コード - Javascript:
var canvas = document.getElementById("canvas");
var debugCanvas = document.getElementById("debugCanvas");
var ctx = canvas.getContext("2d");
var ctxDebug = debugCanvas.getContext("2d");
var context = ctx;
var scale = 1;
var originx = 0;
var originy = 0;
function draw() {
// plne/Straen
[find drawing in fiddle, since its too long]
}
this.onmousewheel = function(event) {
var mousex = event.clientX - canvas.offsetLeft;
var mousey = event.clientY - canvas.offsetTop;
var wheel = event.wheelDelta/120;//n or -n
//according to Chris comment
var zoom = Math.pow(1 + Math.abs(wheel)/2 , wheel > 0 ? 1 : -1);
zoomIn(mousex, mousey, zoom);
return;
}
var isZooming = false;
var distances = new Array();
function touchStart(e) {
preventDefaultScroll(e);
if(e.touches.length > 1 && isZooming == false) {
var touch1 = event.touches[0];
var touch2 = event.touches[1];
x1 = touch1.pageX;
y1 = touch1.pageY;
x2 = touch2.pageX;
y2 = touch2.pageY;
var diffX = x2 - x1;
var diffY = y2 - y1;
var centerX = x1 + diffX/2;
var centerY = y1 + diffY/2;
//$("#debugText").text(centerX + " " + centerY);
debugCanvas.width = debugCanvas.width;
ctxDebug.beginPath();
ctxDebug.arc(centerX, centerY, 20, 0, 2 * Math.PI, false);
ctxDebug.fillStyle = 'green';
ctxDebug.fill();
ctxDebug.lineWidth = 5;
ctxDebug.strokeStyle = '#003300';
ctxDebug.stroke();
zoomCenterX = centerX;
zoomCenterY = centerY;
var touch1 = event.touches[0];
var touch2 = event.touches[1];
x1 = touch1.pageX;
y1 = touch1.pageY;
x2 = touch2.pageX;
y2 = touch2.pageY;
var distanz = dist(x1,y1,x2,y2);
lastDistance = distanz;
distanceInterval = setInterval(checkDistance,50);
isZooming = true;
}
}
var distanceInterval;
var zoomCenterX;
var zoomCenterY;
var lastDistance = 0;
function checkDistance()
{
$("#debugText").text("checkDist");
if(distances.length == 0) return;
var distanceGesamt = 0;
for(var i = 0; i < distances.length; i++)
{
distanceGesamt += distances[i];
}
var distanceDurchschnitt = distanceGesamt / distances.length;
var curDist = distanceDurchschnitt - lastDistance;
var zoomFac = 1 + (curDist / 100);
$("#debugText").text(distanceDurchschnitt + " " + zoomFac);
distances = new Array();
zoomIn(zoomCenterX, zoomCenterY, zoomFac)
lastDistance = distanceDurchschnitt;
}
function touchEnd(e)
{
if(e.touches.length < 2)
{
isZooming = false;
clearInterval(distanceInterval);
}
}
function dist(x1,y1,x2,y2)
{
return Math.sqrt((x1 -= x2) * x1 + (y1 -= y2) * y1);
}
function touchMove(e)
{
if(isZooming)
{
var touch1 = event.touches[0];
var touch2 = event.touches[1];
x1 = touch1.pageX;
y1 = touch1.pageY;
x2 = touch2.pageX;
y2 = touch2.pageY;
var distanz = dist(x1,y1,x2,y2);
distances.push(distanz);
}
}
function preventDefaultScroll(event) {
event.preventDefault();
window.scroll(0,0);
return false;
}
canvas.addEventListener('gestureend', function(e) {
if (e.scale < 1.0) {
// User moved fingers closer together
} else if (e.scale > 1.0) {
// User moved fingers further apart
}
}, false);
function zoomIn(mousex, mousey, zoom)
{
canvas.style.display = 'none';
context.translate(
originx,
originy
);
context.scale(zoom,zoom);
context.translate(
-( mousex / scale + originx - mousex / ( scale * zoom ) ),
-( mousey / scale + originy - mousey / ( scale * zoom ) )
);
originx = ( mousex / scale + originx - mousex / ( scale * zoom ) );
originy = ( mousey / scale + originy - mousey / ( scale * zoom ) );
scale *= zoom;
requestAnimFrame(function() {
context.clearRect(0,0,canvas.width,canvas.height);
draw();
});
canvas.style.display = 'block';
//context.clearRect(0,0,canvas.width,canvas.height);
}
$(document).ready(function() {
draw();
addEventListener('touchstart', touchStart, true);
addEventListener('touchmove', touchMove, true);
addEventListener('touchend', touchEnd, true);
addEventListener('touchcancel', touchEnd, true);
});
window.requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function( callback ){
window.setTimeout(callback, 1000 / 60);
};
})();