首页 > 解决方案 > 如何在 JSX 中为数组的项目设置动画

问题描述

我有一个数组中的聊天列表,当用户与聊天机器人聊天时,它会实时更新。当有新消息到达时,最新消息将移至顶部。

我现在想为这种行为设置动画。有谁知道,我如何向移动到顶部的元素添加动画或过渡?

我的组件:

import { Component, h, Prop } from '@stencil/core';
import { BotUserModel } from '../../global/models/BotUserModel';
import { ChatCategory } from '../../global/models/ChatCategory';

@Component({
  tag: 'chathub-pool-column',
  styleUrl: 'pool-column.scss',
  shadow: true,
})
export class PoolColumn {
  @Prop()
  category: ChatCategory;

  render() {
    return (
      <div key={this.category.title}>
        <p>{this.category.title} | {this.category.chats.length}</p>
        <div>
          {this.category.chats.map((botUser: BotUserModel) => (
            <div key={botUser._id}
              class={
                'card text-white bg-primary mb-3 p-2 poolCard rounded-0'
              }
            >
              <div class={'card-header'}>{botUser._id}</div>
              <div class={'card-body d-flex flex-row ' +
              'justify-content-between align-items-center'}>
                <span class={'w-100 mr-2'}>
                  {botUser.incomingMessages.length > 0
                    ? botUser.incomingMessages[
                    botUser.incomingMessages.length - 1
                      ].text
                    : 'No message has arrived'}
                </span>
                <i class={'fa-plus'} />
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }

}

这是浏览器中的外观

编辑:

澄清一下:我理想的解决方案是,与最新消息的聊天移至顶部,而其他条目则降低一级。就像您每次拖放都会对列表进行排序一样。我最初的想法是使用 CSS-Transitions,但我不知道在这种情况下要监听哪个属性。

在 Christian 的一些帮助/启发下(见评论),我做了一个简单的闪烁效果,当有新消息到达时触发。

.blink {
  animation: pulse .5s;
}

@keyframes pulse {
  0% {
    opacity: 1;
  }

  50% {
    opacity: 0.75;
  }

  100% {
    opacity: 1;
  }
}

组件中的代码方法(我对初始代码进行了相当大的更改。“this.card”指的是div,即使用this.category.chats.map创建的)

  @Watch('timestamp')
  handleTextChange() {
    this.card.classList.add('blink');
    this.card.onanimationend = () => {
      this.card.classList.remove('blink');
    };
  }

这很好,但是如果您有一个想法,我将如何实现我的理想解决方案,我将非常感激。

标签: css-animationsjsxstenciljs

解决方案


我会使用 CSS 动画。在我看来,这是实现不会弄乱代码的动画的最简单方法。遗憾的是我看不到你的 CSS 属性,我不确定你的哪个类适合这个,但我的想法是这样的:

.card {
  /*Your properties*/

  animation-duration: .3s;
  animation-name: slidein;
  animation-fill-mode: forwards;
  width: 0%;
  overflow: hidden;

  /*Your properties*/
}

@keyframes slidein {
  from {
    margin-left: 100%;
    width: 0%; 
  }

  to {
    margin-left: 0%;
    width: 100%;
  }
}

但正如我上面提到的 - 这取决于您已经编写的 CSS。在我看来,一个非常好的网站可以让你快速开始准备使用动画:

https://animista.net/play/entrances

添加

我认为在您的情况下没有必要,但您可以一一运行动画:

  {this.category.chats.map((botUser: BotUserModel, index) => (
    <div key={botUser._id}
      class={
        'card text-white bg-primary mb-3 p-2 poolCard rounded-0'
      }
      style={{'animation-delay': index+'s'}}
    >

所以这两个区别是使用地图函数的索引,而不是使用带有动画延迟的内联样式标签。第一个有1s延迟,第二个有2s延迟,依此类推。


推荐阅读