我希望实现一组标志图像的CSS关键帧动画,标志必须无限滑动,以下是我是如何做到的:

.animated-logo-set {
  display: flex;
  flex-direction: column;
  height: 20px;
  overflow: hidden;
}
.animated-logo-set span {
  font-size: 20px;
  line-height: 20px;
  background-color: red;
  height: 20px;
  animation: slideup 5s infinite;
}
@keyframes slideup {
  0%,
  15% {
    transform: translateY(0);
  }
  50%,
  66% {
    transform: translateY(-20px);
  }
  90%,
  100% {
    transform: translateY(-40px);
  }
}
<div class="animated-logo-set">
  <span>Samsung</span>
  <span>Toyota</span>
  <span>Samsung</span>
</div>

这工作很好,如果我知道有多少标志图像是动画.在我的例子中,它可以是从2到20的任意数量的标志图像,例如,我如何处理此类动画的动态元素?有没有一种方法我们可以只使用CSS来完成它,或者我们需要使用JS来完成它?这里的任何指针都是值得感谢的.

以下是指向CodeSandbox的链接:https://codesandbox.io/s/blazing-forest-6oyk7w?file=/index.html:0-836.

谢谢.

推荐答案

只有在硬编码值的情况下(例如:您知道有多少项),才能在CSS中完成此操作.要对100个项目执行此操作,您需要js.

下面是它的一个普通的js类:

class BannerAnimation {
  #index
  el
  items
  duration = 4000
  animationDuration = 420

  constructor(props) {
    const { start, ...args } = props
    Object.assign(this, args)
    this.#index = start || 1
    if (!this.items || !this.items.length) {
      this.items = [...this.el.children].map((c) => c.innerHTML)
    }
    ;[...this.el.children].forEach((c) => c.remove())
    this.appendChild(this.#index - 1)
    this.el.style.setProperty('--dur', `${this.animationDuration}ms`)
    Object.assign(this.el.style, {
      display: 'block',
      height: this.el.children[0].offsetHeight + 'px'
    })
    setTimeout(this.start, this.duration)
  }

  start = () => {
    const div = this.appendChild(this.#index)
    const first = this.el.children[0]
    first.style.marginTop = `-${first.offsetHeight}px`
    this.el.style.height = div.offsetHeight + 'px'
    this.el.classList.add('animating')
    setTimeout(this.end, this.animationDuration)
  }

  end = () => {
    this.el.classList.remove('animating')
    this.el.children[0].remove()
    this.#index = (this.items.length + this.#index + 1) % this.items.length
    setTimeout(this.start, this.duration)
  }

  appendChild = (i) => {
    const div = document.createElement('div')
    div.innerHTML = this.items[i]
    this.el.appendChild(div)
    return div
  }
}

new BannerAnimation({
  el: banner,
  duration: 1000,
  // items: [1, 2, 3]
})
#banner {
  overflow: hidden;
  transition: height 0ms cubic-bezier(.4, 0, .2, 1);
  transition-duration: var(--dur);
}
#banner div:first-child {
  margin-top: 0px
}
#banner div {
  transition: margin-top 0ms cubic-bezier(.4, 0, .2, 1);
  transition-duration: var(--dur);
}
<div id="banner">
  <div>One</div>
  <div>
    Two
    <div style="height: 100px; border: 1px solid red;"></div>
  </div>
  <div>Three</div>
  <div>Four</div>
  <div>Five<br>and a half...</div>
  <div>Six</div>
  <div>Seven</div>
</div>
<hr>

应适用于任意数量的物品(至少2个).可以在同一页面上多次使用,用于不同的元素(当然,您需要相应地更新css). children 的身高可能会有所不同.

将以下配置作为对象:

  • el: required(HTML元素)
  • start:基于1的索引(默认:1)
  • 幻灯片更改间隔duration:毫秒(默认值:4000)
  • animationDuration:过渡持续时间(以毫秒为单位)(默认值:420)
  • items:个HTML字符串数组(默认:this.el的子项innerHTML)也可以处理数字(例如:items: [1, 2, 3]).换句话说,在上面的示例中,我可以将#banner留空,并将项传递为['One', 'Two'..., 'Seven'].

Css相关问答推荐

如何在悬停时缓慢更改渐变 colored颜色 ?

NextJs - Tailwind css类样式未应用于响应屏幕

如何仅以WooCommerce单一产品页面为目标?

如何解决 Spotify 嵌入代码中的白色背景错误?

更改 20 个实例中的一个组件的样式

CSS Select 器在 rvest 中找到,在 RSelenium 中找不到

Bootstrap 5 - 更改列顺序时出现问题

CSS 字符串变量的正确null值是多少?

Blazor 组件未链接 css

在 vuetify 中跨 `default.vue` 和 `index.vue` 维护网格系统

CSS 中的区域类似于 C# 区域?

如何在连字符 (-) 等特殊字符后分词

媒体查询以错误的宽度触发

在 css 中使用 FontAwesome 或 Glyphicons :before

定位背景图片,添加内边距

是否允许在链接中嵌套链接?

go 除文本输入的内阴影

脉动的心脏 CSS 动画

如何将 HTML
显示为内联元素?

使用 CSS3 滤镜模糊定义的边缘