首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用css关键帧同步两个动画?

如何使用css关键帧同步两个动画?
EN

Stack Overflow用户
提问于 2020-03-26 10:48:35
回答 3查看 967关注 0票数 6

我正在研究解决方案

我已经创建了一个基本的html横幅,在这里我想保持图像和文字动画的同步。

基本上,图像动画就像3秒左右的缩放徽标,同时图标也是动画,我希望文本在打字效果上是一样的。

我已经使用css和javascript创建了基本解决方案,但它不是同步的。

代码语言:javascript
复制
var typewriter = function(txt) {
  var container = document.getElementById('typewriter'),
    speed = 28,
    i = 0,
    wordsObj = txt.split(" ")
  container.textContent = "";
  runAllWords();

  function runAllWords() {

    if (i < wordsObj.length) {
      var a = (i == 0) ? i : i - 1;
      setTimeout(function() {
        showWord(wordsObj[i], 0)
      }, wordsObj[a].length * speed);
    }
  }

  function showWord(word, countWord) {
    if (countWord < word.length) {
      setTimeout(function() {
        showLetter(word, countWord)
      }, speed);
    } else {
      container.textContent = container.textContent + " ";
      i += 1;
      runAllWords();
    }
    if (i === wordsObj.length) {
      console.log('complete')
    }
  }

  function showLetter(word, countWord) {
    container.textContent = container.textContent + word[countWord];
    showWord(word, countWord + 1);
  }
}

var i = 0;

function myLoop() {
  //  create a loop function

  var dataType = document.getElementById('typewriter').dataset.typewriter,
    w = dataType.split(',')
  setTimeout(function() { //  call a 3s setTimeout when the loop is called
    typewriter(w[i]); //  your code here
    i++; //  increment the counter
    if (i < w.length) { //  if the counter < 10, call the loop function
      myLoop(); //  ..  again which will trigger another 
    } //  ..  setTimeout()
  }, 3000)
}

myLoop();
代码语言:javascript
复制
.addsp_320x50 {
  width: 100%;
  height: 50px;
  position: relative;
}

.addsp_320x50_img {
  position: absolute;
  top: 1px;
  left: 10px;
  width: 48px;
  height: 48px;
  border: 0px solid #ccc;
  border-radius: 50%;
}

.addsp_title_text {
  position: absolute;
  top: 5px;
  left: 70px;
  font-family: Open Sans;
  font-weight: bold;
}

.addsp_title_desc {
  position: absolute;
  top: 20px;
  left: 70px;
  font-family: Open Sans;
  color: #999;
}

.addsp_320x50_action button {
  height: 27px;
  background: #058562;
  border-radius: 4px;
  color: #fff;
  border-color: #058562;
  font-size: 12px;
  font-weight: bold;
  font-family: Open Sans;
  border-style: solid;
  position: absolute;
  right: 10px;
  top: 10px;
  display: flex;
}

.adz_text_1 {}

.adz_text_2 {
  animation: text2;
}

.adz_text_1,
.adz_text_2 {}

@keyframes text2 {
  0%,
  50%,
  100% {
    width: 0px;
  }
  60%,
  90% {
    width: 200px;
  }
}

@keyframes text1 {
  0%,
  50%,
  100% {
    width: 0px;
  }
  10%,
  40% {
    width: 200px;
  }
}

@media only screen and (min-width: 320px) {
  .addsp_320x50_img {
    width: 42px;
    height: 42px;
    top: 4px;
    left: 5px;
  }
  .addsp_title_text {
    top: 14px;
    left: 56px;
    font-size: 0.85rem;
  }
  .addsp_title_desc {
    top: 25px;
    left: 55px;
    font-size: 0.8rem;
  }
}

@media only screen and (min-width: 480px) {
  .addsp_title_text {
    top: 3px;
    left: 55px;
    font-size: 1.1rem;
  }
  .addsp_title_desc {
    top: 28px;
    left: 55px;
    font-size: 0.8rem;
  }
}

@media only screen and (min-width: 600px) {
  .addsp_title_text {
    top: 3px;
    left: 70px;
    font-size: 1.1rem;
  }
  .addsp_title_desc {
    top: 28px;
    left: 70px;
    font-size: 0.8rem;
  }
}

@media only screen and (min-width: 800px) {
  .addsp_title_text {
    top: 3px;
    left: 70px;
    font-size: 1.1rem;
  }
  .addsp_title_desc {
    top: 28px;
    left: 70px;
    font-size: 0.8rem;
  }
}

.addsp_320x50_img:nth-child(1) {
  animation-name: scale;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-delay: 1s;
  animation-iteration-count: infinite;
  animation-fill-mode: forwards;
  opacity: 0;
}

