gpt4 book ai didi

javascript - 如何在不使用 setTimeout 的情况下恰好在 1 秒后停止关键帧动画? - 队列中的问题事件

转载 作者:行者123 更新时间:2023-11-30 14:24:08 26 4
gpt4 key购买 nike

我认为这将是一个很难解决的问题......

我创建了一个速度计,显示我所在城市发生的地震次数。我想以两种方式为这个速度计设置动画:background-color(没有地震时为绿色,有 3000 地震时为红色)和此彩色 div 的宽度(我为背景颜色设置动画的 div)。因此,当没有地震时,宽度将为 0,当有 3000 次地震时,宽度将为 100%。

动画是 2 秒,所以例如如果我有 1500 地震:添加动画速度计的类

  $('#first').addClass('first-start');

然后使用 setTimeout 我添加了一个类来在 1 秒后停止动画

 setTimeout(function() {
$('#first').addClass('first-pause');
}, 1000);

这段代码几乎总是能正常工作。

现在我添加一个片段:

$('#first').addClass('first-start');

setTimeout(function() {
$('#first').addClass('first-pause');
}, 1000);
#page {
margin-top: 50px;
width: 300px;
height: 300px;
background-color: #000;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 4;
overflow: hidden;
}

#box-first{
width: 200px;
height: 100px;
background-color: #fff;
border-radius: 200px 200px 0 0;
margin-top: 10px;
margin-bottom: 10px;
position: relative;
display: flex;
justify-content: flex-end;
align-items: flex-start;
z-index: 3;
overflow: hidden;
}

#first{
border-radius: 200px 200px 0 0;
margin: 0;
background: red;
width: 200px;
height: 100px;
transform: rotate(180deg);
transform-origin: 50% 100%;
position: absolute;
top: 0px;
right: 0px;
border: 0;
z-index: 1;
}

#n1{
font-size: 20px;
color: #fff;
font-weight: bold;
position: absolute;
left: 50px;
right: 0;
text-align: center;
top: 50px;
bottom: 0;
display: flex;
align-items: flex-end;
justify-content: center;
width: 100px;
height: 50px;
background: #000;
border-radius: 100px 100px 0 0;
z-Index: 1;
overflow: hidden;
}

@keyframes first {
0% {
background-color: green;
transform: rotate(180deg);
}
33% {
background-color: yellow;
transform: rotate(240deg);
}
66% {
background-color: orange;
transform: rotate(300deg);
}
100% {
background-color: red;
transform: rotate(360deg);
}
}



.first-start {
animation: first 2s linear;
}

.first-pause {
animation-play-state: paused;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="page">
<div id="box-first">
<div id="first">

</div>
<div id="n1">
1500
</div>
</div>
</div>

https://jsfiddle.net/hoymds97/

问题是我在一个包含很多事件的大文件(4000 行)中使用此代码,并且在同一函数中有 8 个速度计。我注意到有时(当有更多事件时)setTimeout 不会在为动画速度计添加类后立即启动。

结果,动画会在...之后停止例如,在我们的例子中,它好像在 1700 毫秒而不是 1000 秒后阻塞。有时它甚至会在 2 秒后停止。

我认为问题在于 queue 中的许多事件。

那么我该如何解决这个问题呢?

是否可以始终使用 setTimeout 或不使用它来解决?

我希望你能帮助我,对不起我的英语。

最佳答案

这是一个全新的想法,它依赖于过渡而不是动画,您可以轻松调整状态而不会出现同步问题。

主要技巧是对背景颜色使用渐变并调整其位置以获得所需的颜色。

这是一个简单的代码来说明着色:

.box {
background: linear-gradient(to right, green, yellow, orange, red);
background-size: 2000% 100%;
transition:1s;
background-repeat: no-repeat;
background-position: 0 0;
height: 200px;
}

.box:hover {
background-position: 100% 0;
}
<div class="box">

</div>

如您所见,我定义了 4 种颜色的渐变,我们只需要调整 background-size 以获得着色(0%绿色和 100% 红色)。这在视觉上不会完全相同,因为我们不会像动画那样使用纯色,因此我将 background-size 设置得足够大以产生纯色的错觉。

现在,我们只需要找到 background-positiondegree 的值,这很容易。 backround-position0%100% 之间的值,度数是 180deg360 度。对于状态 50%,我们逻辑上将使用 50% 作为背景位置,使用 270deg 作为转换和 x% 状态我们将分别使用 x%x%*(360deg - 180deg) + 180deg = x%*180deg + 180deg = 180deg(x% + 1)

这是一个 50% 的例子(悬停查看)

#page {
margin-top: 50px;
width: 300px;
height: 300px;
background-color: #000;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
z-index: 4;
overflow: hidden;
}

#box-first{
width: 200px;
height: 100px;
background-color: #fff;
border-radius: 200px 200px 0 0;
margin-top: 10px;
margin-bottom: 10px;
position: relative;
display: flex;
justify-content: flex-end;
align-items: flex-start;
z-index: 3;
overflow: hidden;
}

#first{
border-radius: 200px 200px 0 0;
margin: 0;
background: linear-gradient(to right, green, yellow, orange, red);
background-size: 2000% 100%;
background-repeat:no-repeat;
background-position:0% 0%;
transition:1s;
width: 200px;
height: 100px;
transform: rotate(180deg);
transform-origin: 50% 100%;
position: absolute;
top: 0px;
right: 0px;
border: 0;
z-index: 1;
}
#box-first:hover #first{
transform: rotate(270deg);
background-position:50% 0%;
}

#n1{
font-size: 20px;
color: #fff;
font-weight: bold;
position: absolute;
left: 50px;
right: 0;
text-align: center;
top: 50px;
bottom: 0;
display: flex;
align-items: flex-end;
justify-content: center;
width: 100px;
height: 50px;
background: #000;
border-radius: 100px 100px 0 0;
z-Index: 1;
overflow: hidden;
}
<div id="page">
<div id="box-first">
<div id="first">

</div>
<div id="n1">
1500
</div>
</div>
</div>

为了使其动态化,我们需要使用 JS 调整值,过渡将完成这项工作。为此,我们可以为转换为所需值的状态定义一个data-attribute

这是一个示例,我还简化了 html 并使用了伪元素和 CSS 变量

setTimeout(function() {
$('.box').each(function() {
var d = $(this).data('state');
$(this).attr("style", "--s:" + d);
});
}, 1000);
body {
margin: 0;
background: #000;
}

.box {
width: 200px;
height: 100px;
background-color: #fff;
border-radius: 200px 200px 0 0;
margin: 10px;
position: relative;
display: inline-flex;
z-index: 0;
overflow: hidden;
}

.box:before {
content: "";
position: absolute;
z-index: -1;
border-radius: 200px 200px 0 0;
background: linear-gradient(to right, green, yellow, orange, red);
background-size: 2000% 100%;
background-repeat: no-repeat;
background-position: calc(var(--s, 0) * 1%) 0%;
transition:2s linear;
width: 200px;
height: 100px;
transform: rotate(calc((var(--s, 0)/100 + 1)*180deg));
transform-origin: 50% 100%;
top: 0px;
right: 0px;
}

.box:after {
content: attr(data-number);
font-size: 20px;
color: #fff;
font-weight: bold;
text-align: center;
margin: auto auto 0;
width: 100px;
height: 50px;
line-height: 50px;
background: #000;
border-radius: 100px 100px 0 0;
z-Index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box" data-number="1500" data-state="50"></div>

<div class="box" data-number="1000" data-state="20"></div>

<div class="box" data-number="3000" data-state="80"></div>

<div class="box" data-number="6000" data-state="100"></div>

您可能会注意到,由于过渡对所有对象都相同,因此所有对象的持续时间都相同。如果您想要不同的持续时间并保持相同的速度,也只需在过渡中使用 CSS 变量即可。

setTimeout(function() {
$('.box').each(function() {
var d = $(this).data('state');
$(this).attr("style", "--s:" + d);
});
}, 1000);
body {
margin: 0;
background: #000;
}

.box {
width: 200px;
height: 100px;
background-color: #fff;
border-radius: 200px 200px 0 0;
margin: 10px;
position: relative;
display: inline-flex;
z-index: 0;
overflow: hidden;
}

.box:before {
content: "";
position: absolute;
z-index: -1;
border-radius: 200px 200px 0 0;
background: linear-gradient(to right, green, yellow, orange, red);
background-size: 2000% 100%;
background-repeat: no-repeat;
background-position: calc(var(--s, 0) * 1%) 0%;
transition: calc(2s * var(--s, 0)/100) linear;
width: 200px;
height: 100px;
transform: rotate(calc((var(--s, 0)/100 + 1)*180deg));
transform-origin: 50% 100%;
top: 0px;
right: 0px;
}

.box:after {
content: attr(data-number);
font-size: 20px;
color: #fff;
font-weight: bold;
text-align: center;
margin: auto auto 0;
width: 100px;
height: 50px;
line-height: 50px;
background: #000;
border-radius: 100px 100px 0 0;
z-Index: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box" data-number="1500" data-state="50"></div>

<div class="box" data-number="1000" data-state="20"></div>

<div class="box" data-number="3000" data-state="80"></div>

<div class="box" data-number="6000" data-state="100"></div>

关于javascript - 如何在不使用 setTimeout 的情况下恰好在 1 秒后停止关键帧动画? - 队列中的问题事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52213872/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com