我是否正确使用样式组件?

时间:2019-04-05 17:48:50

标签: javascript reactjs styled-components gsap

我的App.js开始看起来很长,我开始怀疑我是否按照预期的方式使用样式组件。

import React, { Component } from "react";
import "./App.scss";
import styled, { keyframes } from "styled-components";
import { TweenMax, TweenLite, Power2, TimelineLite } from "gsap";
import NameSvg from "./name";
import Nav from "./Nav";
import Player from "./Player";

class App extends Component {
  nav = null;
  hero = null;
  welcome = null;
  wrapper = null;
  scroll = null;
  name = null;
  tl = new TimelineLite({ paused: true });
  lis = [];
  welcomeTxt = [];

  changePlayingState = () => {
    this.setState({ playing: !this.state.playing });
  };

  state = {
    liText: [{ li: "My Work", id: 1 }, { li: "About Me", id: 2 }],
    welcomeTxt: [{ word: "Hello", id: 1 }, { word: "I'm", id: 2 }],
    playing: false
  };

  componentDidMount() {
    this.tl
      .staggerTo(this.welcomeTxt, 0.9, { opacity: 1, y: 70 }, 0.1)
      .staggerTo(
        this.welcomeTxt,
        0.9,
        { visibility: "visible", opacity: 0, delay: 0.5 },
        "prev"
      )
      .to(this.name, 0.9, { y: 350, x: -400 }, "prev+=.5")
      .to(this.nav, 0.9, { opacity: 1 }, "prev+=.5")
      .to(this.hero, 0.9, { opacity: 1 }, "p rev+=.9")
      .staggerTo(this.lis, 0.9, { opacity: 1, x: 20 }, "prev+=.9")
      .to(this.music, 0.9, { opacity: 1 }, "prev+=2")
      .to(this.scroll, 0.9, { visibility: "visible" }, "prev+=2");

    this.tl.play();
  }

  render() {
    return (
      <Wrapper ref={div => (this.wrapper = div)}>
        <Nav ref={div => (this.nav = div)}>
          Logo
          <ul>
            {// map through the elements
            this.state.liText.map((element, index) => (
              <a href="#">
                <li key={index} ref={li => (this.lis[index] = li)}>
                  {element.li}
                </li>
              </a>
            ))}
          </ul>
          <Logo />
        </Nav>
        <Welcome ref={div => (this.welcome = div)}>
          {// map through the elements
          this.state.welcomeTxt.map((element, index) => (
            <div
              className={`welcome${index}`}
              key={index}
              ref={div => (this.welcomeTxt[index] = div)}
            >
              {element.word}
              <br />
            </div>
          ))}
          <Name ref={div => (this.name = div)}>
            <NameSvg className="namesvg" />
          </Name>
        </Welcome>

        <Music ref={div => (this.music = div)}>
          <ToolTip>
            pst..could i interest you in some music for your stay?
            <button className="noThanks">No..thanks</button>
          </ToolTip>
          <a href="#" onClick={this.changePlayingState}>
            {this.state.playing ? (
              <img
                src="https://img.icons8.com/material/48/000000/circled-pause.png"
                key={"pause"}
              />
            ) : (
              <img
                src="https://img.icons8.com/material-rounded/48/000000/circled-play.png"
                alt="play button"
                key={"play"}
                className="playButton"
              />
            )}
          </a>
          {this.state.playing ? <Player playing={this.state.playing} /> : null}
        </Music>

        <Scroll ref={div => (this.scroll = div)}>
          <div className="one" />
          <div className="two" />
          <div className="three" />
        </Scroll>
        <Enter />
        <Hero ref={div => (this.hero = div)} className="hero" />
      </Wrapper>
    );
  }
}

export default App;

const building = keyframes`
  0% {
    left: 0;
    width:0;
    opacity:1;
  } 
  50%{
    left:0;
    width:70%;
    opacity:.7
  }
  100% {
    left: 70%;
    width:0;
    opacity:0;
  }
`;

const Wrapper = styled.div`
  display: grid;
  background: #f8f8f8;
  height: 100vh;
  grid-template-columns: repeat(12, 1fr);
  grid-template-rows: repeat(12, 1fr);
  font-family: "Roboto Condensed", sans-serif;
  transform: translateX(-15px);
  overflow: hidden;
`;

