用于Web应用程序的HTML5 Canvas视口

时间:2014-09-18 11:18:28

标签: javascript html5 canvas

我现在已经试图解决这个问题几天了,并且无法从类似的问题中解决这个问题。

有2幅画布,一个缩放视口,显示较大背景的一部分,以及缩小的相机地图。单击第二个画布时,视口应移动到背景区域。



var onClick,
onLoad = function () {
    var canvas,
        viewport,
        context,
        canvasWidth,
        canvasHeight,
        viewportContext,
        background = {},
        camera,
        scale = 4;

    function init() {
        background.image = new Image();
        background.image.src = "http://upload.wikimedia.org/wikipedia/commons/4/4e/Coronation_of_Ahmad_Shah_Durrani_in_1747_by_Breshna.jpg";
        canvas = document.getElementById("canvas");
        context = canvas.getContext("2d");
        viewport = document.getElementById("viewport");
        viewportContext = viewport.getContext("2d");
        camera = {
            x: canvas.width/2,
            y: canvas.height/2,
            width: canvas.width/scale,
            height: canvas.height/scale
        };
        background.width = canvas.width * scale;
        background.height = canvas.height * scale;
       
    };
	
  	// Translate viewport's context to camera pos
    function moveContext() {
        viewportContext.setTransform(1, 0, 0, 1, 0, 0); // Reset context
        viewportContext.translate(camera.x*scale, camera.y*scale);
    };
	
  	// Update camera's position
    function moveCamera(vector) {
        camera.x = vector.x;
        camera.y = vector.y;
        moveContext();
    };

    function draw() {
        context.drawImage(background.image, 0, 0, canvas.width, canvas.height);
      // Draw camera guide
        context.strokeStyle = 'red';
        context.beginPath();
        context.moveTo(camera.x - camera.width / 2, camera.y - camera.height / 2);
        context.lineTo(camera.x + camera.width / 2, camera.y - camera.height / 2);
        context.lineTo(camera.x + camera.width / 2, camera.y + camera.height / 2);
        context.lineTo(camera.x - camera.width / 2, camera.y + camera.height / 2);
        context.lineTo(camera.x - camera.width / 2, camera.y - camera.height / 2);
        context.stroke();
		
      	// Draw viewport background
        viewportContext.clearRect(0, 0, viewport.width, viewport.height);
        viewportContext.drawImage(background.image, -background.width/2, -background.height/2, background.width, background.height);
    };

    function update() {
    };

    function gameLoop() {
        update();
        draw();
        requestAnimationFrame(gameLoop);
    };


    onClick = function (event) {
        var x = event.offsetX,
            y = event.offsetY;

        //alert("x: " + x + "\ny: " + y);
        moveCamera({ x: x, y: y });
    };


    init();
    requestAnimationFrame(gameLoop);

    
};

if (window.addEventListener) {
    window.addEventListener("load", onLoad, false);
    window.addEventListener("click", function () { onClick(event) }, false);
}

canvas {
  display:block;
  margin:15px;
  border:1px solid #000;
}

<canvas id="viewport" width="400" height="240">HTML5 Canvas not supported!</canvas>
<canvas id="canvas" width="400" height="240"></canvas>
&#13;
&#13;
&#13;

目前,我获取鼠标点击的坐标,将相机设置到该位置,重置视口的变换矩阵,然后将视口的上下文转换为相机位置。

显然,我缺少这个理论的基本部分。

我错过了什么?

1 个答案:

答案 0 :(得分:1)

你需要修改你的转换,就像我在评论中所说的那样。试试这个:

    function moveContext() {
        viewportContext.setTransform(1, 0, 0, 1, 0, 0); // Reset context
        viewportContext.translate(
            (viewport.width/2-camera.x+camera.width/2)*scale,
            (viewport.height/2-camera.y+camera.height/2)*scale
        );
    };

整件事:

&#13;
&#13;
var onClick,
onLoad = function () {
    var canvas,
        viewport,
        context,
        canvasWidth,
        canvasHeight,
        viewportContext,
        background = {},
        camera,
        scale = 4;

    function init() {
        background.image = new Image();
        background.image.src = "http://upload.wikimedia.org/wikipedia/commons/4/4e/Coronation_of_Ahmad_Shah_Durrani_in_1747_by_Breshna.jpg";
        canvas = document.getElementById("canvas");
        context = canvas.getContext("2d");
        viewport = document.getElementById("viewport");
        viewportContext = viewport.getContext("2d");
        camera = {
            x: canvas.width/2,
            y: canvas.height/2,
            width: canvas.width/scale,
            height: canvas.height/scale
        };
        background.width = canvas.width * scale;
        background.height = canvas.height * scale;
       
    };
	
  	// Translate viewport's context to camera pos
    function moveContext() {
        viewportContext.setTransform(1, 0, 0, 1, 0, 0); // Reset context
        viewportContext.translate(
            (viewport.width/2-camera.x+camera.width/2)*scale,
            (viewport.height/2-camera.y+camera.height/2)*scale
        );
    };
	
  	// Update camera's position
    function moveCamera(vector) {
        camera.x = vector.x;
        camera.y = vector.y;
        moveContext();
    };

    function draw() {
        context.drawImage(background.image, 0, 0, canvas.width, canvas.height);
      // Draw camera guide
        context.strokeStyle = 'red';
        context.beginPath();
        context.moveTo(camera.x - camera.width / 2, camera.y - camera.height / 2);
        context.lineTo(camera.x + camera.width / 2, camera.y - camera.height / 2);
        context.lineTo(camera.x + camera.width / 2, camera.y + camera.height / 2);
        context.lineTo(camera.x - camera.width / 2, camera.y + camera.height / 2);
        context.lineTo(camera.x - camera.width / 2, camera.y - camera.height / 2);
        context.stroke();
		
      	// Draw viewport background
        viewportContext.clearRect(0, 0, viewport.width, viewport.height);
        viewportContext.drawImage(background.image, -background.width/2, -background.height/2, background.width, background.height);
    };

    function update() {
    };

    function gameLoop() {
        update();
        draw();
        requestAnimationFrame(gameLoop);
    };


    onClick = function (event) {
        var x = event.offsetX,
            y = event.offsetY;

        //alert("x: " + x + "\ny: " + y);
        moveCamera({ x: x, y: y });
    };


    init();
    requestAnimationFrame(gameLoop);

    
};

if (window.addEventListener) {
    window.addEventListener("load", onLoad, false);
    window.addEventListener("click", function () { onClick(event) }, false);
}
&#13;
canvas {
  display:block;
  margin:15px;
  border:1px solid #000;
}
&#13;
<canvas id="viewport" width="400" height="240">HTML5 Canvas not supported!</canvas>
<canvas id="canvas" width="400" height="240"></canvas>
&#13;
&#13;
&#13;