bad-apple-console 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.html ADDED
@@ -0,0 +1,95 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Bad Apple! - Console Player</title>
7
+ <style>
8
+ * { margin: 0; padding: 0; box-sizing: border-box; }
9
+ body {
10
+ background: #0a0a0a;
11
+ color: #e0e0e0;
12
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
13
+ display: flex;
14
+ align-items: center;
15
+ justify-content: center;
16
+ height: 100vh;
17
+ text-align: center;
18
+ overflow: hidden;
19
+ }
20
+ .container {
21
+ max-width: 480px;
22
+ padding: 2rem;
23
+ }
24
+ h1 {
25
+ font-size: 2.5rem;
26
+ font-weight: 800;
27
+ margin-bottom: 0.5rem;
28
+ background: linear-gradient(135deg, #fff 0%, #888 100%);
29
+ -webkit-background-clip: text;
30
+ -webkit-text-fill-color: transparent;
31
+ }
32
+ .subtitle {
33
+ font-size: 1rem;
34
+ color: #666;
35
+ margin-bottom: 2rem;
36
+ }
37
+ .card {
38
+ background: #141414;
39
+ border: 1px solid #222;
40
+ border-radius: 12px;
41
+ padding: 1.5rem;
42
+ margin-bottom: 1.5rem;
43
+ }
44
+ .card p {
45
+ color: #999;
46
+ line-height: 1.6;
47
+ margin-bottom: 0.75rem;
48
+ }
49
+ .card p:last-child { margin-bottom: 0; }
50
+ kbd {
51
+ background: #222;
52
+ border: 1px solid #333;
53
+ border-radius: 4px;
54
+ padding: 2px 8px;
55
+ font-family: 'SF Mono', Monaco, monospace;
56
+ font-size: 0.85rem;
57
+ color: #ccc;
58
+ }
59
+ .shortcut {
60
+ display: flex;
61
+ gap: 0.5rem;
62
+ justify-content: center;
63
+ align-items: center;
64
+ margin-top: 1rem;
65
+ font-family: 'SF Mono', Monaco, monospace;
66
+ font-size: 0.85rem;
67
+ color: #555;
68
+ }
69
+ .status {
70
+ margin-top: 1.5rem;
71
+ font-size: 0.85rem;
72
+ color: #444;
73
+ }
74
+ </style>
75
+ </head>
76
+ <body>
77
+ <div class="container">
78
+ <h1>Bad Apple!</h1>
79
+ <p class="subtitle">Console Video Player</p>
80
+
81
+ <div class="card">
82
+ <p>Open Chrome DevTools to start playback automatically.</p>
83
+ <p>Or press <kbd>Space</kbd> to start manually.</p>
84
+ </div>
85
+
86
+ <div class="shortcut">
87
+ <kbd>F12</kbd> or <kbd>Cmd</kbd>+<kbd>Opt</kbd>+<kbd>J</kbd>
88
+ </div>
89
+
90
+ <p class="status" id="status">Waiting for DevTools...</p>
91
+ </div>
92
+
93
+ <script type="module" src="index.js"></script>
94
+ </body>
95
+ </html>
package/index.js ADDED
@@ -0,0 +1,94 @@
1
+ import { FRAMES, TOTAL_FRAMES } from './frames.js';
2
+
3
+ const FPS = 30;
4
+ const FRAME_INTERVAL = 1000 / FPS;
5
+
6
+ // Scale up the 120x90 images to display at 480x360 in the console
7
+ // (4x scale via CSS padding — browser upscales the image)
8
+ const DISPLAY_WIDTH = 120 * 4;
9
+ const DISPLAY_HEIGHT = 90 * 4;
10
+
11
+ // Pre-process all frames once: replace the small padding with scaled-up padding.
12
+ // This avoids regex/string manipulation inside the hot 30fps loop.
13
+ const SCALED_FRAMES = FRAMES.map(css =>
14
+ css.replace(
15
+ /padding:\s*45px\s+60px/,
16
+ `padding: ${DISPLAY_HEIGHT / 2}px ${DISPLAY_WIDTH / 2}px`
17
+ )
18
+ );
19
+
20
+ let frameIndex = 0;
21
+ let lastFrameTime = 0;
22
+ let isPlaying = false;
23
+ let rafId = null;
24
+
25
+ // ---- Playback Loop ----
26
+
27
+ function playLoop(timestamp) {
28
+ if (!isPlaying) return;
29
+
30
+ // Exact 30fps timing using elapsed time
31
+ if (timestamp - lastFrameTime >= FRAME_INTERVAL) {
32
+ // No console.clear() — frames scroll through console history.
33
+ // This prevents the flashing that causes nausea.
34
+ console.log('%c ', SCALED_FRAMES[frameIndex]);
35
+
36
+ // Advance and loop
37
+ frameIndex = (frameIndex + 1) % TOTAL_FRAMES;
38
+ lastFrameTime = timestamp;
39
+ }
40
+
41
+ rafId = requestAnimationFrame(playLoop);
42
+ }
43
+
44
+ function startPlayback() {
45
+ if (isPlaying) return;
46
+ isPlaying = true;
47
+ lastFrameTime = performance.now();
48
+ rafId = requestAnimationFrame(playLoop);
49
+
50
+ // Update UI
51
+ const status = document.getElementById('status');
52
+ if (status) status.textContent = `Playing ${TOTAL_FRAMES} frames @ 30fps — scaled ${DISPLAY_WIDTH}x${DISPLAY_HEIGHT}`;
53
+
54
+ console.log('%c Bad Apple! Starting playback...', 'color: #888; font-size: 12px;');
55
+ }
56
+
57
+ // ---- DevTools Detection ----
58
+
59
+ function isDevToolsOpen() {
60
+ const threshold = 200;
61
+ const widthDiff = window.outerWidth - window.innerWidth;
62
+ const heightDiff = window.outerHeight - window.innerHeight;
63
+ return widthDiff > threshold || heightDiff > threshold;
64
+ }
65
+
66
+ // Check immediately on load
67
+ if (isDevToolsOpen()) {
68
+ console.log('DevTools detected on load. Starting playback...');
69
+ startPlayback();
70
+ }
71
+
72
+ // Poll for DevTools opening (dock mode)
73
+ const devtoolsInterval = setInterval(() => {
74
+ if (isDevToolsOpen() && !isPlaying) {
75
+ console.log('DevTools opened! Starting playback...');
76
+ startPlayback();
77
+ }
78
+ }, 500);
79
+
80
+ // Also detect via console API profiling trick
81
+ let checkCount = 0;
82
+ const checkDevToolsProfiling = () => {
83
+ const start = performance.now();
84
+ console.profile();
85
+ console.profileEnd();
86
+ if (performance.now() - start > 100) {
87
+ if (!isPlaying) startPlayback();
88
+ }
89
+ checkCount++;
90
+ if (checkCount < 20) setTimeout(checkDevToolsProfiling, 1000);
91
+ };
92
+ checkDevToolsProfiling();
93
+
94
+ // Playback starts strictly when DevTools is opened.
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "bad-apple-console",
3
+ "version": "1.0.0",
4
+ "description": "Play the Bad Apple! music video inside Chrome DevTools at 30fps with zero runtime overhead.",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "files": [
8
+ "index.js",
9
+ "frames.js",
10
+ "index.html",
11
+ "build.js"
12
+ ],
13
+ "scripts": {
14
+ "build": "node build.js"
15
+ },
16
+ "keywords": [
17
+ "bad-apple",
18
+ "devtools",
19
+ "console",
20
+ "ascii-art",
21
+ "video",
22
+ "chrome",
23
+ "easter-egg"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/samuelebertocco/bad-apple-console.git"
28
+ },
29
+ "author": "alienpingu",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "jimp": "^1.6.0"
33
+ }
34
+ }