SVG 掩码翻译在 Chromium 浏览器上滞后
SVG mask translation lags on Chromium browsers
我是动画 SVG 合集的作者 theme-toggles。我注意到任何涉及翻译掩码的内容在 chromium 浏览器上都非常不稳定,但在 Firefox 上却很好。
动画似乎受到限制,可能是因为 Chromium 认为遮罩不在视野范围内。虽然这个问题似乎在大多数时间都存在,但在某些情况下他们确实在 Chromium 上工作,但我无法解释为什么他们有时会工作。
如能帮助解决此问题,我们将不胜感激。我在此处描述的 中发现了类似的问题,但尚未完全找出解决方案的原因。
.theme-toggle {
font-size: 10rem;
}
<link href="https://cdn.jsdelivr.net/npm/theme-toggles@3.5.1/css/classic.min.css" rel="stylesheet"/>
<label class="theme-toggle">
<input type="checkbox" />
<span class="theme-toggle-sr">Toggle theme</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
stroke-linecap="round"
class="theme-toggle__classic"
viewBox="0 0 32 32"
>
<mask id="theme-toggle__classic__cutout" color="#000">
<path fill="#fff" d="M0 0h32v32H0z" />
<circle cx="34" cy="2" r="8" />
</mask>
<circle
cx="16"
cy="16"
r="9.34"
mask="url(#theme-toggle__classic__cutout)"
/>
<g
stroke="currentColor"
class="theme-toggle__classic__sun-rays"
mask="url(#theme-toggle__classic__cutout)"
>
<path d="M16 5.5v-4" />
<path d="M16 30.5v-4" />
<path d="M1.5 16h4" />
<path d="M26.5 16h4" />
<path d="m23.4 8.6 2.8-2.8" />
<path d="m5.7 26.3 2.9-2.9" />
<path d="m5.8 5.8 2.8 2.8" />
<path d="m23.4 23.4 2.9 2.9" />
</g>
</svg>
</label>
这似乎至少可以提高 Chromium 的性能。我做了三处改动:
- 将面具换成clip-path
- 仅将 clip-path 应用于包含圆和射线的父组一次
- 这一个有所不同:不转换
transform
,而是直接转换 d
路径数据。对于 Chrome (99) 和 Firefox (98),您现在可以编写 CSS 语法 d: path('...')
并为路径数据设置动画。它不适用于 Safari。
.theme-toggle.theme-toggle--reversed .theme-toggle__classic {
transform: scale(-1,1)
}
.theme-toggle {
--theme-toggle__classic--duration: 750ms
}
.theme-toggle__classic * {
transition-property: opacity,transform,d;
transition-timing-function: cubic-bezier(0,0,0.15,1.25);
transform-origin: center;
transition-duration: var(--theme-toggle__classic--duration);
transition-delay: calc(var(--theme-toggle__classic--duration) / 5);
}
.theme-toggle__classic #theme-toggle__classic__cutout path {
transition-delay: 0s;
d: path('M0-10h34v4a8 8 0 108 8h1v32h-43z');
}
.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic .theme-toggle__classic__sun-rays *,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic .theme-toggle__classic__sun-rays * {
transform: scale(.5) rotate(45deg);
opacity: 0;
transition-delay: 0s
}
.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic #theme-toggle__classic__cutout path,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic #theme-toggle__classic__cutout path {
d: path('M-11 0h34v4a8 8 0 108 8h1v32h-43z');
transition-delay: calc(var(--theme-toggle__classic--duration) / 5)
}
button.theme-toggle,label.theme-toggle {
border: none;
background: 0 0;
cursor: pointer
}
button.theme-toggle input[type=checkbox],label.theme-toggle input[type=checkbox] {
display: none
}
button.theme-toggle .theme-toggle-sr,label.theme-toggle .theme-toggle-sr {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border-width: 0
}
.theme-toggle {
font-size: 10rem;
}
<label class="theme-toggle">
<input type="checkbox" />
<span class="theme-toggle-sr">Toggle theme</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
stroke-linecap="round"
class="theme-toggle__classic"
viewBox="0 0 32 32"
>
<clipPath id="theme-toggle__classic__cutout">
<path />
</clipPath>
<g clip-path="url(#theme-toggle__classic__cutout)">
<circle cx="16" cy="16" r="9.34" />
<g
stroke="currentColor"
class="theme-toggle__classic__sun-rays"
>
<path d="M16 5.5v-4" />
<path d="M16 30.5v-4" />
<path d="M1.5 16h4" />
<path d="M26.5 16h4" />
<path d="m23.4 8.6 2.8-2.8" />
<path d="m5.7 26.3 2.9-2.9" />
<path d="m5.8 5.8 2.8 2.8" />
<path d="m23.4 23.4 2.9 2.9" />
</g>
</g>
</svg>
</label>
我是动画 SVG 合集的作者 theme-toggles。我注意到任何涉及翻译掩码的内容在 chromium 浏览器上都非常不稳定,但在 Firefox 上却很好。
动画似乎受到限制,可能是因为 Chromium 认为遮罩不在视野范围内。虽然这个问题似乎在大多数时间都存在,但在某些情况下他们确实在 Chromium 上工作,但我无法解释为什么他们有时会工作。
如能帮助解决此问题,我们将不胜感激。我在此处描述的
.theme-toggle {
font-size: 10rem;
}
<link href="https://cdn.jsdelivr.net/npm/theme-toggles@3.5.1/css/classic.min.css" rel="stylesheet"/>
<label class="theme-toggle">
<input type="checkbox" />
<span class="theme-toggle-sr">Toggle theme</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
stroke-linecap="round"
class="theme-toggle__classic"
viewBox="0 0 32 32"
>
<mask id="theme-toggle__classic__cutout" color="#000">
<path fill="#fff" d="M0 0h32v32H0z" />
<circle cx="34" cy="2" r="8" />
</mask>
<circle
cx="16"
cy="16"
r="9.34"
mask="url(#theme-toggle__classic__cutout)"
/>
<g
stroke="currentColor"
class="theme-toggle__classic__sun-rays"
mask="url(#theme-toggle__classic__cutout)"
>
<path d="M16 5.5v-4" />
<path d="M16 30.5v-4" />
<path d="M1.5 16h4" />
<path d="M26.5 16h4" />
<path d="m23.4 8.6 2.8-2.8" />
<path d="m5.7 26.3 2.9-2.9" />
<path d="m5.8 5.8 2.8 2.8" />
<path d="m23.4 23.4 2.9 2.9" />
</g>
</svg>
</label>
这似乎至少可以提高 Chromium 的性能。我做了三处改动:
- 将面具换成clip-path
- 仅将 clip-path 应用于包含圆和射线的父组一次
- 这一个有所不同:不转换
transform
,而是直接转换d
路径数据。对于 Chrome (99) 和 Firefox (98),您现在可以编写 CSS 语法d: path('...')
并为路径数据设置动画。它不适用于 Safari。
.theme-toggle.theme-toggle--reversed .theme-toggle__classic {
transform: scale(-1,1)
}
.theme-toggle {
--theme-toggle__classic--duration: 750ms
}
.theme-toggle__classic * {
transition-property: opacity,transform,d;
transition-timing-function: cubic-bezier(0,0,0.15,1.25);
transform-origin: center;
transition-duration: var(--theme-toggle__classic--duration);
transition-delay: calc(var(--theme-toggle__classic--duration) / 5);
}
.theme-toggle__classic #theme-toggle__classic__cutout path {
transition-delay: 0s;
d: path('M0-10h34v4a8 8 0 108 8h1v32h-43z');
}
.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic .theme-toggle__classic__sun-rays *,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic .theme-toggle__classic__sun-rays * {
transform: scale(.5) rotate(45deg);
opacity: 0;
transition-delay: 0s
}
.theme-toggle input[type=checkbox]:checked~.theme-toggle__classic #theme-toggle__classic__cutout path,
.theme-toggle--toggled:not(label).theme-toggle .theme-toggle__classic #theme-toggle__classic__cutout path {
d: path('M-11 0h34v4a8 8 0 108 8h1v32h-43z');
transition-delay: calc(var(--theme-toggle__classic--duration) / 5)
}
button.theme-toggle,label.theme-toggle {
border: none;
background: 0 0;
cursor: pointer
}
button.theme-toggle input[type=checkbox],label.theme-toggle input[type=checkbox] {
display: none
}
button.theme-toggle .theme-toggle-sr,label.theme-toggle .theme-toggle-sr {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border-width: 0
}
.theme-toggle {
font-size: 10rem;
}
<label class="theme-toggle">
<input type="checkbox" />
<span class="theme-toggle-sr">Toggle theme</span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="1em"
height="1em"
fill="currentColor"
stroke-linecap="round"
class="theme-toggle__classic"
viewBox="0 0 32 32"
>
<clipPath id="theme-toggle__classic__cutout">
<path />
</clipPath>
<g clip-path="url(#theme-toggle__classic__cutout)">
<circle cx="16" cy="16" r="9.34" />
<g
stroke="currentColor"
class="theme-toggle__classic__sun-rays"
>
<path d="M16 5.5v-4" />
<path d="M16 30.5v-4" />
<path d="M1.5 16h4" />
<path d="M26.5 16h4" />
<path d="m23.4 8.6 2.8-2.8" />
<path d="m5.7 26.3 2.9-2.9" />
<path d="m5.8 5.8 2.8 2.8" />
<path d="m23.4 23.4 2.9 2.9" />
</g>
</g>
</svg>
</label>