如何在同一轨道路径上依次设置多个元素的动画?

时间:2019-05-31 16:04:23

标签: css css-animations

我想创建一个动画,显示几个圆圈在轨道上一个接一个地移动。目前,我创建了三个圆,但它们分别出现在单独的直线上,因此以圆周运动的形式移动,但以直线形式移动。如何更改代码以实现所需的运动?这是一个codepen,显示当前状态。

这是我使用的代码:

* {
  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>

2 个答案:

答案 0 :(得分:1)

我正在创建全尺寸的“印版”,可以将其设置为初始旋转点。圆最终以伪元素的形式出现在板上(以避免额外的标记)。修改初始旋转值以使圆更靠近。

.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>

答案 1 :(得分:0)

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


SVG动画

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


但是,假设您要坚持使用HTML / CSS可以完成的工作。

CSS运动路径

自2019年夏季以来,not great的支持非常糟糕,但它可能会有所改善。如果您的受众使用的是正确的浏览器(基于Chrome,Opera,Edge或Chromium的移动浏览器)。它实际上很容易使用,但是有些陷阱。例如,似乎现在只有path()属性起作用。因此,尽管circle()ellipse()这样的形状关键字位于the spec中,但是您不能使用它们。

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>