在img标签中使用的SVG大小不一致,移动起来像跳舞一样。

6

背景

我正在开发一个PhoneGap/Cordova应用程序,它应该在iOS和Android设备上运行,并使用嵌入为<img/>标记的SVG图像,使用HTML属性width=""height=""来设置它们的尺寸,以及style="left: ...px; top: ...px; zoom: ...;"来设置它们的相对位置,其中缩放系数在多个图像对象之间是统一的。

我的问题是,在缩放时,图像在Safari和Chrome中呈现出不同的大小。这也可以在这些浏览器的桌面版本中看到,我认为我可以将其归结为与lefttopCSS属性相关的四舍五入问题。当使用zoomCSS属性和widthheight HTML属性的分数值时,问题会加剧。

我在这里创建了一个演示可下载版本。在此演示中,我使用了两个SVG图像,除了填充颜色不同外,其余完全相同,我用它来进行颜色对比。演示中有三对:最上面的使用分数值zoom,中间使用分数值widthheight,最后使用widthheight值的圆整倍数。有一个按钮,可以启动一个简单的动画,将所有图像向右移动一个像素。在Chrome中很容易注意到中间的图像会抖动,而其他两个则稍微难以注意到变化 - 但它们也存在。我正在使用Windows 10和Chrome 65.0 - 虽然我也可以在Firefox和Edge中看到问题的变化(尽管 - 它们呈现方式不同)。

这是演示的动画。请注意,我在帧之间更改的全部是所有图像的left位置 - 并以统一的方式进行。

dancing SVGs demo

实际问题

对于我的应用程序来说,图像在页面不同位置和各个缩放级别下必须具有一致的渲染。当平稳地改变缩放lefttop属性时,图���应该相应地平稳地改变尺寸和位置,但不应该在改变lefttop属性时改变尺寸。是否有一种方法可以确保当多个图像使用相同(可能是小数)的宽度高度值,但不同的lefttop位置时,它们将被呈现为相同的图像?是否有一种方法可以确保在所有图像使用相同尺寸时,缩放属性的平滑过渡会产生平滑的呈现效果?

答案指南

一个合适的答案要么解释为什么当前浏览器无法做到这一点,并指向确认的错误报告,描述此问题并显示它影响任何平台的流行设备; 或者提供一种替代方式来调整图像的大小和位置,同时保留使用小数值的可能性,并在所有图像使用相同尺寸时获得统一性和平滑的缩放转换。

非常感谢您提供的任何帮助!

1个回答

1
我认为这是因为不同浏览器之间对于zoom属性的支持并不一致(你可以在这里https://caniuse.com/#feat=css-zoom看到)。建议使用transform: scale()属性代替。

function budgeRight() {
   var imgs = document.querySelectorAll('img');
   imgs = Array.prototype.slice.apply(imgs);
   imgs.forEach(function(img) { 
      var left = parseInt(img.style.left);
      
      img.style.left = (left + 1).toString() + "px"; 
    });
}

var interval = null;
var button = document.getElementById('button-click-me');

button.addEventListener('click', function() {
  if (interval) {
    clearInterval(interval);
    interval = null;
  }
  else {
    interval = setInterval(budgeRight, 500);
  }
});
img { position: absolute; }
body { background-color: #000; }
<img style="-webkit-transform: scale(2.3); -moz-transform: scale(2.3); -ms-transform: scale(2.3); -o-transform: scale(2.3); transform: scale(2.3); -webkit-transform-origin: top left; -moz-transform-origin: top left; -ms-transform-origin: top left; -o-transform-origin: top left; transform-origin: top left; left: 41px; top: 25px;" src="https://gist.githubusercontent.com/kwikwag/74b991206c5fd197c70a6ec2c02fd238/raw/3f4070dbb97c69f716ad6b32ca5f6abd1f4fd702/rect_white.svg?sanitize=true">
<img style="-webkit-transform: scale(2.3); -moz-transform: scale(2.3); -ms-transform: scale(2.3); -o-transform: scale(2.3); transform: scale(2.3); -webkit-transform-origin: top left; -moz-transform-origin: top left; -ms-transform-origin: top left; -o-transform-origin: top left; transform-origin: top left; left: 40px; top: 25px;" src="https://gist.githubusercontent.com/kwikwag/74b991206c5fd197c70a6ec2c02fd238/raw/3f4070dbb97c69f716ad6b32ca5f6abd1f4fd702/rect_red.svg?sanitize=true">
<img style="-webkit-transform: scale(2.3); -moz-transform: scale(2.3); -ms-transform: scale(2.3); -o-transform: scale(2.3); transform: scale(2.3); -webkit-transform-origin: top left; -moz-transform-origin: top left; -ms-transform-origin: top left; -o-transform-origin: top left; transform-origin: top left; left: 31px; top: 35px;" width="9.35" height="23.35" src="https://gist.githubusercontent.com/kwikwag/74b991206c5fd197c70a6ec2c02fd238/raw/3f4070dbb97c69f716ad6b32ca5f6abd1f4fd702/rect_red.svg?sanitize=true">
<img style="-webkit-transform: scale(2.3); -moz-transform: scale(2.3); -ms-transform: scale(2.3); -o-transform: scale(2.3); transform: scale(2.3); -webkit-transform-origin: top left; -moz-transform-origin: top left; -ms-transform-origin: top left; -o-transform-origin: top left; transform-origin: top left; left: 32px; top: 35px;" width="9.35" height="23.35" src="https://gist.githubusercontent.com/kwikwag/74b991206c5fd197c70a6ec2c02fd238/raw/3f4070dbb97c69f716ad6b32ca5f6abd1f4fd702/rect_white.svg?sanitize=true">
<img style="left: 91px; top: 130px;" width="18" height="42" src="https://gist.githubusercontent.com/kwikwag/74b991206c5fd197c70a6ec2c02fd238/raw/3f4070dbb97c69f716ad6b32ca5f6abd1f4fd702/rect_red.svg?sanitize=true">
<img style="left: 94px; top: 130px;" width="18" height="42" src="https://gist.githubusercontent.com/kwikwag/74b991206c5fd197c70a6ec2c02fd238/raw/3f4070dbb97c69f716ad6b32ca5f6abd1f4fd702/rect_white.svg?sanitize=true">
<button id="button-click-me">Click me</button>

注意我添加了transform-origin: top left,以便从每个图像的左上角进行缩放。 并且我使用了所有供应商前缀-webkit--moz-等,以在这两个属性上具有最大的兼容性...


Valentin,感谢您的回复。虽然zoom属性在不同浏览器之间确实存在不一致性,但我的问题是关于它在某种类型的浏览器内部行为的一致性。您提供的解决方案是使用scale属性,但在我的浏览器(Windows Chrome)中仍然存在大小不一致的问题,尽管这些问题较小。因此,我不得不拒绝接受这个答案。如果您能证明这是浏览器中已确认的错误,我会接受它。 - Yuval

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接