maxeth / react-type-animation

A React typewriter animation based on typical with extended functionality and customization.
https://react-type-animation.netlify.app/
MIT License
391 stars 24 forks source link

Feature Request: omit cursor after animation is done #23

Open ahnaftahmid39 opened 1 year ago

ahnaftahmid39 commented 1 year ago

It would be a nice addition If I could remove the cursor after animation is finished when repeat is not Infinity and an additional prop like omitCursorAfterAnimating and cursor is true.

Nice package.

maxeth commented 1 year ago

Right, I'll note this down.

You could do a (slightly complicated) workaround for now by copying over the default animation css styles, passing them manually via className and using callback functions inside the sequence array where you can then remove the className from the ref passed to the callback function.

If that's confusing you can post your code and I'll show you what I mean.


I'd look somewhat like this:

const CURSOR_CLASS_NAME = 'custom-type-animation-cursor';
 const [counter, setCounter] = useState(0)
return (
  <>
    <TypeAnimation
      ref={ref}
      cursor={false}
      style={{
        fontSize: '1.75rem',
      }}
      className={CURSOR_CLASS_NAME}
      sequence={[
        'One',
        800,
        'One Two',
        800,
        'One Two Three',
        (el) => { if (counter === repeatNum) el.classList.remove(CURSOR_CLASS_NAME)}, // A reference to the element gets passed as the first argument of a callback function
         () => { setCounter(p => p+1) }
      ]}
      repeat={Infinity}
    />

    <style global jsx>{`
      .custom-type-animation-cursor::after {
        content: '|';
        animation: cursor 1.1s infinite step-start;
      }
      @keyframes cursor {
        50% {
          opacity: 0;
        }
      }
    `}</style>
  </>
);

You'd have to update some counter inside React state each time a sequence is completed, and then remove the class name if counter === repeatNum

ahnaftahmid39 commented 1 year ago

Hey thanks for your response. I was able to use your approach in my next js project like following: Should I close this issue ? styles.module.css


.custom-type-animation-cursor::after {
  content: '|';
  animation: cursor 1.1s infinite step-start;
}
@keyframes cursor {
  50% {
    opacity: 0;
  }
}

Home.jsx

import styles from '../styles/Home.module.css';
import { useRef } from 'react';

const repeatCount = 3;

const Home = () => {
  const counter = useRef(0);
  return (
    <>
      <TypeAnimation
        cursor={false}
        omitDeletionAnimation={true}
        repeat={repeatCount}
        className={`${styles['custom-type-animation-cursor']}`}
        sequence={[
          'Share your notes',
          3000,
          'Help Others',
          3000,
          'Teach and Learn',
          3000,
          (el) => {
            if (counter.current == repeatCount) {
              el.classList.remove(styles['custom-type-animation-cursor']);
            } else {
              counter.current++;
            }
          },
        ]}
      />
    </>
  );
};
maxeth commented 1 year ago

Let's leave it open until the feature gets added, which may take a while anyways :)