是否可以关键帧-css 在 pi 上逆时针设置 div 动画?

Is it possible to keyframe-css animate a div counter-clockwise over pi?

问题:

是否可以仅在 css 个关键帧中为内圆 .watch-face 从 12 点开始逆时针旋转完整旋转或 2πr 设置动画?


完成后的动画效果如下:

完成动画:

查看实时代码起点:Code sample

HTML:

<div class="watch-container">
  <div class="watch-face"></div>
</div>

SCSS

$watch-face-size: 165;
$watch-border-size: 185;

.watch-face {
  height: $watch-face-size + px;
  width: $watch-face-size + px;
  background: green;
  box-sizing: border-box;
  border-radius: $watch-face-size + px;
  position: relative;
  display: inline-block;

  &.animate-counter-clockwise {
    //How to write a keyframe animation to animate from
  }


  &::after {
    content: "10";
    position: absolute;
    font-size: 68px;
    color: #fff;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    text-align: center;
    font-weight: 400;
    letter-spacing: -3px;

  }

  &::before {
    position: absolute;
    content: " ";
    border: 5px solid green;
    background: transparent;
    border-radius: $watch-border-size + px;
    width: $watch-border-size + px;
    height: $watch-border-size + px;
    top: -10px;
    left: -10px;
  }
}

//boilerplate styles
html {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    -o-box-sizing: border-box;
    box-sizing: border-box;
}
*, *:before, *:after {
    -webkit-box-sizing: inherit;
    -moz-box-sizing: inherit;
    -ms-box-sizing: inherit;
    -o-box-sizing: inherit;
    box-sizing: inherit;
}

.watch-container {
  width: 30%;
  margin: 50px auto;
  line-height: 22px;
  font-family: 'Roboto', arial, sans-serif;
  font-size: 14px;
  font-weight: 400;
  text-align: center;
}

我不知道您如何使用当前标记制作动画。据我所知,像这样径向动画 div 是不可能的。但是,您可以通过旋转正方形并添加一些覆盖物来伪造它。这是一个演示:

http://codepen.io/apexskier/pen/wGovRy

<div class="watch-face animating">
  <div class="cover"></div>
  <div class="a"></div>
  <div class="b"></div>
  <div class="c"></div>
  <div class="d"></div>
</div>

abcd 代表时钟的四个象限,每个象限都会围绕中间旋转并根据需要显示和隐藏. cover 用于隐藏第一个,因为它逐渐显示。

我使用 z-index 来正确地分层。

这是一些重要的 css(请参阅代码笔了解所有内容)

编辑:通过使整个事物宽度均匀来固定象限周围的边界

.watch-face {
  .a, .b, .c, .d, .cover {
    position: absolute;
height: ($watch-face-size / 2);
width: ($watch-face-size / 2);
    background-color: green;
    z-index: 5;
    transform-origin: bottom right;
    border-top-left-radius: ($watch-face-size / 2) - 1;
    border-top: 1px solid #fff; // hides a nasty green aliasing line
    border-left: 1px solid #fff; // hides a nasty green aliasing line
  }
  .cover {
    opacity: 0;
  }

  &.animating, &.animate {
    .a, .b, .c, .d, .cover {
      animation-duration: 4s;
      animation-timing-function: linear;
    }
  }

  &.animating {
    .a, .b, .c, .d, .cover {
      animation-iteration-count: infinite;
    }
  }

  &.animate {
    .a, .b, .c, .d, .cover {
      animation-iteration-count: 1;
    }
  }

  .a {
    animation-name: clock-a;
    opacity: 1;
    transform: rotate(90deg);
  }
  .b {
    animation-name: clock-b;
    transform: rotate(180deg);
  }
  .c {
    animation-name: clock-c;
    transform: rotate(270deg);
  }
  .d {
    animation-name: clock-d;
    transform: rotate(360deg);
  }
  .cover {
    animation-name: clock-cover;
    z-index: 10;
    background-color: #fff;
  }
}

@keyframes clock-cover {
  0% {
    opacity: 1;
  }
  74.9999999% {
    opacity: 1;
  }
  75% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@keyframes clock-a {
  0% {
    transform: rotate(0);
  }
  25% {
    transform: rotate(90deg);
  }
  100% {
    transform: rotate(90deg);
  }
}

@keyframes clock-b {
  0% {
    transform: rotate(90deg);
    opacity: 0;
  }
  24.999999% {
    opacity: 0;
  }
  25% {
    transform: rotate(90deg);
    opacity: 1;
  }
  50% {
    transform: rotate(180deg);
  }
  100% {
    transform: rotate(180deg);
    opacity: 1;
  }
}

@keyframes clock-c {
  0% {
    transform: rotate(180deg);
    opacity: 0;
  }
  49.999999% {
    opacity: 0;
  }
  50% {
    transform: rotate(180deg);
    opacity: 1;
  }
  75% {
    transform: rotate(270deg);
  }
  100% {
    transform: rotate(270deg);
    opacity: 1;
  }
}

@keyframes clock-d {
  0% {
    transform: rotate(270deg);
    opacity: 0;
  }
  74.999999% {
    opacity: 0;
  }
  75% {
    transform: rotate(270deg);
    opacity: 1;
  }
  100% {
    transform: rotate(360deg);
    opacity: 1;
  }
}

我会为这个动画使用 SVG,参见 the solution codepen:

<div class="watch-container">
  <div class="watch-face">
    <svg class="animator">
      <circle cx="50%" cy="50%" r="100" />
    </svg>
  </div>
</div>

所以你可以用简单的动画来制作圆圈:

@-webkit-keyframes clock-animation {
  0% { stroke-dashoffset: 0; }
  33% { stroke-dashoffset: 628; }
  100% { stroke-dashoffset: 628; }
}

.animator {
  height: 100%;
  width: 100%;

  circle {
    animation: clock-animation 3s linear infinite;
    fill: transparent;
    stroke: white;
    stroke-dasharray: 628;
    stroke-dashoffset: 0;
    stroke-width: 200px;
    transform: rotate(-90deg);
    transform-origin: 50% 50%;
  }
}

简短说明:您需要创建一个内部包含圆形元素的 SVG。 circle 元素有一个边框(描边),它实际上填满了整个圆的大小。然后,您需要使用 stroke-dasharray 定义笔划外观,它设置单笔划破折号的宽度(在我们的例子中为 100%),并使用 stroke-dashoffset 操作这个单一的大破折号。偏移量移动破折号,它稍微离开圆圈。

我通过简单的猜测/chrome 控制台手动选择了数字,但它们很容易用正常的学校几何规则计算,SASS 在这里有很大帮助。

这种方法真正令人满意的是您只需要一个 SVG 元素和一小块 CSS。它看起来非常漂亮,让你想起学生时代,这就是为什么这是我最喜欢做这些事情的方式。

灵感来自 this awesome progress bar implementation