Адаптируйте CSS Spinner Animation к Fini sh вместо Repeat - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь создать такую ​​же анимацию, как показано ниже:

body {
	text-align: center;
	background: #222;
}

svg {
	position: absolute;
	display: block;
}

.container {
	display: inline-block;
	position: relative;
	width: 50px;
}

.container #Layer_2 {
	width: 60px;
	stroke-dasharray: 121;
	stroke-dashoffset: 121;
	transform: rotate(270deg);
}

.container #Layer_2.on {
	animation: circle 1.4s;
	-webkit-animation-fill-mode: forwards;
	animation-fill-mode: forwards;
}

@keyframes circle {
	0% {
		stroke-dashoffset: 121;
		transform: rotate(90deg);
	}

	100% {
		stroke-dashoffset: 0;
	}
}
<div class="container">

  <svg id="Layer_2" class="on" viewBox="0 0 50 50">
    <defs>
      <style>
        .cls-1 {
          fill: none;
          stroke: #ddd;
          stroke-miterlimit: 10;
          stroke-width: 1px;
        }

      </style>
    </defs>
    <circle class="cls-1" cx="25" cy="25" r="19.27" />
  </svg>

</div>

Однако в идеале я не хочу использовать SVG. У меня уже есть спиннер на моем сайте, который использует похожую анимацию:

* {
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
	box-sizing: border-box;
	font-family: "Avenir Next", sans-serif;
	margin: 0;
	outline: none;
	padding: 0;
}

.spinner-wrapper {
	display: inline-block;
	position: relative;
	width: 64px;
	height: 64px;
	animation: wrapper-rotate 1568ms linear infinite;
	--spinner-border-width: 3px;
	--spinner-color: black;
}

.spinner-wrapper .spinner {
	position: absolute;
	width: 100%;
	height: 100%;
	animation: fill-unfill-rotate 5332ms cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite both;
}

.spinner-wrapper .circle-clipper {
	display: block;
	position: relative;
	width: 50%;
	height: 100%;
	float: left;
	overflow: hidden;
}

.spinner-wrapper .circle-clipper.circle-clipper-left .circle {
	left: 0;
	border-right-color: transparent !important;
	transform: rotate(129deg);
	animation: left-spin 1333ms cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite both;
}

.spinner-wrapper .circle-clipper.circle-clipper-right .circle {
	right: 0;
	border-left-color: transparent !important;
	transform: rotate(-129deg);
	animation: right-spin 1333ms cubic-bezier(0.785, 0.135, 0.15, 0.86) infinite both;
}

.spinner-wrapper .circle-clipper .circle {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	width: 200%;
	height: 100%;
	border: var(--spinner-border-width) solid var(--spinner-color);
	border-bottom-color: transparent !important;
	border-radius: 50%;
}

.spinner-wrapper .gap-patch {
	position: absolute;
	top: 0;
	left: 45%;
	width: 10%;
	height: 100%;
	overflow: hidden;
}

.spinner-wrapper .gap-patch .circle {
	width: 1000%;
	left: -450%;
}

@keyframes wrapper-rotate {
	to {
		transform: rotate(360deg);
	}
}

@keyframes fill-unfill-rotate {
	12.5% {
		transform: rotate(135deg);
	}

	25% {
		transform: rotate(270deg);
	}

	37.5% {
		transform: rotate(405deg);
	}

	50% {
		transform: rotate(540deg);
	}

	62.5% {
		transform: rotate(675deg);
	}

	75% {
		transform: rotate(810deg);
	}

	87.5% {
		transform: rotate(945deg);
	}

	to {
		transform: rotate(1080deg);
	}
}

@keyframes left-spin {
	from {
		transform: rotate(130deg);
	}

	50% {
		transform: rotate(-5deg);
	}

	to {
		transform: rotate(130deg);
	}
}

@keyframes right-spin {
	from {
		transform: rotate(-130deg);
	}

	50% {
		transform: rotate(5deg);
	}

	to {
		transform: rotate(-130deg);
	}
}
<div class="spinner-wrapper">
    <div class="spinner">
      <div class="circle-clipper circle-clipper-left">
        <div class="circle"></div>
      </div>
      <div class="gap-patch circle-clipper">
        <div class="circle"></div>
      </div>
      <div class="circle-clipper circle-clipper-right">
        <div class="circle"></div>
      </div>
    </div>
  </div>

Анимация, показанная выше, похожа на то, чего я хочу достичь, но, очевидно, она бесконечна и не совсем завершает полный круг.

Кто-нибудь может подсказать, что я могу сделать с моим существующим решением, чтобы адаптировать его для имитации первой анимации?

Я пробовал разные вещи, но не смог добиться реального прогресса.

1 Ответ

1 голос
/ 26 апреля 2020

Я рассмотрю идею, используя clip-path, как я делал в этот предыдущий ответ :

.loader {
  width:150px;
  height:150px;
  display:inline-block;
  margin:20px;
  border:2px solid #fff;
  border-radius:50%;
  transform:scaleX(var(--s,1)) rotate(225deg);
  clip-path:polygon(50% 50%,0 0,0 0,0 0, 0 0,0 0);
  animation:change 1.4s linear forwards;
}
.opp {
  --s:-1;
}

@keyframes change {
  25% {
    clip-path:polygon(50% 50%,0 0,   0 100%,0 100%,0 100%,0 100%);
  }
  50% {
    clip-path:polygon(50% 50%,0 0,0 100%,   100% 100%, 100% 100%,100% 100%);
  }
  75% {
    clip-path:polygon(50% 50%,0 0,0 100%,100% 100%,    100% 0,100% 0);
  }
  100% {
    clip-path:polygon(50% 50%,0 0,0 100%,100% 100%, 100% 0,     0% 0%);
    transform:scaleX(var(--s,1)) rotate(45deg);
  }
}

body {
 background:black;
}
<div class="loader"></div>

<div class="loader opp"></div>
...