PageSourceSearch

https://ehmorris.com/bubbles/activePointer.js

js ehmorris.com collected 2026-10-03 20:28:15 UTC 2,916 bytes, 107 lines download raw bytes

1import { BLAST_HOLD_THRESHOLD, SLINGSHOT_MOVE_THRESHOLD } from "./constants.js";
2import { drawHoldBlastPreview, makeHoldBlast } from "./holdBlast.js";
3import { drawSlingshotPreview, makeSlingshot } from "./slingshot.js";
4
5export const makeActivePointer = (
6  canvasManager,
7  audioManager,
8  scoreStore,
9  tutorialManager,
10  pointerId,
11  startPosition,
12  ballAtPoint,
13  onTrigger,
14  defaultPointerAction
15) => {
16  const pointerStart = Date.now();
17  let currentPosition = { ...startPosition };
18  let hitSlingshotDistanceThresholdInTime = false;
19
20  const getDistance = () =>
21    Math.sqrt(
22      (startPosition.x - currentPosition.x) ** 2 +
23        (startPosition.y - currentPosition.y) ** 2
24    );
25
26  const setPosition = ({ x, y }) => {
27    currentPosition = { x, y };
28
29    if (
30      Date.now() - pointerStart <= BLAST_HOLD_THRESHOLD &&
31      getDistance() > SLINGSHOT_MOVE_THRESHOLD
32    ) {
33      hitSlingshotDistanceThresholdInTime = true;
34    }
35  };
36
37  const isSlingshot = () => hitSlingshotDistanceThresholdInTime;
38
39  const isHoldBlast = () =>
40    Date.now() - pointerStart > BLAST_HOLD_THRESHOLD &&
41    !hitSlingshotDistanceThresholdInTime;
42
43  const slingshotAllowed = () =>
44    tutorialManager.isTutorialComplete() ||
45    (!tutorialManager.isTutorialComplete() &&
46      tutorialManager.canMakeSlingshot());
47
48  const blastAllowed = () =>
49    tutorialManager.isTutorialComplete() ||
50    (!tutorialManager.isTutorialComplete() && tutorialManager.canMakeBlast());
51
52  const tapAllowed = () =>
53    tutorialManager.isTutorialComplete() ||
54    (!tutorialManager.isTutorialComplete() && tutorialManager.canMakeTap());
55
56  const trigger = () => {
57    if (isSlingshot() && slingshotAllowed()) {
58      onTrigger(
59        makeSlingshot(canvasManager, scoreStore, startPosition, currentPosition)
60      );
61      audioManager.playMiss();
62    } else if (isHoldBlast() && blastAllowed()) {
63      onTrigger(
64        makeHoldBlast(
65          canvasManager,
66          scoreStore,
67          startPosition,
68          Date.now() - pointerStart
69        )
70      );
71      audioManager.playImpact();
72    } else if (tapAllowed()) {
73      defaultPointerAction(currentPosition, ballAtPoint);
74    }
75  };
76
77  const draw = () => {
78    if (isSlingshot() && slingshotAllowed()) {
79      drawSlingshotPreview(
80        canvasManager,
81        startPosition,
82        currentPosition,
83        !tutorialManager.isTutorialComplete()
84      );
85
86      if (!tutorialManager.isTutorialComplete()) {
87        tutorialManager.previewingSlingshot();
88      }
89    } else if (isHoldBlast() && blastAllowed()) {
90      drawHoldBlastPreview(canvasManager, startPosition, pointerStart);
91
92      if (!tutorialManager.isTutorialComplete()) {
93        tutorialManager.previewingBlast();
94      }
95    }
96  };
97
98  return {
99    getId: () => pointerId,
100    setPosition,
101    trigger,
102    draw,
103    getDuration: () => Date.now() - pointerStart,
104    isSlingshot,
105    isHoldBlast,
106  };
107};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.