我现在已经试图解决这个问题几天了,并且无法从类似的问题中解决这个问题。
有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;
目前,我获取鼠标点击的坐标,将相机设置到该位置,重置视口的变换矩阵,然后将视口的上下文转换为相机位置。
显然,我缺少这个理论的基本部分。
我错过了什么?
答案 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
);
};
整件事:
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;