CSS 动画不适用于 <img> 中的 svg



>我正在尝试在图像/对象标签中对 SVG 进行动画处理,但它不起作用

svg {
width: 100%;
height: 200px;
}
.rotate-45 {
transform-origin: center;
transform: rotate(45deg);
}
.rotate {
transform-origin: center;
animation: rotate 1s ease-in-out infinite;
}
.rotate-back {
transform-origin: center;
animation: rotate 1s ease-in-out infinite;
animation-direction: alternate;
}
.left {
animation: move 1s ease-in-out infinite;
}
.right {
animation: move 1s ease-in-out infinite;
}
@keyframes rotate {
100% {
transform: rotate(calc(90deg + 45deg));
}
}
@keyframes move {
50% {
transform: translate(-30px, -30px);
}
}
<svg width="100%" height="100%" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(500,500)">
<rect class="rotate-45 rotate-back" x="-5" y="-5" width="10" height="10" stroke="#00a99d" stroke-width="20" fill="none" />
<rect class="rotate-45 rotate" x="-50" y="-50" width="100" height="100" stroke="#00a99d" stroke-width="20" stroke-linejoin="bevel" fill="none" />
<g transform="translate(-50,0) rotate(-45)">
<polyline class="left" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke-width="20" fill="none" />
</g>
<g transform="translate(50,0) rotate(135)">
<polyline class="right" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke-width="20" fill="none" />
</g>
<text y="-140" text-anchor="middle" font-weight="bold" font-size="3em" font-family="sans-serif">loading data...</text>
</g>
</svg>

如何与CSS一起对图像标签内的SVG进行动画处理

这是该代码 https://plnkr.co/edit/TdfR7cpVaQArtcUs0Hro?p=preview

您无法从外部对<img>的内部进行动画处理。即使它是 SVG。这有两个原因:

  1. CSS 不跨文档边界应用,并且
  2. 通过<img>引用的图像必须是独立的。

如果将 CSS 放在外部 SVG 中(正常在<style>元素中),则动画应该可以工作。

另请注意,您需要更改执行transform-origin的方式。它在Chrome中的工作方式很方便,但根据当前规范是错误的。 它不适用于其他浏览器,如火狐。

<svg width="100%" height="100%" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink">
<style>
.rotate-45 {
transform-origin: 0px 0px;
transform: rotate(45deg);
}
.rotate {
transform-origin: 0px 0px;
animation: rotate 1s ease-in-out infinite;
}
.rotate-back {
transform-origin: 0px 0px;
animation: rotate 1s ease-in-out infinite;
animation-direction: alternate;
}
.left {
animation: move 1s ease-in-out infinite;
}
.right {
animation: move 1s ease-in-out infinite;
}
@keyframes rotate {
100% {
transform: rotate(135deg);
}
}
@keyframes move {
50% {
transform: translate(-30px, -30px);
}
}
</style>
<g transform="translate(500,500)">
<rect class="rotate-45 rotate-back" x="-5" y="-5" width="10" height="10" stroke="#00a99d" stroke-width="20" fill="none"/>
<rect class="rotate-45 rotate" x="-50" y="-50" width="100" height="100" stroke="#00a99d" stroke-width="20" stroke-linejoin="bevel" fill="none"/>
<g transform="translate(-50,0) rotate(-45)"><polyline class="left" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke-width="20" fill="none"/></g>
<g transform="translate(50,0) rotate(135)"><polyline class="right" points="40,-40 50,-50 -40,-50 -50,-40 -50,50 -40,40" stroke="#00a99d" stroke-width="20" fill="none"/></g>
<text y="-140" text-anchor="middle" font-weight="bold" font-size="3em" font-family="sans-serif">loading data...</text>
</g>
</svg>

如果您不想嵌入<?xml-stylesheet href="style.css" type="text/css"?>即可img标签工作,则可以使用它。上面的代码将在object标签中工作

如果您希望img标签起作用,请按照 Kaiido 的建议进行操作并嵌入它。

如果您使用的是纯JavaScript或其他一些不会自动在HTML输出中包含SVG内联的环境(例如create-react-app),这里有一个解决方案可能会派上用场:

<img id="logo" src="logo.svg" />
<script>
// load logo inline for animation on hover
const loadLogo = async () => {
// get logo, parse source text, and insert text into doc
document.write(await (await fetch("logo.svg")).text());
// remove fallback img logo
document.querySelector("img#logo").remove();
};
loadLogo();
</script>

所有这些操作都是尝试在给定的 url/路径处加载图像,然后将其文本内容直接插入到文档中。然后,您可以从其他样式表中设置样式,使用javascript操作子元素,具有用户交互动画等。如果由于任何原因无法加载,则有一个<img>作为备份。

这也可以写得更通用,但这只是我曾经使用过的快速解决方案。


另一种解决方案是按照此处的说明仅使用<object>嵌入 SVG,尽管这可能会有一些限制,具体取决于您要执行的操作。

最新更新