完成所有嵌套转换后,是否有办法捕获事件

时间:2019-03-13 20:01:00

标签: javascript reactjs

我试图弄清楚所有嵌套过渡结束后如何捕获事件。例如,我有一个儿童字符串,将其拆分为单词,然后将每个单词拆分为字符后,我尝试为每个字符设置动画。为此,我用<Transition>包装了每个单词中的所有字符。但是,当每个单词中的所有字符都用过渡动画完成时,我需要赶上事件。动画开始后,onExited事件立即触发。

在下面的代码中,我需要找到一种方法来在动画中完成所有角色后将this.state.showHeadline设置为true。

链接到Codesandbox

import React from "react";
import { render } from "react-dom";
import { Transition, TransitionGroup } from "react-transition-group";
import styled, { css } from "styled-components";

const Content = styled.div`
  display: flex;
`;

const Word = styled.span`
  margin-right: 0.5em;
  &:last-child {
    margin-right: 0;
  }
`;
const Char = styled.span`
  text-align: center;
  min-width: 8px;
  color: black;
  backface-visibility: visible;
  transition: opacity 4.5s, filter 2s;
  transition-timing-function: ease-in-out;
  -webkit-font-smoothing: antialiased;
  webkit-text-stroke: 0.45px;
  -webkit-text-stroke: 0.45px rgba(0, 0, 0, 0.1);

  transform: perspective(1050px) rotateY(0deg) scale(0.9);
  display: inline-block;
  opacity: 0;

  ${props =>
    props.state &&
    ((props.state === "entering" &&
      css`
        opacity: 0;
      `) ||
      (props.state === "entered" &&
        css`
          opacity: 1;
        `))}
`;

class TextWrapper extends React.Component {
  constructor() {
    super();
    this.state = {
      showTitle: false,
      showHeadline: false
    };
  }

  setState(state) {
    super.setState(state);
  }

  componentDidMount() {
    setTimeout(
      this.setState(prevState => {
        return {
          showTitle: true
        };
      }),
      1000
    );
  }

  render() {
    const content = this.props.children.split(" ").map((word, i) => {
      const chars = word.split("").map((char, i, charArray) => {
        return (
          <Transition
            in={this.state.showTitle}
            timeout={(i + 0.5) * 400}
            key={char + i}
          >
            {state => <Char state={state}>{char}</Char>}
          </Transition>
        );
      });
      return (
        <Transition key={i} timeout={0}>
          <Word>
            <TransitionGroup
              appear={true}
              component={null}
              onEntered={console.log("char")}
            >
              {chars}
            </TransitionGroup>
          </Word>
        </Transition>
      );
    });

    return (
      <React.Fragment>
        <Content>
          <TransitionGroup appear={true} component={null} onExited={null}>
            {content}
          </TransitionGroup>
        </Content>
        {this.state.showHeadline && <Content>Hello</Content>}
      </React.Fragment>
    );
  }
}

const App = () => <TextWrapper>Example Text</TextWrapper>;

const root = document.getElementById("app");
if (root) {
  render(<App />, root);
}

2 个答案:

答案 0 :(得分:1)

您不需要redux

由于您的CSS正在处理动画定时,因此它们总是会比角色state所在的Transition延迟。因此,您需要做几件事:

  1. 确定string的长度。
  2. 跟踪通过其entered事件处理程序进入onEntered状态的所有字符。该处理程序采用添加到keysLoaded状态的回调函数。
  3. keysLoaded状态的长度与stringLength的长度进行比较。
  4. 如果两个匹配,它将触发一个showHeadline回调函数。

但是 ......您仍然必须补偿CSS transition的延迟(这就是showHeadline回调函数延迟3500ms的原因)!

工作示例

Edit Transition Component

答案 1 :(得分:0)

您需要设置一个计数器和一个侦听器,当一个单词的动画结束时,计数+1并收听计数是否等于单词长度。如果相等,请运行int hourglassSum(vector<vector<int>> arr) { if(arr.size() < 3 || arr[0].size() < 3 ) return -1; int rowSize = arr[0].size(); int sum = -9 * 6; // smallest negative sum possible; for( int i = 1; i < arr.size()-1; i++ ) { int tmp_sum = 0; for( int j = 1; j < rowSize-1; j++ ) { tmp_sum = (arr[i - 1][j - 1] + arr[i - 1][j] + arr[i - 1][j + 1] ); tmp_sum += (arr[i ][j ]); tmp_sum += (arr[i + 1][j - 1] + arr[i + 1][j] + arr[i + 1][j + 1]); sum = max(tmp_sum, sum); } } return sum; }