File size: 1,669 Bytes
75fefa7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
import { useEffect, useRef, useState } from 'react';
import { encryptText } from '@/components/app/(home)/sections/hero/Title/Title';



export default function useSwitchingCode(code: string, ms = 20, progress = 1, fill = true) {
  const [value, setValue] = useState(code);
  const prevCode = useRef(value);

  useEffect(() => {
    if (code === prevCode.current) return;

    let i = 0;

    setValue(prevCode.current);

    let timeout: number;

    const tick = () => {
      i += progress;

      const prevLines = prevCode.current.split('\n');
      const currentLines = code.split('\n');

      const maxLines = fill ? 10 : Math.max(prevLines.length, currentLines.length);
      while (prevLines.length < maxLines) prevLines.push('');
      while (currentLines.length < maxLines) currentLines.push('');

      const remainingLines = prevLines.map((line, index) => {
        if (line === currentLines[index]) return line;

        const charLength = Math.floor(line.length * (i / 30));

        return (currentLines[index]?.slice(0, Math.floor(currentLines[index].length * (i / 30))) ?? '')
         + encryptText(line.slice(charLength), 0, { randomizeChance: 0.5 });
      });

      setValue((fill ? remainingLines : remainingLines.filter((line, index, arr) => {
        if (line === '' && arr[index - 1] === '') return false;

        return true;
      })).join('\n'));

      if (i < 30) {
        timeout = window.setTimeout(tick, ms);
      } else {
        prevCode.current = code;
      }
    };

    tick();

    return () => {
      window.clearTimeout(timeout);
      prevCode.current = code;
    };
  }, [code, ms, progress, fill]);

  return value;
}