.addsp_320x50_img:nth-child(2) {
  animation-name: scale;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-delay: 4s;
  animation-iteration-count: infinite;
  animation-fill-mode: forwards;
  opacity: 0;
}

.addsp_320x50_img:nth-child(3) {
  animation-name: scale;
  animation-duration: 3s;
  animation-timing-function: linear;
  animation-delay: 7s;
  animation-iteration-count: infinite;
  animation-fill-mode: forwards;
  opacity: 0;
}

@keyframes scale {
  0% {
    transform: scale(1);
    opacity: 1
  }
  20% {
    transform: scale(1.2);
    opacity: 1
  }
  40% {
    transform: scale(1);
    opacity: 1
  }
  60% {
    transform: scale(1.2);
    opacity: 1
  }
  80% {
    transform: scale(1);
    opacity: 1
  }
  90% {
    transform: translateY(-100px);
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

.blinking-cursor {
  color: #2E3D48;
  -webkit-animation: 1s blink step-end infinite;
  -moz-animation: 1s blink step-end infinite;
  -ms-animation: 1s blink step-end infinite;
  -o-animation: 1s blink step-end infinite;
  animation: 1s blink step-end infinite;
}

@keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: black;
  }
}

@-moz-keyframes blink {
  from,
  to {
    color: transparent;
  }
  50% {
    color: black;
  }
}

@-webkit-keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: black;
  }
}

@-ms-keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: black;
  }
}

@-o-keyframes "blink" {
  from,
  to {
    color: transparent;
  }
  50% {
    color: black;
  }
}
代码语言:javascript
复制
<div class="addsp_320x50">
  <img src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="addsp_320x50_img">
  <img src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="addsp_320x50_img">
  <img src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="addsp_320x50_img">
  <div class="addsp_title_text">
    <span class="adz_text_1 typewriter" id="typewriter" data-typewriter="Web Strategy,
    		UX Testing,
    		Content Management System,
    		Web Design,
    		Research and Analytics,
    		Information Architecture,
    		Strategic Consulting,Maintenance and Support"></span><span class="blinking-cursor">|</span>
  </div>
  <div class="addsp_320x50_action">
    <button>DOWNLOAD</button></div>
</div>

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-03-30 23:15:34

我想你可能在找动画迭代事件动画启动事件

不要仅仅使用myLoop函数来调用自己,而是尝试使用这些侦听器来调用它。

js文件的末尾看起来应该是:

代码语言:javascript
复制
var i = 0;

function myLoop() {
  var dataType = document.getElementById("typewriter").dataset.typewriter,
    w = dataType.split(",");

  if (i < w.length -1 ) {
    typewriter(w[i]);
  }

  i++;
}

var imageElems = Array.from(document.querySelectorAll('.addsp_320x50_img'));
imageElems.forEach(elem=>{
 elem.addEventListener('animationstart',myLoop);
});

其中".addsp_320x50_img“是您给所有图像的任何公共选择器。

票数 1
EN

Stack Overflow用户

发布于 2020-04-03 08:35:36

从数学上讲,下沉意味着调整频率和相位。我会分别演示每一个。请注意,我要解释的是这个概念,您可以使用Javascript、css等在代码中实现它

频率

除非较长的持续时间是较短的持续时间的一个因素,否则不能击沉两个动画。

例如,在您的代码中,闪烁的持续时间为1s。因此,您的图像缩放持续时间和整个持续时间必须是一个选择的1s,2s,3s,.或者1/2,1/3,.

为了更好的理解,让我举一个简单的例子。假设两个图像想要动画化。

代码语言:javascript
复制
<img src="1.png" id="img1">
<img src="1.png" style="margin-left: 50px;" id="img2">  

考虑一下每个动画的两个不同的动画

代码语言:javascript
复制
@keyframes k1
{
    25%
    {
        transform: rotate(-4deg);
    }
    50%
    {
        transform: rotate(0deg);
    }
    75%
    {
        transform: rotate(3deg);
    }
    100%
    {
        transform: rotate(0deg);
    }
}

@keyframes k2
{
    50%
    {
        transform: scale(1.2);
    }
    100%
    {
        transform: scale(1);
    }
}

因此,由于k2更简单,我将首先将其分配给持续时间为0.7s的img2

代码语言:javascript
复制
#img2
{
    animation: k2 0.7s linear infinite;
}

根据上面所解释的,我将把动画k1分配给img1,持续时间为1.4s。(不是1.3s不是1.5s 非常重要!)

代码语言:javascript
复制
#img1
{
    animation: k1 1.4s linear infinite;
}

