PageSourceSearch

https://ivan-the-terrible.github.io/WelcomeLasers/Letters.js

js ivan-the-terrible.github.io collected 2026-10-03 09:21:29 UTC 3,993 bytes, 140 lines download raw bytes

1import { TextDirection } from "./TextDirectionEnum.js";
2import { DetermineFontSize } from "../util.js";
3import { Letter } from "./Letter.js";
4import { findCanvasCollision } from "./CanvasCollisions.js";
5
6/**
7 * Based on current screen size,
8 * we deconstruct a word into individual letters with properties to place them.
9 * @param {HTMLElement} canvas
10 * @param {CanvasRenderingContext2D} ctx
11 * @returns {Array} An array of letters with letter objects per index
12 */
13export function createLetters(canvas, ctx) {
14  const fontSize = DetermineFontSize(canvas.width);
15  //Need to set font size so 'measureText' has accurate sizing
16  ctx.font = fontSize + "px Helvetica";
17  ctx.textAlign = "center";
18  ctx.fillStyle = "white";
19
20  const random = Math.floor(Math.random() * 3);
21
22  const messageList = ["Welcome!", "Terrible", "Pong?"];
23  const message = messageList[random];
24  const letterLayoutOption = TextDirection[random];
25
26  const letters = [];
27  for (let i = 0; i < message.length; i++) {
28    const character = message[i];
29
30    const letter = new Letter(
31      canvas,
32      ctx,
33      character,
34      message.length,
35      i,
36      letterLayoutOption
37    );
38
39    letters[i] = letter;
40  }
41  return letters;
42}
43
44/**
45 * The last letter will run away to avoid the laser
46 * @param {Letter} letter
47 * @param {HTMLElement} canvas
48 * @param {Corners} corners
49 */
50export function lastLetterChase(letter, canvas, corners) {
51  if (letter.dy == null) {
52    makeLetterMove(letter, corners);
53  }
54  const canvasCollision = findCanvasCollision(
55    letter,
56    canvas.width,
57    canvas.height
58  );
59  if (Object.keys(canvasCollision).length != 0) {
60    letter.moveLetterFromCanvas(canvasCollision.xSide, canvas);
61    letter.moveLetterFromCanvas(canvasCollision.ySide, canvas);
62  }
63  letter.moveX();
64  letter.moveY();
65}
66
67/**
68 *
69 * @param {Letter} letter
70 * @param {Corner} corners
71 * @returns object with {x, y} that corresponds to the farthest corner
72 */
73function determineFarthestCorner(letter, corners) {
74  const diffCanvasX = letter.x - corners.BottomRight.x;
75  const diffCanvasY = letter.y - corners.BottomRight.y;
76  //Distance of letter to origin are its own coordinates
77  //aka letter.x - 0
78
79  const squaredCanvasX = diffCanvasX * diffCanvasX;
80  const squaredCanvasY = diffCanvasY * diffCanvasY;
81  const squaredOriginX = letter.x * letter.x;
82  const squaredOriginY = letter.y * letter.y;
83
84  const bottomRightRadicand = squaredCanvasX + squaredCanvasY;
85  const distanceToBottomRightCorner = Math.sqrt(bottomRightRadicand);
86
87  const topLeftRadicand = squaredOriginX + squaredOriginY;
88  const distanceToTopLeftCorner = Math.sqrt(topLeftRadicand);
89
90  const bottomLeftRadicand = squaredOriginX + squaredCanvasY;
91  const distanceToBottomLeftCorner = Math.sqrt(bottomLeftRadicand);
92
93  const topRightRadicand = squaredCanvasX + squaredOriginY;
94  const distanceToTopRight = Math.sqrt(topRightRadicand);
95
96  const distances = [
97    distanceToTopLeftCorner,
98    distanceToTopRight,
99    distanceToBottomRightCorner,
100    distanceToBottomLeftCorner,
101  ];
102  const greatestDistance = Math.max(...distances);
103  const farthestCorner = distances.indexOf(greatestDistance);
104
105  switch (farthestCorner) {
106    case 0:
107      return corners.TopLeft;
108
109    case 1:
110      return corners.TopRight;
111
112    case 2:
113      return corners.BottomRight;
114
115    case 3:
116      return corners.BottomLeft;
117
118    default:
119      break;
120  }
121}
122
123/**
124 * Give the letter velocity (dx,dy) based on the corners
125 * @param {Letter} letter
126 * @param {Corner} corners
127 */
128function makeLetterMove(letter, corners) {
129  const farthestCorner = determineFarthestCorner(letter, corners);
130  letter.dx = 5;
131  letter.dy = 5;
132
133  //dx/dy should be positive/negative based on what direction it needs to go in
134  //If it's zero, then negative dx/dy to move backwards towards zero
135  const xDirection = Math.sign(farthestCorner.x) ? 1 : -1;
136  const yDirection = Math.sign(farthestCorner.y) ? 1 : -1;
137
138  letter.dx = letter.dx * xDirection;
139  letter.dy = letter.dy * yDirection;
140}

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.