Плавная остановка анимации ключевого кадра CSS

у меня есть следующий код: http://jsfiddle.net/odj8v0x4/.

function stopGlobe() {
    $('.mapfront').removeClass('mapfront-anim');
    $('.mapback').removeClass('mapback-anim');
}

function startGlobe() {
    $('.mapfront').addClass('mapfront-anim');
    $('.mapback').addClass('mapback-anim');
}
@keyframes mapfront_spin {
    0% {
        background-position: 1400px 0%;
    }
    100% {
        background-position: 0 0%;
    }
}
@keyframes mapback_spin {
    0% {
        background-position: 0 0%;
    }
    100% {
        background-position: 1400px 0%;
    }
}
@-webkit-keyframes mapfront_spin {
    0% {
        background-position: 1400px 0%;
    }
    100% {
        background-position: 0 0%;
    }
}
@-webkit-keyframes mapback_spin {
    0% {
        background-position: 0 0%;
    }
    100% {
        background-position: 1400px 0%;
    }
}
body {
    margin: 50px;
    background: #000;
}
.globe {
    width: 400px;
    height: 400px;
    position: relative;
}
.front {
    width: 400px;
    height: 400px;
    background: url(http://dl.dropboxusercontent.com/u/17180596/SphereForeground.png);
    z-index: 5;
    position: absolute;
    top: 0;
    left: 0;
}
.back {
    width: 400px;
    height: 400px;
    background: url(http://dl.dropboxusercontent.com/u/17180596/SphereBackground.png);
    z-index: 2;
    position: absolute;
    top: 0;
    left: 0;
}
.mapfront, .mapback {
    border-radius: 300px;
    width: 340px;
    height: 340px;
    position: absolute;
    top: 30px;
    left: 30px;
    z-index: 4;
}
.mapfront {
    background: url(http://dl.dropboxusercontent.com/u/17180596/CartoForeground.png) repeat-x;
}
.mapfront-anim {
    -webkit-animation: mapfront_spin 15s linear infinite;
    animation: mapfront_spin 15s linear infinite;
}
.mapback {
    background: url(http://dl.dropboxusercontent.com/u/17180596/CartoBackground.png) repeat-x;
    position: absolute;
}
.mapback-anim {
    -webkit-animation: mapback_spin 15s linear infinite;
    animation: mapback_spin 15s linear infinite;
}
<div class="globe">
    <div class="front"></div>
    <div class="mapfront mapfront-anim"></div>
    <div class="mapback mapback-anim"></div>
    <div class="back"></div>
</div>

после выполнения функций javascript stopGlobe() анимация останавливается, но резко останавливается.

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

4 ответов


вам не понравится этот ответ, но реальность такова, что анимации CSS3 не очень полезны для достижения этого. Чтобы сделать эту работу, вам нужно будет реплицировать много вашего CSS в вашем Javascript, который разрушает точку (например, в этом тесно связанном ответе изменить скорость анимации CSS3?). Чтобы действительно остановить его плавно, лучше всего было бы написать анимацию на такой платформе, как библиотека анимации Greensock который обеспечивает все инструменты, которые вам нужны, чтобы сделать это на самом деле плавно остановить, а не внезапно остановиться.


вы можете достичь этого, используя только CSS.

все, что вам нужно, это немного движения, чтобы сделать его гладким.

Итак, я установил transform translate при необходимости. И это преобразование переходит с легкостью, чтобы произвести эффект сглаживания.

Итак, при наведении курсора анимация останавливается (внезапно). Но в то же время применяется transform translate, и поскольку это преобразование переходит с соответствующим ослаблением, оно немедленно начинается с с той же скоростью, что и анимация.

эта скорость будет замедляться в соответствии с ослаблением, пока она не остановится.

Я добавляю оболочку в элемент, к которому применяется translate. Чтобы избежать того, что это преобразование "перемещает" элемент, нам нужно сделать элемент больше видимого пространства и установить внутри оболочки, которая ограничит видимую часть (которая будет статической)

просто наведите курсор на глобус. (смотри, Ма, не В JS)

 @keyframes mapfront_spin {
    0% {        background-position: 1400px 0%;    }
    100% {        background-position: 0 0%;    }
}
@keyframes mapback_spin {
    0% {        background-position: 0 0%;    }
    100% {        background-position: 1400px 0%;    }
}
@-webkit-keyframes mapfront_spin {
    0% {        background-position: 1400px 0%;    }
    100% {        background-position: 0 0%;    }
}
@-webkit-keyframes mapback_spin {
    0% {        background-position: 0 0%;    }
    100% {        background-position: 1400px 0%;    }
}
body {
    margin: 50px;
    background: #000;
}
.globe {
    width: 400px;
    height: 400px;
    position: relative;
}
.front {
    width: 400px;
    height: 400px;
    background: url(http://dl.dropboxusercontent.com/u/17180596/SphereForeground.png);
    z-index: 5;
    position: absolute;
    top: 0;
    left: 0;
}
.back {
    width: 400px;
    height: 400px;
    background: url(http://dl.dropboxusercontent.com/u/17180596/SphereBackground.png);
    z-index: 2;
    position: absolute;
    top: 0;
    left: 0;
}
.mapfront, .mapback {
    border-radius: 300px;
    width: 340px;
    height: 340px;
    position: absolute;
    top: 30px;
    left: 30px;
    z-index: 4;
    overflow: hidden;
}
.mapfront-inner {
    width: 380px;
    height: 340px;
    top: 0px;
    left: 0px;
    position: absolute;
    background: url(http://dl.dropboxusercontent.com/u/17180596/CartoForeground.png) repeat-x;
    transition: transform 1s ease-out;
}
.mapfront-anim {
    -webkit-animation: mapfront_spin 15s linear infinite;
    animation: mapfront_spin 15s linear infinite;
}
.globe:hover .mapfront-anim,
.globe:hover .mapback-anim 
{
    -webkit-animation-play-state: paused;
    animation-play-state: paused;
}
.globe:hover .mapfront-inner {
    transform: translateX(-40px);
}

.mapback-inner {
    width: 380px;
    height: 340px;
    top: 0px;
    left: -40px;
    background: url(http://dl.dropboxusercontent.com/u/17180596/CartoBackground.png) repeat-x;
    position: absolute;
    transition: transform 1s ease-out;
}
.globe:hover .mapback-inner {
    transform: translateX(40px);
}

.mapback-anim {
    -webkit-animation: mapback_spin 15s linear infinite;
    animation: mapback_spin 15s linear infinite;
}
<div class="globe">
    <div class="front"></div>
    <div class="mapfront">
        <div class="mapfront-inner mapfront-anim">
        </div>
    </div>
    <div class="mapback">
        <div class="mapback-inner  mapback-anim">
        </div>
    </div>
    <div class="back"></div>
</div>

используйте javascript для установки CSS. Установите animation-interation-count до 1 (вместо бесконечного) и установите animation-timing-function для облегчения.

затем он должен медленно остановиться.


вы ca. добавить ко всем ключевым кадрам animation-play-state: paused;. добавьте класс выше, чтобы перезаписать приостановленную анимацию-play-state: running;

просто удалите класс с javascript, если вы хотите приостановить его