P5.js使用flexbox时如何避免canvas内文本、图像挤压变形
问题原因
- 你为canvas元素设置了
max-width: 100%规则,当侧边栏弹出挤压父容器宽度时,浏览器会通过CSS自动缩小canvas的显示尺寸,但p5.js内部的绘图缓冲区尺寸还是初始化时设定的宽度,两者比例不匹配就会导致画布内的文本、图形出现拉伸变形。 - 你仅在p5实例初始化时读取了一次父容器宽度,后续父容器尺寸变化时没有更新画布尺寸和相关的宽度变量,绘图逻辑始终基于初始宽度运行。
解决方案
1. 调整CSS规则,避免canvas被CSS强制缩放
修改你的canvas样式,移除max-width: 100%配置:
canvas{ margin:auto; display:block; }
2. 改造p5.js代码,新增尺寸动态更新逻辑
调整p5实例代码,新增父容器尺寸读取、画布重设的逻辑,同时监听窗口尺寸变化事件:
const typo = (sketch) => { let x1 = 0; let x2; let speed = 3; const ratio_responsive = 200 / 1500; let cvs_width; // 统一封装画布尺寸更新逻辑 function updateCanvasSize() { cvs_width = document.getElementById("canvas").offsetWidth; sketch.resizeCanvas(cvs_width, sketch.windowHeight); } sketch.setup = () => { updateCanvasSize(); sketch.textFont("Palatino"); }; // 监听窗口尺寸变化,自动更新画布 sketch.windowResized = () => { updateCanvasSize(); }; sketch.draw = () => { sketch.background(220); x1 += speed; x2 += speed; if (x2 > 0) { x1 = x2 - cvs_width; } if (x1 > 0) { x2 = x1 - cvs_width; } const typo_size = cvs_width * ratio_responsive; sketch.textSize(typo_size); sketch.text("TYPO CRUSHED", x1, 30, cvs_width, sketch.windowHeight); sketch.text("TYPO CRUSHED", x2, 30, cvs_width, sketch.windowHeight); } } let typo_sketch = new p5(typo, "canvas");
3. 调整侧边栏切换逻辑,动画结束后同步更新画布
因为你的侧边栏设置了300ms的显隐过渡动画,需要等动画完成后再更新画布尺寸,避免中间状态的尺寸偏差:
function toggle(){ $('main').on('click', '.toggle-sidebar', function(){ const sidebar = $('.sidebar'); sidebar.toggleClass('is-visible'); sidebar.toggle(300, function(){ // 触发resize事件,自动调用画布更新逻辑 window.dispatchEvent(new Event('resize')); }); }) }; toggle();
如果你需要侧边栏动画过程中画布也同步平滑缩放,可以在动画运行期间通过requestAnimationFrame持续调用updateCanvasSize方法,上述方案是性能开销最低的实现方式。
内容的提问来源于stack exchange,提问作者Herma
相关产品推荐
相关产品推荐

