J'ai créé un composant qui enveloppe chaque lettre de mon texte dans une balise span: export default function Header ({text}) {let header = [] for (let i = 0; i

1
jakey_dev 16 mars 2021 à 17:32

2 réponses

Meilleure réponse

Changez le texte en un tableau de chaînes. Puis bouclez sur les mots et divisez-les en caractères:

export default function Header({ words = ["hello", "world"] }) {
  const header = words.map((word, j) => {
    return (
      <>
        <span>
          {word.split("").map((letter, i) => {
            const colours = [
              "red",
              "green",
              "yellow",
              "blue",
              "pink",
              "orange",
            ];
            const rng = Math.floor(Math.random() * colours.length);

            return (
              <span key={i} style={{ color: colours[rng] }}>
                {letter}
              </span>
            );
          })}
        </span>
        {j < words.length - 1 && <span className="white-space"></span>}
      </>
    );
  });

  return <h1 id="header">{header}</h1>;
}
1
Gh05d 16 mars 2021 à 14:52

Version improvisée:

function wrapLetters(word) {
  const wrappedLetters = [];
  const colours = ["red", "green", "yellow", "blue", "pink", "orange"];
  for (let i = 0; i < word.length; i++) {
    const rng = Math.floor(Math.random() * colours.length);
    wrappedLetters.push(
      <span key={i} style={{ color: colours[rng] }}>
        {word[i]}
      </span>
    );
  }
  return wrappedLetters;
}

function wrapWord(wrappedLetters, i, notLast) {
  return (
    <span className="wrapper" key={i}>
      {notLast
        ? [...wrappedLetters, <span className="white-space" />]
        : wrappedLetters}
    </span>
  );
}

export default function Header({ text }) {
  const words = text.split(" ");
  const wrappedWords = words
   .map(wrapLetters)
   .map((wrappedLetters, i) => {
     return wrapWord(wrappedLetters, i, i < words.length - 1);
   });
  return <h1 id="header">{wrappedWords}</h1>;
}

Sandbox: https://codesandbox.io /s/eloquent-sea-lvg6x?file=/src/Component.js:0-871


J'ai écrit le composant comme ça. J'espère que les commentaires sont explicites.

function wrapWord(word) {
  const lettersData = [];
  const colours = ["red", "green", "yellow", "blue", "pink", "orange"];
  for (let i = 0; i < word.length; i++) {
    const rng = Math.floor(Math.random() * colours.length);
    lettersData.push(
      <span key={i} style={{ color: colours[rng] }}>
        {word[i]}
      </span>
    );
  }
  return lettersData;
}

export default function Header({ text }) {
  const words = text.split(" "); // split text into an array if words
  const wordsData = words.map((word) => wrapWord(word)); // for each word create an array of spans

  // this method wraps each word with a span, and injects a space if it's not last word
  const combinedWords = wordsData.map((arr, i) => {
    return (
      <span className="wrapper" key={i}>
        {i < wordsData.length - 1
          ? [...arr, <span className="white-space" />]
          : arr}
      </span>
    );
  });

  return <h1 id="header">{combinedWords}</h1>;
}

Bac à sable de code: https: // codesandbox. io / s / happy-hugle-6xpud? file = / src / Component.js: 0-739

1
T J 16 mars 2021 à 16:02