Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to create a typing effect on reactjs

So basically i have already created the typing effect but i can only get the first string in the array to work. I want to write out all at the arrays in new lines using the typing effect.I have listed the JSX and CSS files below. I should also point out that this just part of a big project so trying to run this JSX and css wont work

import React  from 'react';
import "./Content.css";


const content =()=>{
	const message =["WELCOME TO MY WORLD","THIS IS MY WEBSITE","I AM AT YOUR SERVICE"];
	let i =0 ;
	for(i=0; i<message.length;i++){
		  return(
			<div className='background'>
		  <h1 className="typewriter">
	  		{message[i]}	
	  	</h1>
	  	</div>

	  	)

	}
	
}

export default content;
background{
	display: flex;
	justify-content: center;
	flex-wrap: wrap;

}

canvas{width: 60;


}

.typewriter {
  text-align: center;
  overflow: hidden; 
  border-right: .15em solid black; 
  color: white;
  font-family: Courier New;
  top:30%;
  font-size: 40px;
  white-space: nowrap; 
  letter-spacing: .30em;
  animation: 
    typing 3.5s steps(30, end),
    blink-caret .75s step-end infinite;
}

/* The typing effect */
@keyframes typing {
  from { width:20% }
  to { width: 50% }
}


@keyframes blink-caret {
  from, to { border-color: transparent }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
like image 517
Udendu Abasili Avatar asked Apr 17 '18 19:04

Udendu Abasili


People also ask

How do you animate text like typing in after effects?

In the Layers panel, drop down the text layer properties. Click the Animate button and choose Opacity from the menu. In the new Animate controls, turn the Opacity down to 0%. Ensuring that the playhead is at the start of the clip, create a keyframe for the Range Selector Start property, then change the setting to 0%.


2 Answers

Could make it a class component like this:

class Typer extends React.Component {

  static defaultProps = {
    heading: '',
    dataText: []
  }

  constructor(props) {
    super(props);

    this.state = {
      text: '',
      isDeleting: false,
      loopNum: 0,
      typingSpeed: 150
    }
  }

  componentDidMount() {
    this.handleType();
  }

  handleType = () => {
    const { dataText } = this.props;
    const { isDeleting, loopNum, text, typingSpeed } = this.state;
    const i = loopNum % dataText.length;
    const fullText = dataText[i];

    this.setState({
      text: isDeleting ? fullText.substring(0, text.length - 1) : fullText.substring(0, text.length + 1),
      typingSpeed: isDeleting ? 30 : 150
    });

    if (!isDeleting && text === fullText) {
      
      setTimeout(() => this.setState({ isDeleting: true }), 500);
      
    } else if (isDeleting && text === '') {
      
      this.setState({
        isDeleting: false,
        loopNum: loopNum + 1
      });
      
    }

    setTimeout(this.handleType, typingSpeed);
  };

  render() {    
    return (
      <h1>{ this.props.heading }&nbsp;
        <span>{ this.state.text }</span>
        <span id="cursor"/>
      </h1>
    );
    
  }
}

ReactDOM.render(
  <Typer
    heading={'Things I want to type:'}
    dataText={["WELCOME TO MY WORLD","THIS IS MY WEBSITE","I AM AT YOUR SERVICE"]} 
  />, 
  document.getElementById('app')
);
@import url('https://fonts.googleapis.com/css?family=VT323');
body {
  font-family: 'VT323', monospace;
  background-color: #003B00;
  padding: 1em 2em;
}

h1 {
  color: #00FF41;
}

#cursor {
  border-left: .1em solid #00FF41;
  animation: blink .7s steps(1) infinite;
}

@keyframes blink {
  50% {
    border-color: transparent;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.0/umd/react-dom.production.min.js"></script>

<div id="app"></div>

Link to pen: https://codepen.io/AliKlein/pen/aPyKjy JSFiddle: https://jsfiddle.net/am9qke3v/

like image 174
Ali Klein Avatar answered Nov 03 '22 01:11

Ali Klein


If you want to use hooks to accomplish this, you can do something like this:

(big thanks to @AliKlein for the inspiration)

const { render } = ReactDOM;
const { useState, useEffect } = React;

const CONSTANTS = {
  DELETING_SPEED: 30,
  TYPING_SPEED: 150,
}

function TypeWriter({ messages, heading }) {
  const [state, setState] = useState({
    text: "",
    message: "",
    isDeleting: false,
    loopNum: 0,
    typingSpeed: CONSTANTS.TYPING_SPEED,
  });

  useEffect(() => {
    let timer = "";
    const handleType = () => {
      setState(cs => ({
        ...cs, // cs means currentState
        text: getCurrentText(cs),
        typingSpeed: getTypingSpeed(cs)
      }));
      timer = setTimeout(handleType, state.typingSpeed);
    };
    handleType();
    return () => clearTimeout(timer);
  }, [state.isDeleting]);

  useEffect(() => {
    if (!state.isDeleting && state.text === state.message) {
      setTimeout(() => {
        setState(cs => ({
          ...cs,
          isDeleting: true
        }))
      }, 500);
    } else if (state.isDeleting && state.text === "") {
      setState(cs => ({
        ...cs, // cs means currentState
        isDeleting: false,
        loopNum: cs.loopNum + 1,
        message: getMessage(cs, messages)
      }));
    }
  }, [state.text, state.message, state.isDeleting, messages]);

  function getCurrentText(currentState) {
    return currentState.isDeleting
      ? currentState.message.substring(0, currentState.text.length - 1)
      : currentState.message.substring(0, currentState.text.length + 1);
  }

  function getMessage(currentState, data) {
    return data[Number(currentState.loopNum) % Number(data.length)];
  }

  function getTypingSpeed(currentState) {
    return currentState.isDeleting
      ? CONSTANTS.TYPING_SPEED
      : CONSTANTS.DELETING_SPEED;
  }

  return (
    <h1>
      {heading}&nbsp;
        <span>{state.text}</span>
      <span id="cursor" />
    </h1>
  );
}

let msgs = ["WELCOME TO MY WORLD","THIS IS MY WEBSITE","I AM AT YOUR SERVICE"];
render(<TypeWriter heading={"Things I want to type:"} messages={msgs} />, document.body);
@import url('https://fonts.googleapis.com/css?family=VT323');
body {
  font-family: 'VT323', monospace;
  background-color: #003B00;
  padding: 1em 2em;
}

h1 {
  color: #00FF41;
}

#cursor {
  border-left: .1em solid #00FF41;
  animation: blink .7s steps(1) infinite;
}

@keyframes blink {
  50% {
    border-color: transparent;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>
like image 40
Matt Oestreich Avatar answered Nov 02 '22 23:11

Matt Oestreich