【发布时间】:2021-11-05 13:58:00
【问题描述】:
我正在查看 CSS 中的 offset-path,您实际上是这样做的:
* {
box-sizing: border-box;
}
:root {
--delay: 0ms;
--path: path("M.4 76.8C102-24.9 266.9-24.9 368.5 76.8c81.3 81.3 81.3 213.2 0 294.5-65.1 65.1-170.6 65.1-235.6 0-52.1-52.1-52.1-136.5 0-188.5 41.6-41.6 109.2-41.6 150.8 0 33.3 33.3 33.3 87.3 0 120.6-26.7 26.7-69.9 26.7-96.5 0-21.3-21.3-21.3-55.9 0-77.2 17.1-17.1 44.7-17.1 61.8 0 13.6 13.6 13.6 35.8 0 49.4-10.9 10.9-28.6 10.9-39.5 0-8.7-8.7-8.7-22.9 0-31.6 7-7 18.3-7 25.3 0");
}
body {
margin: 0;
padding: 2rem;
min-height: 100vh;
background-color: #1b1b24;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper {
position: relative;
}
.obj {
--color: salmon;
position: absolute;
top: 0;
left: 0;
offset-path: var(--path);
animation: move 4500ms infinite ease-in-out var(--delay);
width: 2.5rem;
height: 2.5rem;
border-radius: 50%;
background-color: var(--color);
opacity: 0;
transform: scale(0);
}
.obj--2 {
--delay: 1500ms;
--color: hotpink;
}
.obj--3 {
--delay: 3000ms;
--color: turquoise;
}
svg {
width: 429px;
}
@keyframes appear {
100% {
opacity: 1;
}
}
@keyframes move {
10% {
opacity: 1;
offset-distance: 0%;
transform: scale(1);
}
30% {
box-shadow: -0.5rem 0 0.3rem var(--color, white);
}
70% {
box-shadow: -0.5rem 0 0.3rem var(--color, white);
}
90% {
opacity: 1;
offset-distance: 100%;
transform: scale(0.2);
box-shadow: none;
}
100% {
opacity: 0;
offset-distance: 100%;
transform: scale(0.2);
}
}
<div class="wrapper">
<div class="obj"></div>
<div class="obj obj--2"></div>
<div class="obj obj--3"></div>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 431.7 422.6"><path d="M1.1 77.8c101.7-101.7 266.5-101.7 368.2 0 81.3 81.3 81.3 213.2 0 294.5-65.1 65.1-170.6 65.1-235.6 0-52.1-52.1-52.1-136.5 0-188.5 41.6-41.6 109.2-41.6 150.8 0 33.3 33.3 33.3 87.3 0 120.6-26.7 26.7-69.9 26.7-96.5 0-21.3-21.3-21.3-55.9 0-77.2 17.1-17.1 44.7-17.1 61.8 0 13.6 13.6 13.6 35.8 0 49.4-10.9 10.9-28.6 10.9-39.5 0-8.7-8.7-8.7-22.9 0-31.6 7-7 18.3-7 25.3 0" fill="none" stroke="#5e5e7d" stroke-width="3" stroke-miterlimit="10"/></svg>
</div>
他们有这个变量:
--path: path("M.4 76.8C102-24.9 266.9-24.9 368.5 76.8c81.3 81.3 81.3 213.2 0 294.5-65.1 65.1-170.6 65.1-235.6 0-52.1-52.1-52.1-136.5 0-188.5 41.6-41.6 109.2-41.6 150.8 0 33.3 33.3 33.3 87.3 0 120.6-26.7 26.7-69.9 26.7-96.5 0-21.3-21.3-21.3-55.9 0-77.2 17.1-17.1 44.7-17.1 61.8 0 13.6 13.6 13.6 35.8 0 49.4-10.9 10.9-28.6 10.9-39.5 0-8.7-8.7-8.7-22.9 0-31.6 7-7 18.3-7 25.3 0");
不知何故,它被转换成一些底层数据结构,然后每一帧,你都会沿着那个“路径”移动。它是如何工作的,你如何在高层次上实现它?
基本上,我想您已经以某种方式将 SVG d 路径转换为向量(点数组?),但这似乎不对,因为有些点不在曲线上(控制点)。然后不知何故,时钟的每一次滴答/更新,它都会移动对象的 x 和 y 位置,使其沿着路径更远。不过,我并没有进行精神上的飞跃/联系,以了解如何实现这一点。有什么见解吗?
我想部分问题是,path 是如何在后台实现的?以及如何沿着路径/曲线计算时钟的每个刻度的下一个位置? CSS 以某种方式抽象了所有这些,我想知道它的内部工作原理。
【问题讨论】: