javascript - 将时间转换为关键帧动画百分比
问题描述
我正在制作动画,并试图了解关键帧如何融入其中。
我想显示一个元素 3 秒,淡出 1 秒,等待 3 秒,淡入 1 秒,可见 3 秒。所以总共 8 秒 (3 + 1 + 3 + 1)。
我不知道如何将其写为关键帧。我的动画中有备用设置,因为它使用百分比。这是我到目前为止所拥有的:
time = 0;
window.addEventListener("load", function() {
setInterval(function() {
var label = document.getElementById("label");
if (time==0) {
label.innerHTML = ++time;
}
else {
label.innerHTML = ++time;
}
if (time>=8) time = 0;
}, 1000);
})
* {
margin: 0;
padding: 0;
font-family:sans-serif;
}
#Icons_A0 {
position: absolute;
box-sizing: border-box;
transform: translateX(-50%) translateY(-50%);
left: 50%;
top: 50%;
border: 1px solid #A1A1A1;
background: #E5E5E5;
width: 234px;
height: 238px;
background-color: rgba(255,255,255,1);
overflow: hidden;
opacity: 1;
}
#Rectangle_175 {
opacity: 1;
fill: rgba(75,134,193,1);
stroke: rgb(84, 75, 193);
stroke-width: 4px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Rectangle_175 {
position: absolute;
overflow: visible;
width: 134.35028076171875px;
height: 134.3502655029297px;
left: 49.825px;
top: 76.825px;
transform: rotate(45deg);
transform-origin: left;
}
#Ellipse_49 {
opacity: 1;
fill: rgba(180,180,180,1);
stroke: rgb(112, 112, 112);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_49 {
position: absolute;
overflow: visible;
width: 56px;
height: 56px;
left: 72px;
top: 51px;
animation: fadein 8s linear 0s infinite alternate;
}
@keyframes fadein {
0% {
opacity: 1;
}
20% {
opacity: 1;
}
30% {
opacity: 0;
}
60% {
opacity: 0;
}
70% {
opacity: 1;
}
100% {
opacity: 1;
}
}
<div id="Icons_A0">
<svg data-name="Rectangle 175" data-type="Rectangle" class="Rectangle_175">
<rect id="Rectangle_175" rx="0" ry="0" x="0" y="0" width="120" height="70">
</rect>
</svg>
<svg class="Ellipse_49">
<ellipse id="Ellipse_49" rx="28" ry="28" cx="28" cy="28">
</ellipse>
</svg>
<span id="label"></span>
</div>
解决方案
如果我正确理解了您的问题,则可以通过以下关键帧集来实现:
@keyframes fadein {
0% {
opacity: 1;
}
37.5% {
/* 3 / 8 */
opacity: 1;
}
50% {
/* (3 + 1) / 8 */
opacity: 0.0;
}
87.5% {
/* (3 + 1 + 3) / 8 */
opacity: 0.0;
}
100% {
opacity: 1;
}
}
注释显示了如何根据您的要求计算不同关键帧的百分比。要进行的另一个关键更改是alternate
从动画规则中删除行为,以确保动画循环按照需要以一致的方式重复:
/* remove alternate */
animation: fadein 8s linear 0s infinite;
这是您的代码的精简副本,用于隔离动画圈:
function animationListener(event) {
var type = event.type;
var label = type;
if (type=="animationiteration") {
if (app.interval!=null) {
clearInterval(app.interval);
}
app.time = 0;
app.startTime = new Date().getTime();
app.interval = setInterval(intervalFunction, 1000);
intervalFunction();
label = "iteration";
}
else if (type=="animationstart") {
label = "start";
}
else if (type=="animationend") {
label = "end";
}
app.stateLabel.innerHTML = label;
}
function intervalFunction() {
var time = new Date().getTime();
app.timeLabel.innerHTML = Math.round((time - app.startTime)/1000);
app.keyframeLabel.innerHTML = window.getComputedStyle(app.ellipse).content;
}
function loadHandler() {
app.ellipse = document.getElementById("Ellipse_49").parentNode;
app.stateLabel = document.getElementById("stateLabel");
app.timeLabel = document.getElementById("timeLabel");
app.keyframeLabel = document.getElementById("keyframeLabel");
app.ellipse.addEventListener("animationiteration", animationListener);
app.ellipse.addEventListener("animationend", animationListener);
app.ellipse.addEventListener("animationstart", animationListener);
}
document.addEventListener("DOMContentLoaded", loadHandler);
var app = {};
* {
font-family: sans-serif;
font-size: 11px;
letter-spacing: .6px;
}
#Ellipse_49 {
opacity: 1;
fill: rgba(180, 180, 180, 1);
stroke: rgb(112, 112, 112);
stroke-width: 1px;
stroke-linejoin: miter;
stroke-linecap: butt;
stroke-miterlimit: 4;
shape-rendering: auto;
}
.Ellipse_49 {
position: absolute;
overflow: visible;
width: 56px;
height: 56px;
left: 72px;
top: 51px;
/* remove alternate */
animation: fadein 8s linear 0s infinite;
}
#container {
top: 130px;
left: 10px;
position: relative;
display: block;
align-items: center;
}
label {
width: 80px;
display: inline-block;
}
@keyframes fadein {
0% {
opacity: 1;
content: "show";
}
37.5% {
/* 3 / 8 */
opacity: 1;
content: "fade out";
}
50% {
/* (3 + 1) / 8 */
opacity: 0.0;
content: "wait";
}
87.5% {
/* (3 + 1 + 3) / 8 */
opacity: 0.0;
content: "fade in";
}
100% {
opacity: 1;
content: "show";
}
}
<svg class="Ellipse_49">
<ellipse id="Ellipse_49" rx="28" ry="28" cx="28" cy="28">
</ellipse>
</svg>
<div id="container">
<label>time: </label>
<span id="timeLabel"></span>
<br>
<label>state: </label>
<span id="stateLabel"></span>
<br>
<label>key frame: </label>
<span id="keyframeLabel"></span>
</div>
推荐阅读
- css - 没有类噩梦的内联 CSS
- excel-formula - 如果单元格为空,日期公式返回空白
- javascript - 在 JavaScript 中更改滑块范围拇指的高度
- firebase - Firestore 安全规则多个 get() 未按预期工作
- html - 当父容器高度固定时,如何使 Flexbox flex-column 内容不被压缩?
- r - 使用 data.table 按组对数据进行 Winsorize
- javascript - 我想点击菜单切换然后打开菜单
- typescript - [cocosCreator, cocos2d-x]loadScene回调函数不能使用bind?
- javascript - 如何使用 Datebox 在输入文本中设置/显示值日期
- android - Jsondatalistview 只显示最后一个值。怎么做?