Как я могу анимировать элементы массива в JSX - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть список чатов в массиве, который обновляется в режиме реального времени, когда пользователь общается с чатботом. Когда приходит новое сообщение, самое новое сообщение перемещается в начало.

Теперь я хочу анимировать это поведение. Кто-нибудь знает, как я могу добавить анимацию или переход к элементу, который перемещается вверх?

Мой компонент:

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>
    );
  }

}

Вот как это выглядит в браузере

РЕДАКТИРОВАТЬ:

Чтобы уточнить: Мой Идеальным решением было бы то, что чат с самым новым сообщением перемещается наверх, а остальные записи go на один шаг ниже. Как вы бы отсортировать список за перетаскивание. Моя первоначальная идея состояла в том, чтобы использовать CSS -Переходы, но я не знаю, какой атрибут слушать в этом случае.

С некоторой помощью / вдохновением Кристиана (см. Комментарии) я сделал простой эффект моргания это срабатывает, когда приходит новое сообщение.

.blink {
  animation: pulse .5s;
}

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

  50% {
    opacity: 0.75;
  }

  100% {
    opacity: 1;
  }
}

Метод кода в компоненте (я немного изменил исходный код. «this.card» относится к div, созданному с этим. category.chats.map)

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

Это хорошо, но если у вас есть идея, как мне достичь идеального решения, я был бы очень признателен.

1 Ответ

0 голосов
/ 17 февраля 2020

Я бы go с 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'}}
    >

Таким образом, эти два различия используют индекс функции карты, а не встроенный стиль. тег с задержкой анимации. Первый имеет задержку 1 с, второй - 2 с и т. Д.

...