Подтвердить что ты не робот

Искажение анимации на css3 spinner

Я нашел один привлекательный счетчик (CSS3, SCSS): http://codepen.io/weaintplastic/pen/qEMZbx.

@for $i from 1 through 6 {
    @keyframes preload-show-#{$i}{
        from{
            transform: rotateZ(60* $i + deg) rotateY(-90deg) rotateX(0deg);
            border-left-color: #9c2f2f;
        }
    }
    @keyframes preload-hide-#{$i}{
        to{
            transform: rotateZ(60* $i + deg) rotateY(-90deg) rotateX(0deg);
            border-left-color: #9c2f2f;
        }
    }

    @keyframes preload-cycle-#{$i}{

        $startIndex: $i*5;
        $reverseIndex: (80 - $i*5);

        #{$startIndex * 1%}{
            transform: rotateZ(60* $i + deg) rotateY(90deg) rotateX(0deg);
            border-left-color: #9c2f2f;
        }
        #{$startIndex + 5%},
        #{$reverseIndex * 1%}{
            transform: rotateZ(60* $i + deg) rotateY(0) rotateX(0deg);
            border-left-color: #f7484e;
        }

        #{$reverseIndex + 5%},
        100%{
            transform: rotateZ(60* $i + deg) rotateY(90deg) rotateX(0deg);
            border-left-color: #9c2f2f;
        }
    }
}

@keyframes preload-flip{
    0%{
        transform: rotateY(0deg) rotateZ(-60deg);
    }
    100%{
        transform: rotateY(360deg) rotateZ(-60deg);
    }
}

body{
  background: #efefef;
}

.preloader{
  position: absolute;
  top: 50%;
  left: 50%;
    font-size: 20px;
    display: block;
    width: 3.75em;
    height: 4.25em;
    margin-left: -1.875em;
  margin-top: -2.125em;
    transform-origin: center center;
    transform: rotateY(180deg) rotateZ(-60deg);

    .slice{
        border-top: 1.125em solid transparent;
        border-right: none;
        border-bottom: 1em solid transparent;
        border-left: 1.875em solid #f7484e;
        position: absolute;
        top: 0px;
        left: 50%;
        transform-origin: left bottom;
        border-radius: 3px 3px 0 0;
    }

    @for $i from 1 through 6 {
      .slice:nth-child(#{$i}) { 
        transform: rotateZ(60* $i + deg) rotateY(0deg) rotateX(0);
        animation: .15s linear .9 - $i*.08s preload-hide-#{$i} both 1;
      }
    }


    &.loading{
        animation: 2s preload-flip steps(2) infinite both;
        @for $i from 1 through 6 {
          .slice:nth-child(#{$i}) { 
            transform: rotateZ(60* $i + deg) rotateY(90deg) rotateX(0);
            animation: 2s preload-cycle-#{$i} linear infinite both;
          }
        }
    }

}
<div class="preloader loading">
  <span class="slice"></span>
  <span class="slice"></span>
  <span class="slice"></span>
  <span class="slice"></span>
  <span class="slice"></span>
  <span class="slice"></span>
</div>

Но в середине анимации есть момент дрожания (сбой): нижняя часть шестиугольника перемещается вправо на один или два пикселя.

Я снял видео с этого момента: youtu.be/_TwDuxME8wc.

Я попытался восстановить его самостоятельно, но у меня недостаточно навыков. Не могли бы вы подсказать, как это можно исправить? Спасибо!

4b9b3361

Ответ 1

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

Если вы берете решение @Nick Barlett и меняете размер шрифта .preloader от 20px до 24px, вы избавитесь от десятичных значений. Смотрите это перо: http://codepen.io/pstenstrm/pen/mJJpvP

Это, конечно же, сделает загрузчик больше, поэтому вы можете изменить значения em на px.

Ответ 2

Измените состояние 100% на предзагрузке, чтобы иметь rotateZ(64deg)

@keyframes preload-flip{
    0%{
        transform: rotateY(0deg) rotateZ(-60deg);
    }
    100%{
        transform: rotateY(360deg) rotateZ(-64deg);
    }
}

Кажется, что большая проблема в целом с углами, поскольку ручка слегка искажена.

Ответ 3

Решение

@pstenstrm блестяще разрешает проблему с ошибкой +1.

Здесь возникает еще одна проблема:

В Firefox (только?) в верхнем левом треугольнике есть уродливая неровная граница.

Чтобы решить эту проблему, просто добавьте треугольную схему треугольников:

.slice{
  outline: 1px solid transparent;
}

Просмотрите демо, чтобы увидеть окончательный результат:

Запуск демо