Safari中重叠Canvas导致图片模糊的原因及解决方法
解决Canvas叠加导致下方图片模糊的问题
当在图片上方叠加透明HTML Canvas后,显示Canvas时下方图片会出现像素化模糊(隐藏Canvas时图片清晰),如何避免这个问题?


复现代码
HTML
<button onclick="hideCanvas()">隐藏Canvas</button> <button onclick="showCanvas()">显示Canvas</button> <div class="transformed"> <div style="background-size:contain;background-image:url('https://zwibbler.com/clipart/image/105446-2000px.png');width:1000px;height:1000px;background-size:contain"></div> <canvas id="mycanvas" width="500" height="500" style="display:none"></canvas> </div>
CSS
button { z-index: 1; } .transformed { position: relative; transform: translateX(-0.3px) translateY(0.88px) scale(2.0); transform-origin: top left; } #mycanvas { position: absolute; border: 2px solid green; left: 0; top: 0; }
JavaScript
function hideCanvas() { document.querySelector("#mycanvas").style.display = "none"; } function showCanvas() { document.querySelector("#mycanvas").style.display = "inline-block"; } // 在Canvas上绘制内容触发问题 let ctx = document.querySelector("#mycanvas").getContext("2d"); ctx.beginPath(); ctx.moveTo(0,0); ctx.lineTo(50, 50); ctx.strokeStyle="green"; ctx.lineWidth=5; ctx.stroke();
解决方法
这个问题本质是浏览器的渲染优化逻辑导致的:当容器内包含Canvas元素时,浏览器会将整个容器先渲染成一张位图,再执行缩放变换,图片经过二次缩放后就会变得模糊。可以试试下面几种解决方式:
给Canvas开启硬件加速
在Canvas的CSS中添加transform: translateZ(0),强制让GPU单独渲染Canvas,避免和图片合并后被低精度处理:#mycanvas { position: absolute; border: 2px solid green; left: 0; top: 0; transform: translateZ(0); }让Canvas尺寸匹配变换后的显示大小
父容器用了scale(2.0)的放大变换,直接把Canvas的CSS宽高设置为和图片容器一致的1000px,让Canvas无需被缩放,也就不会触发容器的位图渲染逻辑:#mycanvas { position: absolute; border: 2px solid green; left: 0; top: 0; width: 1000px; height: 1000px; }给父容器添加渲染优化提示
给.transformed容器添加will-change: transform,提前告诉浏览器这个元素会执行变换操作,让浏览器提前优化渲染逻辑:.transformed { position: relative; transform: translateX(-0.3px) translateY(0.88px) scale(2.0); transform-origin: top left; will-change: transform; }
内容的提问来源于stack exchange,提问作者Steve Hanov
相关产品推荐
相关产品推荐

