File size: 3,248 Bytes
2d460b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { toPng } from 'https://cdn.skypack.dev/html-to-image';

const durationTimer = () => {
  const elapsedDisplay = document.querySelector('.elapsed');
  let duration = 0.0;

  return () => {
    const startTime = performance.now();

    const incrementSeconds = setInterval(() => {
      duration += 0.1;
      elapsedDisplay.textContent = duration.toFixed(1);
    }, 100);

    const updateDuration = (task) => {
      if (task?.status == 'completed') {
        duration = task.completed_at - task.created_at;
        return;
      }

      duration = Number(((performance.now() - startTime) / 1_000).toFixed(1));
    };

    window.addEventListener('focus', updateDuration);

    return {
      cleanup: (completedTask) => {
        updateDuration(completedTask);
        clearInterval(incrementSeconds);
        window.removeEventListener('focus', updateDuration);
        elapsedDisplay.textContent = duration.toFixed(1);
      },
    };
  };
};

const updateCardName = (trainerName, pokeName, useTrainerName) => {
  const cardName = document.querySelector('.pokecard .name');

  if (!cardName) {
    return;
  }

  let trainerString = '';

  if (trainerName && useTrainerName) {
    trainerName = [...trainerName].filter((char) => char.match(/[\wÀ-ÿ '".,&+#!?:/\\()_-]/g)?.length).join('');
    trainerString = `${trainerName}${trainerName.match(/[sSzZ]$/g)?.length ? "' " : "'s "}`;
  }

  const fullName = `${trainerString}${pokeName}`;
  cardName.innerText = fullName;

  let nameWidth;
  let cardWidth = document.querySelector('.pokecard').getBoundingClientRect().width;

  let scale = 1.01;

  do {
    scale -= 0.01;
    cardName.style.transform = `scaleX(${scale})`;
    nameWidth = cardName.getBoundingClientRect().width;
  } while (nameWidth / cardWidth > 0.62);

  return fullName;
};

const rotateCard = () => {
  const RANGE = 0.1;
  const INTERVAL = 13; // ~75 per second
  let previousTime = 0;

  // Throttle closure
  return (card, containerMouseEvent) => {
    const currentTime = performance.now();

    if (currentTime - previousTime > INTERVAL) {
      previousTime = currentTime;

      const rect = card.getBoundingClientRect();

      const rotateX = (containerMouseEvent.clientY - rect.y - rect.height / 2) * RANGE;
      const rotateY = -(containerMouseEvent.clientX - rect.x - rect.width / 2) * RANGE;

      card.style.setProperty('--card-rx', rotateX + 'deg');
      card.style.setProperty('--card-ry', rotateY + 'deg');
    }
  };
};

const initialiseCardRotation = (scene) => {
  const card = document.querySelector('.pokecard');

  const mousemoveHandler = rotateCard().bind(null, card);

  scene.addEventListener('mousemove', mousemoveHandler, true);

  return mousemoveHandler;
};

const setOutput = (mode, state) => {
  const output = document.querySelector('.output');

  output.dataset.mode = mode;
  output.dataset.state = state;
};

const screenshotCard = async () => {
  const card = document.querySelector('.pokecard');

  const imageUrl = await toPng(card, {
    width: 400,
    height: 558,
    backgroundColor: 'transparent',
    style: {
      transform: 'none',
    },
  });

  return imageUrl;
};

export { durationTimer, updateCardName, initialiseCardRotation, setOutput, screenshotCard };