const Logo = styled.div``;

const appear = keyframes`
  0% {
    opacity:0
  } 
  50%{
    opacity:.7
  }
  100% {
    opacity:1;
  }
`;

const Name = styled.div`
  position:absolute;
  top:-6%;
  left:-12%;
  height:300%;
  grid-column: 1/5;
  grid-row: 9/13;
  z-index: 3;
  }
`;

const Music = styled.div`
  opacity: 0;
  grid-column: 11/13;
  grid-row: 1/2;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  margin-top: 3em;
  position: relative;
`;

const ToolTip = styled.div`
  ${"" /* visibility: hidden; */}
  position: absolute;
  height: auto;
  padding: 0.3em;
  width: auto;
  bottom: 5.5em;
  border: 0.3px solid black;
  left: -1em;
`;

const Scroll = styled.div`
  visibility: hidden;
  grid-column: 11/13;
  grid-row: 6/9;
  display: flex;
  ${"" /* flex-direction: column; */}
  justify-content: center;

  & .one {
    height: 10px;
    width: 10px;
    background: black;
    border-radius: 50%;
    margin-right: 0.5em;
  }

  & .two,
  .three {
    height: 10px;
    width: 10px;
    background: transparent;
    border: 0.5px solid black;
    border-radius: 50%;
    margin-right: 0.5em;
  }
`;

const Enter = styled.div`
  opacity: 0;
  background: white;
  grid-column: 11/13;
  grid-row: 9/13;
`;

const Hero = styled.div`
  opacity: 0;
  grid-column: 4/12;
  grid-row: 1/12;
  transform: translate(-20%, 20%);

  &:before {
    content: "";
    position: absolute;
    background: rgba(0, 0, 0, 0.9);
    height: 100%;
    width: 0%;
    display: block;
    animation: ${building} 1s;
    animation-delay: 3s;
    animation-fill-mode: forwards;
  }
`;

const Welcome = styled.div`
  position: relative;
  transform: translate(100px, 100px);
  font-family: Neou-Thin;
  font-size: 100px;
`;

我想知道如何将这些分支到自己的文件中... 我正在使用GSAP进行动画处理,当我尝试将其分支到自己的文件中时,动画会停止工作,或者出现错误,例如“无法补间null”

我尝试将导航分支到自己的文件中的一个示例:

import React, { Component } from "react";
import styled, { keyframes } from "styled-components";

class Nav extends Component {
  render() {
    return <Navigation />;
  }
}

export default Nav;

const Navigation = styled.div`
  opacity: 0;
  color: black;
  padding: 2em;
  grid-column: 1 / 3;
  grid-row: 1/6;
  font-family: Neou-Bold;

  & ul {
    list-style: none;
    padding: 0;
    margin-top: 3em;
    font-size: 1.1em;
  }

  & a {
    text-decoration: none;
    color: black;
  }
  & li {
    opacity: 0;
    padding-bottom: 0.5em;
  }
`;

执行此操作时,动画不起作用。

1 个答案:

答案 0 :(得分:1)

代码拆分

考虑何时将组件拆分为新文件,出于可读性或代码重用的考虑,您应该经常这样做。实际上,您的App.js有点偏。据我所知,您可以使用styled-components很好,但如果一个地方有很多文件,建议将它们放在单独的文件中。


GSAP问题

问题似乎与您如何尝试导出styled-components有关。您的Nav提取到新文件后未设置动画的原因似乎是因为您不必要地将其包装在额外的组件中。实际上,只需执行以下操作即可:

import React, { Component } from "react";
import styled, { keyframes } from "styled-components";

const Nav = styled.div`
  opacity: 0;
  color: black;
  padding: 2em;
  grid-column: 1 / 3;
  grid-row: 1/6;
  font-family: Neou-Bold;

  & ul {
    list-style: none;
    padding: 0;
    margin-top: 3em;
    font-size: 1.1em;
  }

  & a {
    text-decoration: none;
    color: black;
  }
  & li {
    opacity: 0;
    padding-bottom: 0.5em;
  }
`;

export default Nav;

当我尝试如上图所示导出Nav组件时,动画起作用了。