如何按顺序对同一轨道路径上的多个元素进行动画处理?



我想创建一个动画,显示几个圆圈在轨道上一个接一个地移动。目前,我创建了三个圆圈,但它们出现在不同的线上,因此以圆周运动移动,但作为一条线。如何更改代码以实现我想要的运动?下面是具有当前状态的代码笔。

这是我使用的代码:

* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Lato', sans-serif;
font-size: 18px;
line-height: 1.6;
background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 100vh;
}
.loader {
height: 50px;
animation: rotate 6s linear infinite;
}
.circle {
display: inline-block;
background-color: purple;
height: 40px;
width: 40px;
border-radius: 50%;
transform: scale(0);
animation: grow 1.5s linear infinite;
margin: -20p;
}
.circle:nth-child(2) {
background-color: palevioletred;
transform: scale(0);
animation-delay: 0.20s;
}
@keyframes rotate {
to {
transform: rotate(360deg)
}
}
@keyframes grow {
50% {
transform: scale(1);
}
}
<div class="loader">
<div class="circle"></div>
<div class="circle"></div>
<div class="circle"></div>
</div>

我正在创建全尺寸的"板",我可以将其设置为初始旋转点。圆圈最终成为板上的伪元素(以避免额外的标记)。修改初始旋转值以使圆圈更紧密地靠拢。

.loader {
width: 100px;
height: 100px;
animation: rotate 6s linear infinite;
position: relative;
}
.plate {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.plate:nth-child(2) {
transform: rotate(120deg);
}
.plate:nth-child(3) {
transform: rotate(240deg);
}
.plate:before {
content: '';
position: absolute;
background-color: red;
height: 40px;
width: 40px;
border-radius: 50%;
transform: scale(0);
animation: grow 1.5s linear infinite;
}
.plate:nth-child(2):before {
background: green;
}
.plate:nth-child(3):before {
background: blue;
}
@keyframes rotate {
to {
transform: rotate(360deg);
}
}
@keyframes grow {
50% {
transform: scale(1);
}
}
* {
box-sizing: bordr-box;
margin: 0;
padding: 0;
}
body {
font-family: "Lato", sans-serif;
font-size: 18px;
line-height: 1.6;
background-image: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
min-height: 100vh;
}
<body>
<div class="loader">
<div class="plate"></div>
<div class="plate"></div>
<div class="plate"></div>
</div>
</body>

@isherwood提供了一个很好的解决方案,在大多数现代浏览器中都可以轻松使用。但是,假设您想要更复杂的运动,例如椭圆轨道。


SVG 动画

您可以将整个事情构建到一个SVG中,因为它支持许多很酷的动画,同时性能很高。但是构建 SVG 并从头开始制作动画有点复杂。幸运的是,有一些工具可以提供帮助。下面是一些示例:Snapsvg(代码库),SVGGator(基于Web的动画工具)或Bodymovin(After Effects工作流程)。


但是,假设您想坚持在HTML/CSS中可以完成的操作。

CSS 运动路径

可悲的是,截至2019年夏季,支持并不大,但可能会有所改善。如果您的受众使用的是正确的浏览器(Chrome、Opera、Edge 或基于 Chromium 的移动浏览器)。它实际上很容易使用,但也有一些陷阱。例如,现在似乎只有path()属性有效。因此,您不能使用形状关键字,例如circle()ellipse(),尽管它们在规范中。

main {
position: relative;
margin: 20px;
}
main,svg {
	width: 100px;
	height: 100px;
}
path {
stroke-width: 1px;
}
svg {
position:absolute;
opacity: 0.5;
}
#c1 {
stroke: red;
}
#c2 {
stroke: blue;
}
#c3 {
stroke: green;
}
div[class*="c"] {
	width: 15px;
	height: 15px;
	border-radius: 50%;
	position: absolute;
	box-shadow: 5px 5px 10px 0 rgba(0,0,0,0.3);
}
.c1 {
	background-color: red;
	offset-path: path('M50,2 C78.2166667,2 98,22.2364005 98,50.5 C98,78.7635995 75.5694444,99 50,99 C24.4305556,99 2,76.5476997 2,50.5 C2,24.4523003 21.7833333,2 50,2 Z');
	animation: moveme 5s ease-in-out infinite;
}
.c2 {
	background-color: blue;
	offset-path: path('M55,13 C80.2774306,13 98,30.9415509 98,56 C98,81.0584491 77.9059606,99 55,99 C32.0940394,99 12,79.0938368 12,56 C12,32.9061632 29.7225694,13 55,13 Z');
	animation: moveme 5.25s linear infinite;
}
.c3{
	background-color: green;
	offset-path: path('M36.0041619,30.5873511 C61.3414991,12.7718541 90.4202796,4.99194919 98.2799065,16.2635432 C106.139533,27.5351371 85.805943,52.9370587 62.845696,69.0811471 C39.885449,85.2252355 7.31148243,93.0730731 1.30061213,84.4528052 C-4.71025818,75.8325372 10.6668246,48.4028481 36.0041619,30.5873511 Z');
	animation: moveme 5.5s linear infinite;
}
@keyframes moveme {
100% { 
motion-offset: 100%;
offset-distance: 100%;
}
}
<main>
<!-- paths for example -->
<svg viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="orbit" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<path d="M50,2 C78.2166667,2 98,22.2364005 98,50.5 C98,78.7635995 75.5694444,99 50,99 C24.4305556,99 2,76.5476997 2,50.5 C2,24.4523003 21.7833333,2 50,2 Z" id="c1"></path>
<path d="M55,13 C80.2774306,13 98,30.9415509 98,56 C98,81.0584491 77.9059606,99 55,99 C32.0940394,99 12,79.0938368 12,56 C12,32.9061632 29.7225694,13 55,13 Z" id="c2"></path>
<path d="M36.0041619,30.5873511 C61.3414991,12.7718541 90.4202796,4.99194919 98.2799065,16.2635432 C106.139533,27.5351371 85.805943,52.9370587 62.845696,69.0811471 C39.885449,85.2252355 7.31148243,93.0730731 1.30061213,84.4528052 C-4.71025818,75.8325372 10.6668246,48.4028481 36.0041619,30.5873511 Z" id="c3"></path>
</g>
</svg>
	<div class="c1"></div>
	<div class="c2"></div>
	<div class="c3"></div>
</main>

最新更新