0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[React]自動テキスト入力を実装してみた

Posted at

https://tech.nextroll.com/ここの自動テキスト入力の箇所を実装してみたときのメモです。

動画(画質が粗い。。)
video.gif

Promiseだらけになってますが、もっと簡単にできる?
カーソルは|をアニメーションで点滅させて表現しています。

ソース(抜粋)
import React, { useState, useEffect } from "react";
import "./home/Home.css";

const MAIN_TEXT = "Join NextRoll as we build";
const SUB_TEXT1 = "modern web UIs";
const SUB_TEXT2 = "scalable data pipelines";
const SUB_TEXT3 = "open source software";
const SUB_TEXT4 = "real-time bidding";
const array_text = [SUB_TEXT1, SUB_TEXT2, SUB_TEXT3, SUB_TEXT4];

export const Test: React.FC = () => {
  const [subText, setSubText] = useState([""]);

  const addChar = (array: string[], val: string): string[] => {
    array.push(val);
    return [...array];
  };
  const delChar = (array: string[]): string[] => {
    array.pop();
    return [...array];
  };

  //SUB_TEXT1~SUB_TEXT4を受け取り、文字入力したり削除したり
  const autoTypeText = (text: string) =>
    new Promise((resolve, reject) => {
      const array = Array.from(text);
      Promise.resolve()
        .then(() => {
          //入力
          return Promise.all(
            array.map((val: string, index) => {
              return new Promise((resolve1, reject) => {
                setTimeout(() => {
                  setSubText((prev) => addChar(prev, val));
                  resolve1(true);
                }, 50 * index);
              });
            })
          );
        })
        .then(() => {
          //少し待つ
          return new Promise((resolve2) => {
            setTimeout(() => {
              resolve2(true);
            }, 1000);
          });
        })
        .then((values) => {
          //削除
          return Promise.all(
            Array.from({ length: text.length }).map((val, index) => {
              return new Promise((resolve3, reject) => {
                setTimeout(() => {
                  setSubText((prev) => delChar(prev));
                  resolve3(true);
                }, 50 * index);
              });
            })
          );
        })
        .then(() => {
          //少し待って終わる
          return new Promise(() => {
            setTimeout(() => {
              resolve(true);
            }, 500);
          });
        });
    });

  //無限ループ
  const infiniteTextLoop = () => {
    (async () => {
      for (let i = 0; ; i++) {
        await autoTypeText(array_text[i]);
        if (i === array_text.length - 1) i = -1;
      }
    })();
  };

  useEffect(() => {
    infiniteTextLoop();
  }, []);

  return (
    <div style={{ margin: "20px", fontSize: "20px" }}>
      <span style={{ marginRight: "8px" }}>{MAIN_TEXT}</span>
      <span>{subText}</span>
      <span className="CursolSpan">|</span>
    </div>
  );
};
css(抜粋)
.CursolSpan {
  color: black;
  animation-duration: 0.7s;
  animation-timing-function: ease;
  animation-delay: 0s;
  animation-iteration-count: infinite;
  animation-direction: normal;
  animation-fill-mode: none;
  animation-play-state: running;
  animation-name: blink;  
}

@keyframes blink {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

参考

Promise直列の無限ループについて
https://zenn.dev/wintyo/articles/2973f15a265581

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?