While browsing the Internet for inspiration, I came across an interesting-looking component.
I thought the block with the running ASCII art looked cool, but I couldn't quite figure out how it was implemented, so I started looking at the source code.
I found the code that looked like it might be doing the job, but it was minified.
const { floor: ra, abs: KE, min: QE } = Math,
O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"],
G7 = Date.now() % 3 ? O5[1] : O5[0],
V5 = G7.length,
JE = { fps: 60 };
function eT(e, t, n, r) {
const i = t.time * 8e-5,
s = QE(t.cols, t.rows),
o = t.metrics.aspect * 0.2,
l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s },
u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5;
return G7[u];
}
const tT = () => {
const e = j.useRef(null),
[t, n] = j.useState({ height: null, width: null });
return (
j.useEffect(() => {
function r() {
n({ height: window.innerHeight, width: window.innerWidth });
}
if (typeof window < "u") return n({ height: window.innerHeight, width: window.innerWidth }), window.addEventListener("resize", r), () => window.removeEventListener("resize", r);
}, []),
j.useEffect(() => {
const r = e.current;
if (!r) return;
const i = 12,
s = ra(t.width / i) * 1.6,
o = ra(t.height / i),
l = { aspect: s / o },
u = setInterval(() => {
let c = "";
for (let d = 0; d < o; d++) {
for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() });
c += `
`;
}
r.textContent = c;
}, 1e3 / JE.fps);
return () => clearInterval(u);
}, [t]),
a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) })
);
};
function nT(e) {
return Math.cos(e.x * e.x - e.y * e.y);
}
const { floor: ia, abs: rT, min: iT } = Math,
D5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"],
X7 = Date.now() % 3 ? D5[1] : D5[0],
F5 = X7.length,
sT = { fps: 60 };
function oT(e, t, n, r) {
const i = t.time * 8e-5,
s = iT(t.cols, t.rows),
o = t.metrics.aspect * 0.2,
l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s },
u = ia(rT(nT(l) - i) * F5 + (ia(e.x / 1) % 2) * 2) % F5;
return X7[u];
}
const aT = () => {
const e = j.useRef(null),
[t, n] = j.useState({ height: null, width: null });
return (
j.useEffect(() => {
function r() {
n({ height: window.innerHeight, width: window.innerWidth });
}
if (typeof window < "u") return n({ height: window.innerHeight, width: window.innerWidth }), window.addEventListener("resize", r), () => window.removeEventListener("resize", r);
}, []),
j.useEffect(() => {
const r = e.current;
if (!r) return;
const i = 12,
s = ia(t.width / i) * 1.6,
o = ia(t.height / i),
l = { aspect: s / o },
u = setInterval(() => {
let c = "";
for (let d = 0; d < o; d++) {
for (let f = 0; f < s; f++) c += oT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() });
c += `
`;
}
r.textContent = c;
}, 1e3 / sT.fps);
return () => clearInterval(u);
}, [t]),
a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) })
);
},
Usually, I would just powerthrough reading the minimized code to understand the implementation (or look for a .map
file to restore the original code). However, I realized that I never tried asking ChatGPT to do it for me... So I copied all of the above code and asked ChatGPT to "explain the code". Here is the response:
The provided code is quite complex, but I'll break it down into a more understandable format, explaining its different parts and their functionalities.
Overview
The code defines several functions and components using JavaScript, specifically in the context of a React application. It deals with generating some dynamic text content, presumably ASCII art or some kind of visual effect using characters from a predefined set. Additionally, it includes utility functions for event handling, performance timing, and HTML content conversion.
Key Components and Functions
Character Set Selection:
const { floor: ra, abs: KE, min: QE } = Math; const O5 = ["reactive.network REACTIVE.NETWORK", "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ"]; const G7 = Date.now() % 3 ? O5[1] : O5[0]; const V5 = G7.length;
- This part of the code imports some common Math functions (
floor
,abs
, andmin
) and defines two sets of characters, stored inO5
.- Based on the current time (
Date.now() % 3
), it selects one of these sets (G7
) to use later.- The length of the selected character set is stored in
V5
.Dynamic Character Selection Function:
function eT(e, t, n, r) { const i = t.time * 8e-5; const s = QE(t.cols, t.rows); const o = t.metrics.aspect * 0.2; const l = { x: ((4 * (e.x - t.cols / 6.25)) / s) * o, y: (5 * (e.y - t.rows / 4)) / s }; const u = ra(KE(YE(l) - i) * V5 + (ra(e.x / 1) % 2) * 2) % V5; return G7[u]; }
- The
eT
function generates a character based on the input position (e.x
,e.y
) and the current time (t.time
).- It adjusts the position using some aspect ratio calculations and selects a character from
G7
based on a combination of the position and time.- The purpose of
YE
function isn't directly clear from the code, but it seems to be a custom function used in this calculation.React Component (
tT
) for Displaying Dynamic Content:const tT = () => { const e = j.useRef(null); const [t, n] = j.useState({ height: null, width: null }); j.useEffect(() => { function r() { n({ height: window.innerHeight, width: window.innerWidth }); } if (typeof window < "u") { n({ height: window.innerHeight, width: window.innerWidth }); window.addEventListener("resize", r); return () => window.removeEventListener("resize", r); } }, []); j.useEffect(() => { const r = e.current; if (!r) return; const i = 12; const s = ra(t.width / i) * 1.6; const o = ra(t.height / i); const l = { aspect: s / o }; const u = setInterval(() => { let c = ""; for (let d = 0; d < o; d++) { for (let f = 0; f < s; f++) c += eT({ x: f, y: d }, { cols: s, rows: o, metrics: l, time: Date.now() }); c += ` `; } r.textContent = c; }, 1e3 / JE.fps); return () => clearInterval(u); }, [t]); return a.jsx("div", { style: { position: "absolute", top: 0, left: 0, width: "100%", height: "100%" }, children: a.jsx("div", { ref: e, style: { width: "100%", height: "100%", whiteSpace: "pre", overflow: "hidden" } }) }); };
- This is a React component that sets up an interval to periodically update the content of a
div
element (e.current
) with dynamically generated characters.- It calculates the number of columns (
s
) and rows (o
) based on the window size and then fills thediv
with characters generated by theeT
function.- The effect runs at a specified frames per second (
JE.fps
).
I followed up asking to "implement equivalent code in TypeScript and make it human readable" and got the following response:
import React, { useEffect, useRef, useState } from 'react';
const selectedCharacterSet =
"$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'. .:â–‘â–’â–“â–ˆ";
const characterSetLength = selectedCharacterSet.length;
const calculateCharacter = (
x: number,
y: number,
cols: number,
rows: number,
aspect: number,
time: number,
): string => {
const timeFactor = time * 0.000_08;
const size = Math.min(cols, rows);
const aspectRatio = aspect * 0.2;
const position = {
x: ((4 * (x - cols / 6.25)) / size) * aspectRatio,
y: (5 * (y - rows / 4)) / size,
};
const index =
Math.floor(
Math.abs(
Math.cos(position.x * position.x - position.y * position.y) -
timeFactor,
) *
characterSetLength +
(Math.floor(x) % 2) * 2,
) % characterSetLength;
return selectedCharacterSet[index];
};
type Size = {
height: null | number;
width: null | number;
};
const AsciiArtGenerator: React.FC = () => {
const textRef = useRef<HTMLDivElement>(null);
const [size, setSize] = useState<Size>({ height: null, width: null });
useEffect(() => {
const handleResize = () => {
setSize({ height: window.innerHeight, width: window.innerWidth });
};
// Initial size setting
handleResize();
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
useEffect(() => {
const element = textRef.current;
if (!element || !size.width || !size.height) return undefined;
const cols = Math.floor(size.width / 12) * 1.6;
const rows = Math.floor(size.height / 12);
const aspectRatio = cols / rows;
const intervalId = setInterval(() => {
let content = '';
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
content += calculateCharacter(
x,
y,
cols,
rows,
aspectRatio,
Date.now(),
);
}
content += '\n';
}
element.textContent = content;
}, 1_000 / 60); // 60 fps
return () => {
clearInterval(intervalId);
};
}, [size]);
return (
<div
ref={textRef}
style={{
height: '100%',
overflow: 'hidden',
whiteSpace: 'pre',
width: '100%',
}}
/>
);
};
export default () => {
return <AsciiArtGenerator />;
};
To my surprise, the response is not only good enough, but it is also very readable.
Here is the above component in action.
Comparing the outputs, it looks like LLM response overlooked a few implementation details, but it is still a good enough implementation to learn from. Definitely a neat use case I've not considered before!
Top comments (6)
Looks like dev.to editor does not support code blocks within block quotes. Sorry about the messy formatting.
Not sure what you did wrong?
The tick marks need to be on their own line :)
Yeah OpenAI and ChatGPT in general are good for pair programming, but I always use phind.com, since it's specifically configured for programming purposes and it's free as well!
it works for unminifying but sometime it hallucinates
I think we just have to accept that everything from LLMs has a chance of being fiction.
Some comments may only be visible to logged-in visitors. Sign in to view all comments.