如何将大Canvas完整缩小复制到小Canvas中?
问题描述
我有两个Canvas,一个大一个小。希望小Canvas完整镜像大Canvas的全部内容并缩小适配,但目前仅能复制大Canvas的角落区域。大Canvas后续要支持绘图功能,小Canvas需要同步镜像其内容。
基础示例代码如下:
<!DOCTYPE html> <html lang="en"> <head> <script type="text/javascript"> var bigCanvas = document.getElementById("bigCanvas") var bigContext = bigCanvas.getContext("2d"); bigContext.fillStyle="red"; bigContext.fillRect(0, 0, bigCanvas.height, bigCanvas.width); bigContext.fillStyle="blue"; bigContext.fillRect(bigCanvas.height/3, bigCanvas.height/3, bigCanvas.height/3, bigCanvas.width/3); bigContext.fillStyle="white"; bigContext.fillRect(7,7,7,7); var smallCanvas = document.getElementById("smallCanvas"); var smallContext = smallCanvas.getContext("2d"); function dupe(){ smallContext.drawImage(bigCanvas,0,0) } </script> </head> <body> <canvas id="bigCanvas" height="280" width="280"></canvas> <canvas id="smallCanvas" height="28" width="28"></canvas> <button id="duplciateBtn" onclick="dupe()">Duplicate</button> </body> </html>
我尝试调整过大、小Canvas的context scale,但没解决问题。最接近的效果是把大Canvas的context scale设为(0.1,0.1),但这会让大Canvas本身缩小,而我需要大Canvas保持原有尺寸。

解决方案
问题出在drawImage的调用方式上——你只传入了源Canvas和起始坐标,这会默认按源尺寸绘制,导致小Canvas只能显示大Canvas的左上角区域。要实现完整缩放适配,需要使用drawImage的完整参数形式:
function dupe(){ // 先清空小Canvas的旧内容,避免残留 smallContext.clearRect(0, 0, smallCanvas.width, smallCanvas.height); // 绘制时指定源区域和目标区域,实现完整缩放 smallContext.drawImage( bigCanvas, 0, 0, bigCanvas.width, bigCanvas.height, // 截取整个大Canvas作为源 0, 0, smallCanvas.width, smallCanvas.height // 填充满整个小Canvas ); }
核心说明
drawImage的完整参数格式是:drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
sx, sy, sWidth, sHeight:定义从源Canvas截取的区域,这里直接取整个大Canvas的尺寸dx, dy, dWidth, dHeight:定义在小Canvas上绘制的位置和尺寸,这里设置为小Canvas的完整尺寸,就能让大Canvas内容等比例缩放到小Canvas中
适配动态绘图的扩展
如果大Canvas要支持实时绘图(比如鼠标手绘),可以通过两种方式同步:
- 监听绘图事件:在大Canvas的绘图操作结束后触发同步
// 示例:鼠标松开时同步 bigCanvas.addEventListener('mouseup', dupe);
- 定时同步:适合连续绘制的场景,每隔一段时间同步一次
// 每100毫秒同步一次,可根据需求调整间隔 setInterval(dupe, 100);
内容的提问来源于stack exchange,提问作者Steven B
相关产品推荐
相关产品推荐

