Canvas绘制缩放图片失真,疑JS获取画布尺寸异常求助
问题
我希望在Canvas中按比例缩放绘制发型图片,但绘制后的图片出现失真。我认为比例计算逻辑无误,猜测失真原因是Canvas实际高度为400,但JavaScript中获取到的画布尺寸为150,特此咨询该猜测是否为失真的真正原因?
效果截图





HTML代码
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>A Basic HTML5 Template</title> <link rel="stylesheet" href="css/main-1.css"> <section id="fitting-room-section"> <canvas class="n-canvas" id="fitting-room-canvas"></canvas> </section> <button type="button" class="n-button">Click Me!</button> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.0/jquery.min.js"></script> </head> <body> <!-- your content here... --> <script src="js/script-1.js"></script> </body> </html>
CSS代码
.n-canvas { width: 100%; height: 100%; max-width: 300px; min-height: 400px; background-color: red; }
JS代码
$( document ).ready(function() { function drawImageScaled() { let canvas = document.getElementById('fitting-room-canvas'); let ctx = canvas.getContext('2d'); let img = new Image(); img.src = 'img/bob.png'; img.onload = function(){ let imgWidth = canvas.width * (2 / 3); // 图片宽度占画布宽度的三分之二 var ratio = imgWidth / img.width; // 图片缩放比例 let imgHeight = img.height * ratio; // 按比例计算图片高度 ctx.drawImage(img, 0, 0, imgWidth, imgHeight); } } jQuery( ".n-button" ).on( "click", drawImageScaled); console.log( "ready!" ); });
回答
你的猜测完全正确,这就是图片失真的核心原因。
Canvas有两个独立的尺寸属性:
- 绘图像素尺寸:由
canvas.width和canvas.height属性控制,这是Canvas内部的绘图画布大小,默认值为300x150 - 页面显示尺寸:由CSS的
width/height控制,仅决定Canvas在页面上的视觉展示大小
你只通过CSS把Canvas的显示高度设为400px,但没有设置Canvas本身的height属性,导致:
- JS中获取到的
canvas.height是默认的150px,绘图时是在300x150的像素画布上绘制 - 绘制完成后,CSS把这个300x150的画布拉伸到400px高度显示,自然会出现拉伸失真
解决方法有两种:
- 在HTML中直接给Canvas设置宽高属性:
<canvas class="n-canvas" id="fitting-room-canvas" width="300" height="400"></canvas>
- 在JS初始化时同步绘图尺寸和显示尺寸:
$( document ).ready(function() { const canvas = document.getElementById('fitting-room-canvas'); // 获取Canvas的实际显示尺寸 const rect = canvas.getBoundingClientRect(); // 同步绘图尺寸 canvas.width = rect.width; canvas.height = rect.height; function drawImageScaled() { let ctx = canvas.getContext('2d'); let img = new Image(); img.src = 'img/bob.png'; img.onload = function(){ let imgWidth = canvas.width * (2 / 3); var ratio = imgWidth / img.width; let imgHeight = img.height * ratio; ctx.drawImage(img, 0, 0, imgWidth, imgHeight); } } jQuery( ".n-button" ).on( "click", drawImageScaled); console.log( "ready!" ); });
两种方法都能让Canvas的绘图尺寸和显示尺寸一致,避免拉伸失真。
内容的提问来源于stack exchange,提问作者Kifsif
相关产品推荐
相关产品推荐

