๐ค AI
This is a great idea for a satirical sketch! We can achieve this under 60 lines for the `sketch.js` file by being concise.
Here's the updated code for your project files, including a slightly condensed `sketch.js` to meet the line count requirement.
---
### `sketch.js` (27 lines)
```js
let p = 0, m = [ // Progress, messages array
'Reticulating splines...', 'Convincing electrons...', 'Bribing the CPU...',
'Asking nicely...', 'Threatening with magnets...', 'Consulting ancient scrolls...',
'Compiling a meme...', 'Checking for alien interference...', 'Reaching across the multiverse...',
'Just one more byte...', 'Calculating the meaning of life...', 'Waiting for inspiration...'
], cM = 0, mT = 0, mI = 2500; // Current message index, message timer, message interval
let cB; // cancelButton
function setup() {
createCanvas(windowWidth, windowHeight); textAlign(CENTER, CENTER); textSize(24); noStroke();
cB = createButton('Cancel'); cB.position(width/2-50, height/2+100); cB.size(100, 40);
cB.style('background-color','#f44').style('color','white').style('border','none').style('border-radius','5px').style('cursor','pointer');
cB.mousePressed(() => { cB.html('Nice try'); setTimeout(() => cB.html('Cancel'), 2000); });
}
function draw() {
background(50); // Dark gray
if (p < 87) p += 0.05; else { p += 0.001; if (frameCount%300===0) p = max(p-random(1,5), 80); } // Progress logic
let bW = width*0.6, bH = 40, bX = width/2-bW/2, bY = height/2-bH/2; // Bar dimensions
fill(80); rect(bX, bY, bW, bH, 5); // Outer bar
fill(255,0,100); rect(bX+2, bY+2, map(p,0,100,0,bW-4), bH-4, 3); // Inner progress bar
fill(255); textSize(16); text(floor(p)+'%', bX+bW/2, bY+bH/2); // Percentage text
if (millis()-mT > mI) { cM = (cM+1)%m.length; mT = millis(); } // Message timing
textSize(20); text(m[cM], width/2, height/2+60); // Excuse message
}
function windowResized() { resizeCanvas(windowWidth, windowHeight); cB.position(width/2-50, height/2+100); }
```
---
### `index.html`
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Satirical Loading Bar</title>
<link rel="stylesheet" href="style.css">
<!-- p5.js v1.11.3 - Core library -->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
</head>
<body>
<script src="sketch.js"></script>
</body>
</html>
```
---
### `style.css`
```css
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background-color: #323232; /* Match sketch background */
font-family: sans-serif; /* A clear, standard font */
color: white;
}
canvas {
display: block;
}
/* Style for the p5.js-created button */
button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, 50%); /* Center the button relative to its position */
padding: 10px 20px;
background-color: #ff4444;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 18px;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #dd3333;
}
```
---
**Explanation:**
1. **`sketch.js`**:
* **Variables:** We declare all necessary variables on single lines where possible (`p` for progress, `m` for messages, `cM` for current message index, `mT` for message timer, `mI` for message interval, `cB` for the cancel button).
* **`setup()`**:
* `createCanvas(windowWidth, windowHeight)`: Creates a canvas that fills the browser window.
* `textAlign(CENTER, CENTER)`, `textSize(24)`, `noStroke()`: Sets up text alignment, size, and disables outlines for shapes.
* **Cancel Button**: `createButton('Cancel')` creates an HTML button. We then position it below the progress bar, style it with red background and white text, and add a `mousePressed` callback.
* **Button Interaction**: When clicked, the button's text changes to "Nice try". A `setTimeout` is used to revert it back to "Cancel" after 2 seconds, emphasizing its futility.
* **`draw()`**:
* `background(50)`: Sets the background to a dark gray.
* **Progress Logic**:
* `if (p < 87) p += 0.05;`: The progress `p` increases slowly until it hits 87%.
* `else { p += 0.001; if (frameCount%300===0) p = max(p-random(1,5), 80); }`: Once past 87%, it slows down drastically (`0.001`). Every 300 frames (roughly 5 seconds at 60fps), it randomly jumps backward by 1-5%, but never below 80%, to create frustration.
* **Progress Bar Drawing**:
* `bW`, `bH`, `bX`, `bY`: Variables are defined for the bar's width, height, and position, centered on the canvas.
* `fill(80); rect(...)`: Draws the outer, darker gray rectangle for the bar's container.
* `fill(255,0,100); rect(...)`: Draws the inner, pinkish-red rectangle whose width is mapped to the `p` (progress) value.
* `fill(255); textSize(16); text(floor(p)+'%', ...) `: Displays the current percentage in white text.
* **Message Logic**:
* `if (millis()-mT > mI) { cM = (cM+1)%m.length; mT = millis(); }`: Checks if `messageInterval` (2500ms = 2.5 seconds) has passed since the last message change. If so, it updates `cM` to the next message in the `m` array (looping back to the beginning) and resets the timer.
* `textSize(20); text(m[cM], ...) `: Displays the current excuse message below the bar.
* **`windowResized()`**: Ensures the canvas and the button reposition correctly if the browser window is resized.
2. **`index.html`**:
* Includes the p5.js library from the CDN (version 1.11.3 as specified).
* Loads your `sketch.js` file.
* Sets a title for the browser tab.
3. **`style.css`**:
* Removes default browser margins and padding.
* Sets the `body` background to dark gray, matching the sketch.
* Ensures the canvas is a block element to prevent extra space below it.
* Provides basic styling for the p5.js-created button, centering it and giving it a distinct look.
This sketch should provide the humorous and frustrating user experience you envisioned!