如何正确地在中间停止动画
How to stop the animation in the middle of it properly
这是一个使用 CSS 个关键帧的简单脉动动画。
问题是如果我想丢弃或删除动画中间的动画,动画会突然停止(突然跳到其初始状态,如您在代码片段中所见)。
我想让动画顺利回到初始状态,即使你在动画中间停止它。
JQuery 和 TweenMax 被接受。
有什么办法吗?
let test = document.getElementById("test");
setTimeout(function(){
test.classList.add("addAniamte");
}, 2000)
setTimeout(function(){
test.classList.remove("addAniamte");
test.classList.add("removeAniamte");
console.log('stoping aniamtion!');
}, 4500)
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1, 1);
}
50% {
-webkit-transform: scale(3, 3);
}
100% {
-webkit-transform: scale(1, 1);
};
}
#test {
background: red;
width: 20px;
height: 20px;
margin: 60px;
}
.addAniamte{
-webkit-animation: pulse 1s linear infinite;
animation: pulse 1s linear infinite;
}
.removeAniamte{
-webkit-animation: none;
animation:none;
}
<div id="test"></div>
我试图通过使用 getComputedStyle
使 javascript 完全动态化。为了顺利停止动画,我们需要有一个观察者变量,它会计算每个动画周期的持续时间。 (tempAnimationWatcher
).
- 向元素添加动画开始事件。
- 计算单次动画时长(
testAnimationTime
)并启动tempAnimationWatcherInterval
观看动画循环时间tempAnimationWatcher
- 如果
stopAnimation
,在剩余 css 时间后停止动画。 (testAnimationTime - tempAnimationWatcher
)
注意:testAnimationTime
计算是基于css动画时间以秒为单位的考虑。参见第 testAnimationTime = parseInt(animationDurationInCss.substring(0, animationDurationInCss.length - 1)) * 1000;
行,这是删除最后一个字符并以毫秒为单位进行转换。
const test = document.getElementById("test");
let tempAnimationWatcher = 0;
let testAnimationTime = 0;
let tempAnimationWatcherInterval;
test.addEventListener('animationstart', function (e) {
console.log('animation starts')
const animationDurationInCss = getComputedStyle(test).animationDuration;
testAnimationTime = parseInt(animationDurationInCss.substring(0, animationDurationInCss.length - 1)) * 1000;
tempAnimationWatcher = 0;
tempAnimationWatcherInterval = setInterval(() => {
tempAnimationWatcher += 10;
if (tempAnimationWatcher >= testAnimationTime) tempAnimationWatcher = 0;
}, 10);
});
function startAnimation() {
test.classList.add("addAniamte");
}
function stopAnimation() {
clearInterval(tempAnimationWatcherInterval);
setTimeout(() => {
test.classList.remove("addAniamte");
console.log("stoping aniamtion!");
}, (testAnimationTime - tempAnimationWatcher));
}
startAnimation();
@keyframes pulse {
0% {
-webkit-transform: scale(1, 1);
}
50% {
-webkit-transform: scale(3, 3);
}
100% {
-webkit-transform: scale(1, 1);
}
;
}
#test {
background: red;
width: 20px;
height: 20px;
margin: 60px;
}
.addAniamte {
animation: pulse 2s linear infinite;
}
<div id="test"></div>
<hr>
<button onclick="startAnimation()">Start</button>
<button onclick="stopAnimation()">Stop</button>
使用 GSAP 很容易做到这一点!以下是如何在 GSAP 3 中执行此类操作。
var tween = gsap.from("#test", {duration: 1, scale: 0.33, repeat: -1, yoyo: true, paused: true});
function startAnimation() {
tween.play();
}
function stopAnimation() {
tween.pause();
gsap.to(tween, {duration: 0.5, progress: 0});
}
#test {
background: red;
width: 60px;
height: 60px;
margin: 60px;
}
<div id="test"></div>
<button onclick="startAnimation()">Start</button>
<button onclick="stopAnimation()">Stop</button>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.0.4/dist/gsap.min.js"></script>
如果没有 GSAP(或者至少是一种仅使用 JS 的方法),它就会像其他答案所示那样非常混乱且容易出错。事实上,我对这个问题有 my own question which lead to a CSS-Tricks article。
这是一个使用 CSS 个关键帧的简单脉动动画。
问题是如果我想丢弃或删除动画中间的动画,动画会突然停止(突然跳到其初始状态,如您在代码片段中所见)。
我想让动画顺利回到初始状态,即使你在动画中间停止它。
JQuery 和 TweenMax 被接受。
有什么办法吗?
let test = document.getElementById("test");
setTimeout(function(){
test.classList.add("addAniamte");
}, 2000)
setTimeout(function(){
test.classList.remove("addAniamte");
test.classList.add("removeAniamte");
console.log('stoping aniamtion!');
}, 4500)
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1, 1);
}
50% {
-webkit-transform: scale(3, 3);
}
100% {
-webkit-transform: scale(1, 1);
};
}
#test {
background: red;
width: 20px;
height: 20px;
margin: 60px;
}
.addAniamte{
-webkit-animation: pulse 1s linear infinite;
animation: pulse 1s linear infinite;
}
.removeAniamte{
-webkit-animation: none;
animation:none;
}
<div id="test"></div>
我试图通过使用 getComputedStyle
使 javascript 完全动态化。为了顺利停止动画,我们需要有一个观察者变量,它会计算每个动画周期的持续时间。 (tempAnimationWatcher
).
- 向元素添加动画开始事件。
- 计算单次动画时长(
testAnimationTime
)并启动tempAnimationWatcherInterval
观看动画循环时间tempAnimationWatcher
- 如果
stopAnimation
,在剩余 css 时间后停止动画。 (testAnimationTime - tempAnimationWatcher
)
注意:testAnimationTime
计算是基于css动画时间以秒为单位的考虑。参见第 testAnimationTime = parseInt(animationDurationInCss.substring(0, animationDurationInCss.length - 1)) * 1000;
行,这是删除最后一个字符并以毫秒为单位进行转换。
const test = document.getElementById("test");
let tempAnimationWatcher = 0;
let testAnimationTime = 0;
let tempAnimationWatcherInterval;
test.addEventListener('animationstart', function (e) {
console.log('animation starts')
const animationDurationInCss = getComputedStyle(test).animationDuration;
testAnimationTime = parseInt(animationDurationInCss.substring(0, animationDurationInCss.length - 1)) * 1000;
tempAnimationWatcher = 0;
tempAnimationWatcherInterval = setInterval(() => {
tempAnimationWatcher += 10;
if (tempAnimationWatcher >= testAnimationTime) tempAnimationWatcher = 0;
}, 10);
});
function startAnimation() {
test.classList.add("addAniamte");
}
function stopAnimation() {
clearInterval(tempAnimationWatcherInterval);
setTimeout(() => {
test.classList.remove("addAniamte");
console.log("stoping aniamtion!");
}, (testAnimationTime - tempAnimationWatcher));
}
startAnimation();
@keyframes pulse {
0% {
-webkit-transform: scale(1, 1);
}
50% {
-webkit-transform: scale(3, 3);
}
100% {
-webkit-transform: scale(1, 1);
}
;
}
#test {
background: red;
width: 20px;
height: 20px;
margin: 60px;
}
.addAniamte {
animation: pulse 2s linear infinite;
}
<div id="test"></div>
<hr>
<button onclick="startAnimation()">Start</button>
<button onclick="stopAnimation()">Stop</button>
使用 GSAP 很容易做到这一点!以下是如何在 GSAP 3 中执行此类操作。
var tween = gsap.from("#test", {duration: 1, scale: 0.33, repeat: -1, yoyo: true, paused: true});
function startAnimation() {
tween.play();
}
function stopAnimation() {
tween.pause();
gsap.to(tween, {duration: 0.5, progress: 0});
}
#test {
background: red;
width: 60px;
height: 60px;
margin: 60px;
}
<div id="test"></div>
<button onclick="startAnimation()">Start</button>
<button onclick="stopAnimation()">Stop</button>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.0.4/dist/gsap.min.js"></script>
如果没有 GSAP(或者至少是一种仅使用 JS 的方法),它就会像其他答案所示那样非常混乱且容易出错。事实上,我对这个问题有 my own question which lead to a CSS-Tricks article。