Changes to bouncebox.scroll.pub

root
root
23 days ago
Initial commit
body.html
Changed around line 1
+
+

Bouncing Balls

+

An interactive physics simulation

+
+
+
+
+
+
+
+
+
+
+
+ Your browser does not support the canvas element.
+
+
+
+
+

Created with love for physics and animation

+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://bouncebox.scroll.pub
+ metaTags
+ editButton /edit.html
+ title Bouncing Balls Physics Demo
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "id": "msg_01MZYJygyrvoiRpAqR3gt1xR",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "I'll create a fun and interactive bouncing balls demo website.\n\n---domain---\nbouncebox.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://bouncebox.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Bouncing Balls Physics Demo\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n
\n

Bouncing Balls

\n

An interactive physics simulation

\n
\n\n
\n
\n \n \n \n \n
\n \n \n Your browser does not support the canvas element.\n \n
\n\n
\n

Created with love for physics and animation

\n
\n\n---style.css---\n:root {\n --primary-color: #2a2b2e;\n --accent-color: #4a90e2;\n --text-color: #ffffff;\n --shadow-color: rgba(0, 0, 0, 0.2);\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: 'Segoe UI', system-ui, sans-serif;\n background: linear-gradient(135deg, #1a1b1f 0%, #2a2b2e 100%);\n color: var(--text-color);\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n\nheader {\n text-align: center;\n padding: 2rem;\n background: rgba(255, 255, 255, 0.05);\n backdrop-filter: blur(10px);\n border-bottom: 1px solid rgba(255, 255, 255, 0.1);\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 0.5rem;\n background: linear-gradient(45deg, var(--accent-color), #6ab0ff);\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n text-shadow: 2px 2px 4px var(--shadow-color);\n}\n\n.controls {\n position: fixed;\n top: 1rem;\n right: 1rem;\n display: flex;\n gap: 1rem;\n padding: 1rem;\n background: rgba(255, 255, 255, 0.1);\n backdrop-filter: blur(5px);\n border-radius: 12px;\n z-index: 100;\n}\n\nbutton {\n padding: 0.5rem 1rem;\n border: none;\n border-radius: 6px;\n background: var(--accent-color);\n color: var(--text-color);\n cursor: pointer;\n transition: transform 0.2s, background 0.2s;\n}\n\nbutton:hover {\n transform: translateY(-2px);\n background: #5fa0f2;\n}\n\ninput[type=\"range\"] {\n width: 100px;\n accent-color: var(--accent-color);\n}\n\ncanvas {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 1;\n}\n\nfooter {\n position: fixed;\n bottom: 0;\n width: 100%;\n padding: 1rem;\n text-align: center;\n background: rgba(255, 255, 255, 0.05);\n backdrop-filter: blur(10px);\n z-index: 100;\n}\n\n@media (max-width: 768px) {\n .controls {\n flex-direction: column;\n right: 0.5rem;\n top: 0.5rem;\n }\n \n h1 {\n font-size: 2rem;\n }\n}\n\n---script.js---\nclass Ball {\n constructor(x, y) {\n this.x = x;\n this.y = y;\n this.vx = (Math.random() - 0.5) * 10;\n this.vy = (Math.random() - 0.5) * 10;\n this.radius = Math.random() * 20 + 10;\n this.color = `hsl(${Math.random() * 360}, 70%, 50%)`;\n }\n}\n\nclass BallSimulation {\n constructor() {\n this.canvas = document.getElementById('ballCanvas');\n this.ctx = this.canvas.getContext('2d');\n this.balls = [];\n this.gravity = 0.8;\n this.friction = 0.99;\n this.bounce = 0.8;\n \n this.resize();\n this.setupEventListeners();\n this.animate();\n }\n\n resize() {\n this.canvas.width = window.innerWidth;\n this.canvas.height = window.innerHeight;\n }\n\n setupEventListeners() {\n window.addEventListener('resize', () => this.resize());\n \n document.getElementById('addBall').addEventListener('click', () => {\n this.addBall(this.canvas.width / 2, this.canvas.height / 3);\n });\n \n document.getElementById('reset').addEventListener('click', () => {\n this.balls = [];\n });\n \n document.getElementById('gravity').addEventListener('input', (e) => {\n this.gravity = parseFloat(e.target.value);\n });\n \n this.canvas.addEventListener('click', (e) => {\n const rect = this.canvas.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n this.addBall(x, y);\n });\n }\n\n addBall(x, y) {\n this.balls.push(new Ball(x, y));\n }\n\n update() {\n this.balls.forEach(ball => {\n ball.vy += this.gravity;\n ball.x += ball.vx;\n ball.y += ball.vy;\n \n ball.vx *= this.friction;\n ball.vy *= this.friction;\n \n if (ball.x + ball.radius > this.canvas.width) {\n ball.x = this.canvas.width - ball.radius;\n ball.vx *= -this.bounce;\n }\n if (ball.x - ball.radius < 0) {\n ball.x = ball.radius;\n ball.vx *= -this.bounce;\n }\n if (ball.y + ball.radius > this.canvas.height) {\n ball.y = this.canvas.height - ball.radius;\n ball.vy *= -this.bounce;\n }\n if (ball.y - ball.radius < 0) {\n ball.y = ball.radius;\n ball.vy *= -this.bounce;\n }\n });\n }\n\n draw() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n \n this.balls.forEach(ball => {\n this.ctx.beginPath();\n this.ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);\n this.ctx.fillStyle = ball.color;\n this.ctx.fill();\n this.ctx.closePath();\n \n // Add shadow\n this.ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';\n this.ctx.shadowBlur = 10;\n this.ctx.shadowOffsetX = 5;\n this.ctx.shadowOffsetY = 5;\n });\n }\n\n animate() {\n this.update();\n this.draw();\n requestAnimationFrame(() => this.animate());\n }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n new BallSimulation();\n});\n\n---end---\n\nThis creates a beautiful, interactive bouncing balls physics simulation with the following features:\n\n1. Click anywhere on the canvas to add balls\n2. Use the \"Add Ball\" button to add balls at the center\n3. Adjust gravity with the slider\n4. Reset button to clear all balls\n5. Smooth animations with requestAnimationFrame\n6. Beautiful gradient background and glassmorphism UI\n7. Responsive design that works on all devices\n8. Accessible controls with ARIA labels\n9. Realistic physics with gravity, friction, and bounce effects\n10. Colorful balls with shadows and random properties\n\nThe website uses modern CSS features like CSS variables, backdrop-filter for glassmorphism effects, and smooth animations. The JavaScript is organized using classes for better code structure and maintainability."
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 278,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 2312
+ }
+ }
readme.scroll
Changed around line 1
+ # bouncebox.scroll.pub
+ Website generated by Claude from prompt: A website to demo the bouncing balls.
script.js
Changed around line 1
+ class Ball {
+ constructor(x, y) {
+ this.x = x;
+ this.y = y;
+ this.vx = (Math.random() - 0.5) * 10;
+ this.vy = (Math.random() - 0.5) * 10;
+ this.radius = Math.random() * 20 + 10;
+ this.color = `hsl(${Math.random() * 360}, 70%, 50%)`;
+ }
+ }
+
+ class BallSimulation {
+ constructor() {
+ this.canvas = document.getElementById('ballCanvas');
+ this.ctx = this.canvas.getContext('2d');
+ this.balls = [];
+ this.gravity = 0.8;
+ this.friction = 0.99;
+ this.bounce = 0.8;
+
+ this.resize();
+ this.setupEventListeners();
+ this.animate();
+ }
+
+ resize() {
+ this.canvas.width = window.innerWidth;
+ this.canvas.height = window.innerHeight;
+ }
+
+ setupEventListeners() {
+ window.addEventListener('resize', () => this.resize());
+
+ document.getElementById('addBall').addEventListener('click', () => {
+ this.addBall(this.canvas.width / 2, this.canvas.height / 3);
+ });
+
+ document.getElementById('reset').addEventListener('click', () => {
+ this.balls = [];
+ });
+
+ document.getElementById('gravity').addEventListener('input', (e) => {
+ this.gravity = parseFloat(e.target.value);
+ });
+
+ this.canvas.addEventListener('click', (e) => {
+ const rect = this.canvas.getBoundingClientRect();
+ const x = e.clientX - rect.left;
+ const y = e.clientY - rect.top;
+ this.addBall(x, y);
+ });
+ }
+
+ addBall(x, y) {
+ this.balls.push(new Ball(x, y));
+ }
+
+ update() {
+ this.balls.forEach(ball => {
+ ball.vy += this.gravity;
+ ball.x += ball.vx;
+ ball.y += ball.vy;
+
+ ball.vx *= this.friction;
+ ball.vy *= this.friction;
+
+ if (ball.x + ball.radius > this.canvas.width) {
+ ball.x = this.canvas.width - ball.radius;
+ ball.vx *= -this.bounce;
+ }
+ if (ball.x - ball.radius < 0) {
+ ball.x = ball.radius;
+ ball.vx *= -this.bounce;
+ }
+ if (ball.y + ball.radius > this.canvas.height) {
+ ball.y = this.canvas.height - ball.radius;
+ ball.vy *= -this.bounce;
+ }
+ if (ball.y - ball.radius < 0) {
+ ball.y = ball.radius;
+ ball.vy *= -this.bounce;
+ }
+ });
+ }
+
+ draw() {
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
+
+ this.balls.forEach(ball => {
+ this.ctx.beginPath();
+ this.ctx.arc(ball.x, ball.y, ball.radius, 0, Math.PI * 2);
+ this.ctx.fillStyle = ball.color;
+ this.ctx.fill();
+ this.ctx.closePath();
+
+ // Add shadow
+ this.ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
+ this.ctx.shadowBlur = 10;
+ this.ctx.shadowOffsetX = 5;
+ this.ctx.shadowOffsetY = 5;
+ });
+ }
+
+ animate() {
+ this.update();
+ this.draw();
+ requestAnimationFrame(() => this.animate());
+ }
+ }
+
+ document.addEventListener('DOMContentLoaded', () => {
+ new BallSimulation();
+ });
style.css
Changed around line 1
+ :root {
+ --primary-color: #2a2b2e;
+ --accent-color: #4a90e2;
+ --text-color: #ffffff;
+ --shadow-color: rgba(0, 0, 0, 0.2);
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: 'Segoe UI', system-ui, sans-serif;
+ background: linear-gradient(135deg, #1a1b1f 0%, #2a2b2e 100%);
+ color: var(--text-color);
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ overflow: hidden;
+ }
+
+ header {
+ text-align: center;
+ padding: 2rem;
+ background: rgba(255, 255, 255, 0.05);
+ backdrop-filter: blur(10px);
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
+ }
+
+ h1 {
+ font-size: 2.5rem;
+ margin-bottom: 0.5rem;
+ background: linear-gradient(45deg, var(--accent-color), #6ab0ff);
+ -webkit-background-clip: text;
+ background-clip: text;
+ color: transparent;
+ text-shadow: 2px 2px 4px var(--shadow-color);
+ }
+
+ .controls {
+ position: fixed;
+ top: 1rem;
+ right: 1rem;
+ display: flex;
+ gap: 1rem;
+ padding: 1rem;
+ background: rgba(255, 255, 255, 0.1);
+ backdrop-filter: blur(5px);
+ border-radius: 12px;
+ z-index: 100;
+ }
+
+ button {
+ padding: 0.5rem 1rem;
+ border: none;
+ border-radius: 6px;
+ background: var(--accent-color);
+ color: var(--text-color);
+ cursor: pointer;
+ transition: transform 0.2s, background 0.2s;
+ }
+
+ button:hover {
+ transform: translateY(-2px);
+ background: #5fa0f2;
+ }
+
+ input[type="range"] {
+ width: 100px;
+ accent-color: var(--accent-color);
+ }
+
+ canvas {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ z-index: 1;
+ }
+
+ footer {
+ position: fixed;
+ bottom: 0;
+ width: 100%;
+ padding: 1rem;
+ text-align: center;
+ background: rgba(255, 255, 255, 0.05);
+ backdrop-filter: blur(10px);
+ z-index: 100;
+ }
+
+ @media (max-width: 768px) {
+ .controls {
+ flex-direction: column;
+ right: 0.5rem;
+ top: 0.5rem;
+ }
+
+ h1 {
+ font-size: 2rem;
+ }
+ }