有时我会尝试使用<path>
(SVG 的功能强大的绘图语法)绘制一些形状。我对它的所有功能只了解一部分,但我知道的足以造成一些危险。所有直线语法命令(如L
)都非常简单,我发现曲线Q
命令也很直观。将自己限制在一个viewBox="0 0 100 100"
中,绘制简单的图形似乎并不那么糟糕。
这是一个我的经典示例,它使用所有基本命令绘制图形,同时也使用 CSS 对其进行动画处理(仅限 Chromium 浏览器)
奇怪但真实
<svg viewBox="0 0 10 10">
<path d="M2,2 L8,8" />
</svg>
svg:hover path {
transition: 0.2s;
d: path("M8,2 L2,8");
}
前几天我遇到了一种情况,我需要一个 UI 元素,它根据其所处的状态显示不同的图标。它有点像“日志”形状,所以默认状态是直线,有点像汉堡菜单(只有四行,所以更像是文本行),然后是其他各种状态。
- 默认
- 活动
- 成功
- 错误
首先,我编写了世界上最复杂的有限状态机
const indicator = document.querySelector(".element");
let currentState = indicator.dataset.state;
indicator.addEventListener("click", () => {
let nextState = "";
if (currentState == "DEFAULT") {
nextState = "ACTIVE";
} else if (currentState == "ACTIVE") {
nextState = "SUCCESS";
} else if (currentState == "SUCCESS") {
nextState = "ERROR";
} else {
nextState = "DEFAULT";
}
indicator.dataset.state = nextState;
currentState = nextState;
});
这为使用数据属性设置样式状态打开了大门
.element {
&[data-state="DEFAULT"] {
}
&[data-state="ACTIVE"] {
}
&[data-state="SUCCESS"] {
}
&[data-state="ERROR"] {
}
}
因此,如果我的元素以四条线的默认状态开始
<div class="element" data-state="DEFAULT">
<svg viewBox="0 0 100 100" class="icon">
<path d="M0, 20 Q50, 20 100, 20"></path>
<path d="M0, 40 Q50, 40 100, 40"></path>
<path d="M0, 60 Q50, 60 100, 60"></path>
<path d="M0, 80 Q50, 80 100, 80"></path>
</svg>
</div>
……我可以在 CSS 中更改其他状态的路径。例如,我可以获取这四条直线并在 CSS 中更改它们。
请注意,四条“直线”中方便地包含了一个未使用的曲线点。只有在路径中具有相同数量和类型的点的路径才能在 CSS 中进行动画处理。放置曲线点打开了大门。
这四条新路径实际上绘制了一些接近圆形的东西!
.editor-indicator {
&[data-state="ACTIVE"] {
.icon {
:nth-child(1) {
d: path("M50, 0 Q95, 5 100,50");
}
:nth-child(2) {
d: path("M100, 50 Q95, 95 50,100");
}
:nth-child(3) {
d: path("M50,100 Q5, 95 0, 50");
}
:nth-child(4) {
d: path("M0, 50 Q5, 5 50, 0");
}
}
}
}
对于其他状态,我绘制了一个粗略的复选标记(用于成功)和一个粗略的感叹号(用于失败)。
这是一个演示(同样,Chromium),您可以单击它来更改状态
我最终没有使用它,因为 Firefox 和 Safari 都不支持 CSS 中的d: path();
。并不是说它没有对它们进行动画处理,而是根本不起作用,所以对我来说它被淘汰了。我只是在不同的状态下替换了图标。
如果您需要跨浏览器形状变形,我们有一篇关于这方面的完整文章。
我喜欢这个!很棒的演示。可惜它不能跨浏览器工作 :(
我很好奇,您是如何创建这些形状并操作这些点的?您是否首先在矢量程序中绘制它们,或者由于它们是相当简单的形状,所以您是“手动编码” SVG?
d
将成为一个表示属性(如 SVG2 草案规范中链接的这个有趣讨论中所述:https://www.w3.org/2016/04/21-svg-minutes.html),因此预计它很快将在所有浏览器中(以及通过 Web 动画 API 的 JS)中工作。您没有问我,但是(如果它可以提供帮助)我认为您通常可以直接在 CodePen 中编码您的 SVG。学习的东西不多。当您有很多形状时,您可以从 Adobe Illustrator 开始,但它可能会导致无法轻松(在代码中)编辑的 SVG 元素或路径命令。使用路径查找器、扩展外观等可以将简单的椭圆、矩形等转换为具有浮点数的复杂路径。
也许您应该看看 d3 如何通过状态实现其更改,以便您可以实现跨浏览器支持。
在 Firefox Android 夜间版中运行良好…
在我的 Firefox 99.0.1 中可以工作