html - 带有重复背景的 Chrome 中的 SVG 背景图像模糊
问题描述
SVG 背景在 Chrome 和其他基于 Blink/webkit 的浏览器中出现模糊:
Chrome 中部分 SVG 的屏幕截图:
Firefox 中部分 SVG 的屏幕截图:
这仅在使用“background-repeat: true”和“background-size: contains” CSS 值显示 SVG 时发生。我们希望尽可能多地重复 SVG 背景高度,因为页面高度是动态的,并且拉伸矢量图像看起来很差。
SVG 在下面示例页面的 CSS 中内联显示,但是当我链接到外部 SVG 图像时,问题以同样的方式发生。
这是一个显示此行为的测试页面: https ://august-13-2020-test-canvas.bubbleapps.io/version-test/pagemaker-test-original-2 (使用“用户名”和“密码”登录,我们需要将此身份验证放在这里)。
带有正确显示(清晰/平滑边缘)SVG 的测试页面在这里:https ://august-13-2020-test-canvas.bubbleapps.io/version-test/pagemaker-test-online-1
具有清晰/平滑边缘的版本以完全相同的方式显示 - 唯一的区别是 SVG 的内容。
这是模糊页面的背景 SVG 链接:https ://dd7tel2830j4w.cloudfront.net/d44/f1588704991659x396570736162959360/background.svg
我从这个页面测试的所有 SVG 都有清晰的边缘:https ://www.svgbackgrounds.com/#flat-mountains (右下角是上面链接中使用的那个)
在尝试解决此问题或在 SVG 代码中确定其原因的过程中,我对 SVG 进行了相当多的编辑,并尝试了以下操作:
- 将所有 SVG 点值(路径的 d 属性)转换为整数
- 将“PreserveAspectRatio”添加到 SVG 的开始标签
- 从 SVG 的开头声明中删除高度和宽度
- 从 SVG 中删除“线性渐变”并用静态颜色替换它们
- 将 SVG 形状的大小加倍以查看模糊度是否随着初始宽度和高度的增大而降低
- 将“crispEdges”属性添加到 SVG 路径
- 优化 SVG(使用 SVGomg)
此外,我尝试稍微更改 CSS,但无法使其正常工作。
我对解决方法的一些想法如下:
- 使用多个背景图像重复显示 SVG(在背景中显示 5-10 次,模仿 background-repeat:repeat-y 效果,但包含多个背景图像)
- 使用 JS 在页面上绘制内联 SVG(不会发生此错误),创建一个与我们组的动态高度完全相同的 HTML(可以随时更改而不会触发 JS 事件)并重复SVG 以某种方式在该组中。
- 向设计师询问不同的 SVG 背景,并希望不再出现模糊问题。
在这里的任何帮助将不胜感激,我正在为此烦恼,并且在咨询了 CodeMentor.io 上的几位开发人员后无法解决该问题。
解决方案
Blink 似乎应用了错误的算法,首先以错误的大小渲染 SVG,然后缩放生成的光栅图像。这很难解决,因为涉及到两种缩放机制,SVGviewBox
和 CSS background-size
。
我只能提供部分解决方案,在 Chrome 和 Edge(两个引擎)中工作,但在 Firefox 中失败。
它将缩放和重复的责任从 CSSbackground
属性转移到带有<pattern>
元素的 SVG 本身。SVG 图像的完整内容在此元素内移动,包括将viewBox
属性设置为相同的值。
然后,模式重复的宽度和高度值设置为width="100vw" height="504vw"
。这会填充视口宽度并保持高度的纵横比。(Firefox 似乎无法vw
在这种情况下解释单位)。
最后,<rect>
定义了 width = height = 100% 的 a 并用模式填充,没有属性的根<svg>
元素viewBox
同样设置为 width = height = 100%。
<svg width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg">
<pattern id="pt" width="100vw" height="504vw" x="0" y="0" viewBox="0 0 1440 7258" patternUnits="userSpaceOnUse" preserveAspectRatio="xMinYMin meet">
<rect width="1440" height="7258" fill="white"/>
<path d="M-137 1749L1546 1994.95V2870L-137 2624.64V1749Z" fill="#F7F8FF"/>
<path d="M-137 3776L1546 4021.95V4897L-137 4651.64V3776Z" fill="url(#paint0_linear)"/>
<path d="M-137 3969L1546 4214.95V4900L-137 4654.64V3969Z" fill="url(#paint1_linear)"/>
<path d="M1319 2764L1545 2796.96V2870L1319 2837.12V2764Z" fill="#264CE9"/>
<path d="M-53 2645L96 2666.68V2744L-53 2722.37V2645Z" fill="#FBE89F"/>
<path d="M-29 2571L307 2620.13V2699L-29 2649.99V2571Z" fill="#54A5F2"/>
<path d="M1209 2820L1545 2869.13V2948L1209 2898.99V2820Z" fill="#6AD2F6"/>
<path d="M-147 4649L307 4715.42V4891L-147 4824.74V4649Z" fill="#6AD2F6"/>
<path d="M-137 -233L1546 12.9461V688L-137 442.638V-233Z" fill="url(#paint2_linear)"/>
<g style="mix-blend-mode:multiply">
<path d="M987 -144L2119 21.4151V388L987 222.978V-144Z" fill="#6AD2F6"/>
</g>
<path d="M-137 27L1546 272.946V948L-137 702.638V27Z" fill="url(#paint3_linear)"/>
<path d="M-258 455L490 564.509V794L-258 684.751V455Z" fill="url(#paint4_linear)"/>
</pattern>
<linearGradient id="paint0_linear" x1="43.9999" y1="3807" x2="458.5" y2="4665" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.06"/>
<stop offset="1" stop-color="#F7F8FF" stop-opacity="0.26"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="43.9999" y1="4000" x2="1229" y2="5099" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.06"/>
<stop offset="1" stop-color="#F7F8FF" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="194" y1="87.4999" x2="1671" y2="300" gradientUnits="userSpaceOnUse">
<stop offset="0.270833" stop-color="#264CE9"/>
<stop offset="1" stop-color="#6AD2F6"/>
</linearGradient>
<linearGradient id="paint3_linear" x1="194" y1="347.5" x2="1671" y2="560" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9"/>
<stop offset="1" stop-color="#6AD2F6"/>
</linearGradient>
<linearGradient id="paint4_linear" x1="-108" y1="550.5" x2="490" y2="638" gradientUnits="userSpaceOnUse">
<stop stop-color="#264CE9" stop-opacity="0.43"/>
<stop offset="1" stop-color="#264CE9"/>
</linearGradient>
<rect width="100%" height="100%" fill="url(#pt)" />
</svg>
我已经稍微简化了标记,但这些更改都是装饰性的,包括删除clipPath
- 它适用于模式元素,无论如何。
推荐阅读
- python - 从训练数据集 PyTorch 读取数据时出现运行时错误
- security - 安全网站是否可能仅在一台特定机器上显示为不安全?
- c# - 发件人对象 - с#
- docker - Kubeflow 是否可以将本地文件夹挂载到多个容器操作?
- ios - 在 ios 中为特定条件隐藏故事板中设置的图像
- javascript - 使用 JS /g 函数替换字符显示未定义
- java - 什么是查找仅包含数字的计数的方法
- php - Opencart v1.5.6.4 - PHP 致命错误:'函数名必须是字符串'
- ios - Swift 布尔值不起作用:无法将“Bool”类型的值分配给“BOOL”类型(又名“Int32”)
- c# - 通过 c# 中的 api 从共享点获取文件/文件夹