最简单的方法是使用另一个画布作为中间层。
这里我将忽略偏移画布,因为除非您想显示整个地图,否则不需要它。大概您需要的只是放大的区域。如果你想缩小,你可以简单地将整个图像绘制到你的视口窗口(通过向ctx.drawImage ( img, x, y, viewPort.width, viewPort.height ) 提供宽度和高度参数)。但是,您要确保您的图像被手动裁剪为适当的大小,这样图像就不会被拉伸,或者确保您的画布视口与您使用的图像具有相同的纵横比。
如果您希望背景的剪辑区域(实际查看区域)与视口窗口(放大/缩小查看区域)的大小不同(更小或更大),则以下方法有效。请注意,这与实际背景的大小无关。大概剪裁区域和视口窗口都比背景图像本身小。
例如:
// use these to determine where the clipping region lives
var offsetX = 0,
offsetY = 0,
clipWidth = <<yourChosenPixelWidth>>,
clipHeight = <<yourChosenPixelHeight>>,
clip = document.createElement ( "canvas" ),
clipCtx,
viewPort = document.getElementById ( "main-canvas" ),
viewCtx = viewPort.getContext ( "2d" ),
background = new Image (),
// offsetCanvas = document.getElementById ( "offset-canvas" ),
imgLoaded = false;
// configure the offset canvas once
background.src = "http://pixeljoint.com/files/icons/full/map__r1470206141.png";
background.onLoad = function() {
// the fiddle scales the image, here we don't
//offsetCanvas.width = background.width;
//offsetCanvas.height = background.height;
//offsetCtx = offsetCanvas.getContext ( "2d" );
//offsetCtx.drawImage ( background, 0, 0 );
imgLoaded = true;
}
clip.width = clipWidth;
clip.height = clipHeight;
clipCtx = clip.getContext ( "2d" );
function updateViewport () {
if ( imgLoaded ) {
// copy pixels from the background directly
// to the middle layer so we have a "clipped"
// but unscaled image object
//clipCtx.putImageData ( offsetCtx.getImageData ( offsetX, offsetY, clip.width, clip.height ) );
clipCtx.drawImage ( background, offsetX, offsetY );
// this is where rescaling happens
viewCtx.drawImage ( clip, 0, 0, viewPort.width, viewPort.height );
// and you're done!
}
}