📣 背景
最近在工作中,遇到了用户如果缩放浏览器窗口,或者使用 mac 笔记本的触摸板缩放浏览器窗口时,canvas 会模糊的问题,
原因很简单,缩放之后,浏览器的 window.devicePixelRatio
已经发生改变,所以要用最新的 devicePixelRatio
去绘制
window.resize 为什么不行?
对于用户使用键盘,比如 commond + +
和 common + -
缩放时,事情很好办,使用 resize
事件即可
1 | <body> |
那么如果换成 mac 的触摸板双指缩放呢?
尴尬了,window.resize 表示:大哥,超纲了?从图中可以看出来,事件没有相应
给力的 VisualViewport
面向 Google 编程了一段时间,总算找到了 浏览器的一个实验性功能,根据 MDN 的描述:
Visual Viewport API 提供了当前页面的视觉视口接口,即
VisualViewport
。对于每个页面容器来说(如 iframe),都存在有一个独立的 window 对象。每个页面容器的 window 对象都有一个独立的VisualViewport
属性。你可以使用Window.visualViewport
获得对应 window 的视觉视口 API。
看起来似乎 mac 的触控板缩放也是一种视觉改变,现在来试试,根据文档,它有两个接口
resize
似乎可以满足我们的需求,编写一点简单的代码,测试一下
1 | <body> |
首先还是使用键盘进行缩放,发现能正常响应,但是 e.target.scale
始终是 1
可以看到 e.target.scale
随着双指的缩放在改变,window.devicePixelRatio
始终是 1, 看起来的效果就像,使用了 css3 的 transform: scale
一样,元素的实际大小没变。
经过测试,可以看出,双指缩放 可以使用 e.target.scale
获取缩放比,键盘缩放,可以使用 window.devicePixelRatio
, 使用 Math.max
取最大字就可以兼容两种情况
1 | window.visualViewport.addEventListener('resize', (e) => { |
兼容性
还是有点恐怖,任重而道远!
🔭 总结
这种冷门的 API (仅对我而言), 看似没啥用,有时却能解决大问题,看来平时还是要多积累知识才行,多看看 web.dev, 涨涨知识!