ReactJS _ styled-comonent-当我触发te next的动态动画时,我的组件眨眼

时间:2019-01-28 16:01:33

标签: javascript css reactjs animation styled-components

我创建了一个可以动态更改动画的代码。我的想法是复制this animation

我想知道为什么当我触发下一个动画时,我的DOM元素只是眨眼吗?

在我看来,通过更改props.animation的名称,我的元素应该重做整个循环。

在我看来,我的代码很公平,所以我不知道出什么问题了。除了那个样式化组件之外,还有一个很棒的工具,所以我认为这与我的代码结构有关,而与库无关。

Here a sandbox,如果您想查看我的组件的运行情况。

这是我的reactJS代码段:

import React from "react";
import ReactDOM from "react-dom"
import styled from 'styled-components';
import style from "./App.module.css"
import { keyframes } from "styled-components";



/*****  
 * 
 *  SET STYLED-COMPONENTS
 * 
 * *****/

//animations
const enterDownAnimation = keyframes`
  from{
    opacity:0;
  }
  50%{ 
    opacity:1;
  }
  to{ 
    transform:translate(0, 5vh);
    opacity:1;
  }
`


const enterSideAnimation = keyframes`
  from{
    transform:translate(3vw);
    opacity:0;
  } 
  to{ 
    transform:translate(0);
    opacity:1;
  }
`

const exitDownAnimation = keyframes`
from{
  transform:"translate(0, 35vh)"; 
  opacity:1;
}
50%{
  transform:"translate(0, 35vh)"; 
  opacity:1;
}
to{ 
  transform:"translate(0, 45vh)";
  opacity:0;
}`


const exitSideAnimation = keyframes`
from{
  transform:"translate(0, 35vh)"; 
  opacity:1;
}
50%{
  transform:"translate(0, 35vh)"; 
  opacity:1;
}
to{ 
  transform:"translate(0, 45vh)";
  opacity:0;
}`




// page_view
const ImageHolder = styled.div`
  position:absolute;
  width:510vw;
  left: ${props => props.viewPosition};
  transition:left 1s ease-in 0.2s;
  display:flex;
  overflow: hidden;
  margin:0;
`;


const ViewOne = styled.div`
  width: 102vw;
  height:100vh; 
  background: #E36300;  
`;

const ViewTwo = styled.div`
  width:102vw;
  height:100vh;
  background: #8AD300;
`;

// slide_content
const TextFirstLine = styled.div`
  position:absolute;
  top: 32vh;
  opacity:0;
  animation: ${props => props.animation} 0.6s cubic-bezier(.11,.91,1,1.03) .1s 1 normal forwards;
`

const TextSecondLine = styled.div`  
  position:absolute;
  top: 45vh;
  opacity:0;
  margin-top:5vh;
  animation:  ${props => props.animation} 0.6s cubic-bezier(.11,.91,1,1.03) .7s 1 normal forwards;
  `
const ViewImage = styled.img`
  position: absolute;
  font-size: 7vw; 
  opacity:0;
  top: 25%;
  width: 36vw;
  margin-top:5vh;
  right:3vw;
  animation:  ${props => props.animation} 0.6s cubic-bezier(.11,.91,1,1.03) 1.3s 1 normal forwards;
  `



const MoveViewButtonContainer = styled.div`

`
const MoveViewButton = styled.div`

`


export default class App extends React.Component {
  state = {
    exitLoop: true,
    currentView: 0,
    nextView: 0,

    elementType: "text",

    viewPosition: "0vw",
    textAnimation: enterDownAnimation,
    imageAnimation: enterSideAnimation
  }


  animationPrepare = (index) => {
    if (this.state.exitLoop) {
      this.updateButton(index);
      this.updateNextView(index);
    }
    this.textAnimation();
  }
  updateButton = (index) => {
    var buttonToTransparent = this.refs["button" + this.state.currentView];
    buttonToTransparent.style.backgroundColor = "transparent";

    var buttonCurrentView = this.refs["button" + index];
    buttonCurrentView.style.backgroundColor = "black";
  }

  updateNextView = (nextView) => {
    this.setState({ nextView })
  }

  textAnimation = () => {
    this.setState({ elementType: "text" },
      () => this.routeAnimationPosition());
    var textSecondLine = this.refs.textSecondLine
    textSecondLine.addEventListener("animationend", (e) => this.imageAnimation(e));
  }