如果您运行此代码,您将看到他们是沉!若要更好地感受概念,请将k1的持续时间更改为0.9s。现在感觉他们是分开做他们的事情了!

Note

我将k1设置为1.4s (0.7s×2),因为k1似乎是一个组合,向前走回来,使用2x感觉他们在一起跳舞,保持同样的和谐!

相态

在css中,相位由animation-delay显示。修改频率(持续时间)足以淹没两个动画,但如果两个动画同时开始,它会感觉更好!因此,为了说明img1的延迟设置为0.2s。他们还在下沉,但感觉不太好!现在将延迟改为0.7。现在又很漂亮了!(也许更漂亮)

回到你的代码

你的图像的持续时间是1.2秒(3s的40%),你的文本闪烁时间是1s,正如你所看到的,它们不是彼此的因素,所以你不能沉下去!

票数 2
EN

Stack Overflow用户

发布于 2020-04-02 22:41:09

如果使用与打字机脚本相同的JavaScript循环控制动画,则不会丢失同步。我重写了打字机脚本,以便在下面的片段中完成此操作。

startTypewriter()投诉

首先,将收集到的所有消息转换为一个数组。

代码语言:javascript
复制
typewriter.getAttribute('data-typewriter').split(',');

然后启动CSS图标动画。因为JavaScript间隔在执行代码之前等待其持续时间,所以在创建间隔之前通过调用type()输入第一条消息。

代码语言:javascript
复制
icon.classList.add('icon-animation');

type(typewriter, messages[0].trim(), animationDuration - pauseDuration);

现在开始间隔,默认情况下每3秒运行一次。发生的第一件事是动画被重置,以防它不同步。

代码语言:javascript
复制
icon.classList.remove('icon-animation');
window.setTimeout(function() {
  icon.classList.add('icon-animation');
}, 25);

接下来,通过调用type()输入消息。在结束之前,将运行一次检查,以确定它是否位于最后一个数组元素上。如果是这样,它将重新开始。

代码语言:javascript
复制
if (i == messages.length) i = 0;

type()投诉

在开始时,计算timePerCharacter值。将消息拆分为数组,并清除打字机输出。

代码语言:javascript
复制
var timePerCharacter = duration / message.length;
var message = message.split('');
typewriter.innerHTML = '';

创建一个循环,运行每个timePerCharacter。这个字符输出到打字机输出。

代码语言:javascript
复制
typewriter.innerHTML += message[i];

一旦输出所有字符,循环就会被清除。

代码语言:javascript
复制
if (i == message.length) clearInterval(typeLoop);

斯尼彭特

代码语言:javascript
复制
var animationDuration = 3000;
var pauseDuration = 2000;

startTypewriter();

function startTypewriter() {
  var typewriter = document.getElementById('typewriter');
  var icon = document.getElementById('icon');
  var messages = typewriter.getAttribute('data-typewriter').split(',');
  
  icon.classList.add('icon-animation');
  
  type(typewriter, messages[0].trim(), animationDuration - pauseDuration);
    
  var i = 1;
  
  window.setInterval(function() {
    icon.classList.remove('icon-animation');
    window.setTimeout(function() {
      icon.classList.add('icon-animation');
    }, 25);
    
    type(typewriter, messages[i].trim(), animationDuration - pauseDuration);
    
    i++;
    
    if (i == messages.length) i = 0;
  }, animationDuration);
}

function type(typewriter, message, duration) {
  var timePerCharacter = duration / message.length;
  var message = message.split('');
  typewriter.innerHTML = '';

  var i = 0;

  var typeLoop = window.setInterval(function() {  
    typewriter.innerHTML += message[i];
    
    i++;
  
    if (i == message.length) clearInterval(typeLoop);
  }, timePerCharacter);
}
代码语言:javascript
复制
@keyframes icon {
  20% {
    transform: scale(0.9);
  }
  
  40% {
    transform: scale(1);
  }
  
  60% {
    transform: scale(0.9);
  }
  
  80% {
    transform: scale(1);
  }
  
  100% {
    transform: translateY(-200%);
  }
}

.icon {
  border-radius: 100%;
}

.icon-animation {
  animation: icon 3s;
}

@keyframes cursor {
  50% {
    color: transparent;
  }
}

.blinking-cursor {
  animation: cursor 1s steps(1) infinite;
}
代码语言:javascript
复制
<img id="icon" src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="icon">

<span id="typewriter" data-typewriter="
        Web Strategy,
    		UX Testing,
    		Content Management System,
    		Web Design,
    		Research and Analytics,
    		Information Architecture,
    		Strategic Consulting,
        Maintenance and Support
">
</span>
<span class="blinking-cursor">|</span>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60865536

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档