  imageAnimation = () => {
    this.setState({ elementType: "image" },
      () => this.routeAnimationPosition());
    var viewImage = this.refs.viewImage
    viewImage.addEventListener("animationend", (e) => this.moveView(e));
  }

  routeAnimationPosition = () => {
    if (this.state.exitLoop) {
      this.setExitAnimation();
    } else {
      this.setEnterAnimation();
    }
  }

  setEnterAnimation = () => {
    if (this.state.elementType === "text") {
      if (this.state.currentView % 2 == 0) {
        this.setState({ textAnimation: this.enterDownAnimation });
      } else {
        this.setState({ textAnimation: this.enterUpAnimation })
      }
    } else {
      switch (this.state.currentView) {
        case 0:
          this.setState({ imageAnimation: this.enterSideAnimation });
          break;
        case 1:
          this.setState({ imageAnimation: this.enterUpAnimation });
          break;
        case 2:
          this.setState({ imageAnimation: this.enterDownAnimation });
          break;
        case 3:
          this.setState({ imageAnimation: this.enterSideAnimation });
          break;
        case 4:
          this.setState({ imageAnimation: this.enterUpAnimation });
          break;
        default:
          console.log("no animation found")
          break; // test return
      }
    }
  }

  setExitAnimation = () => {
    if (this.state.elementType === "text") {
      if (this.state.currentView % 2 == 0) {
        this.setState({ textAnimation: exitDownAnimation });
      } else {
        this.setState({ textAnimation: exitUpAnimation })
      }
    } else {
      switch (this.state.currentView) {
        case 0:
          this.setState({ imageAnimation: this.exitSideAnimation });
          break;
        case 1:
          this.setState({ imageAnimation: this.exitUpAnimation });
          break;
        case 2:
          this.setState({ imageAnimation: this.exitDownAnimation });
          break;
        case 3:
          this.setState({ imageAnimation: this.exitSideAnimation });
          break;
        case 4:
          this.setState({ imageAnimation: this.exitUpAnimation });
          break;
        default:
          console.log("no animation found")
          break; // test return
      }
    }
  }


  moveView = () => {
    var newView = -(102 + (102 * this.state.nextView))
    this.setState({ viewPosition: newView + "vw" });

    var viewImage = this.refs.viewImage;
    viewImage.addEventListener("transitionend", () => {
      console.log("transition achieved")
      this.updateSlideData();
    }, false);
  }

  updateSlideData = () => {
    if (this.state.exitLoop) { 
      // prepare nextView 
      // text => todo 
      this.setState({
        currentView: this.state.nextView,
        exitLoop: true,
        imageSource: nextViewImage,
        // portfolioUrl:nextViewUrl,
        // firstLineText: nextViewFirstLine,
        // secondLineText:nextViewSecondLine
      },
        // inner_callback to ensure updated state 
        () => this.animationPrepare()
      )
    } else {
      // prepare the next pageView animation
      this.setState({
        exitLoop: false,
        isArrow: null
      })
      return
    }
  }

  // move background

  // animation enter

  render() {
    var buttonTab = [0, 1, 2, 3, 4]
    return (
      <div>
        <ImageHolder
          viewPosition={this.state.viewPosition}
          animation={this.state.animation}
          ref="imageHolder"
        >
          <ViewOne />
          <ViewTwo /> 
        </ImageHolder>

        {/* { this.generateButton(buttonTab)} */}
        <div
          className={style.button_holder}
        >
          <MoveViewButtonContainer
            className={style.button_view_container}
          >
            <MoveViewButton ref="button0" id={style.first_button} className={style.button_view} onClick={() => this.animationPrepare(0)} />
            <MoveViewButton ref="button1" className={style.button_view} onClick={() => this.animationPrepare(1)} />
          </MoveViewButtonContainer>
        </div>

        <div
          id={style.text_wrapper}
        >
          <TextFirstLine
            ref="textFirstLine"
            animation={this.state.textAnimation}
          >
            FirstLine
          </TextFirstLine>
          <TextSecondLine
            ref="textSecondLine"
            animation={this.state.textAnimation}
          >
            SecondLine
          </TextSecondLine>
        </div>


        <ViewImage
          ref="viewImage"
          animation={this.state.imageAnimation}
          alt="here an image"/>
      </div>

    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

任何提示都会很棒, 谢谢

0 个答案:

没有答案