Changes to bouncyball.scroll.pub

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

Click and drag the football, then release to bounce!

+
+
+
+
+

Made with passion for football fans

+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://bouncyball.scroll.pub
+ metaTags
+ title Interactive Bouncing Football
+ description Experience a realistic physics-based football simulation where you can grab and bounce a football using your mouse or touch
+ keywords football, physics, animation, interactive, game
+ editButton /edit.html
+ title Interactive Bouncing Football
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "id": "msg_016G1qnokdNZ2kpifW4Kcucn",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "Here's a fun, interactive football bouncing website:\n\n---domain---\nbouncyball.scroll.pub\n\n---index.scroll---\nbuildHtml\nbaseUrl https://bouncyball.scroll.pub\nmetaTags\n title Interactive Bouncing Football\n description Experience a realistic physics-based football simulation where you can grab and bounce a football using your mouse or touch\n keywords football, physics, animation, interactive, game\neditButton /edit.html\ntitle Interactive Bouncing Football\nstyle.css\nbody.html\nscript.js\n\n---body.html---\n
\n
\n
\n
\n
\n
\n
\n
\n

Click and drag the football, then release to bounce!

\n
\n
\n
\n
\n

Made with passion for football fans

\n
\n\n---style.css---\n:root {\n --ball-brown: #8B4513;\n --seam-color: #F5F5F5;\n --ground-color: #2E7D32;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n min-height: 100vh;\n background: linear-gradient(180deg, #87CEEB, #E0F7FA);\n overflow: hidden;\n font-family: system-ui, sans-serif;\n}\n\nmain {\n height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n position: relative;\n}\n\n.football-container {\n flex: 1;\n width: 100%;\n position: relative;\n}\n\n.football {\n width: 100px;\n height: 60px;\n background: var(--ball-brown);\n border-radius: 50%;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n cursor: grab;\n box-shadow: inset -10px -10px 15px rgba(0,0,0,0.3);\n transition: transform 0.2s;\n}\n\n.football:active {\n cursor: grabbing;\n}\n\n.seam {\n position: absolute;\n width: 100%;\n height: 4px;\n background: var(--seam-color);\n top: 50%;\n transform: translateY(-50%);\n}\n\n.rotate45 {\n transform: rotate(45deg);\n}\n\n.instructions {\n text-align: center;\n padding: 1rem;\n background: rgba(255,255,255,0.8);\n border-radius: 10px;\n margin: 1rem;\n z-index: 10;\n}\n\n.ground {\n width: 100%;\n height: 100px;\n background: var(--ground-color);\n position: absolute;\n bottom: 0;\n}\n\nfooter {\n position: absolute;\n bottom: 0;\n width: 100%;\n text-align: center;\n padding: 1rem;\n color: white;\n background: rgba(0,0,0,0.5);\n}\n\n@media (max-width: 768px) {\n .football {\n width: 80px;\n height: 48px;\n }\n \n .instructions {\n font-size: 0.9rem;\n }\n}\n\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const football = document.querySelector('.football');\n let isDragging = false;\n let currentX, currentY, initialX, initialY;\n let xOffset = 0;\n let yOffset = 0;\n let velocity = { x: 0, y: 0 };\n let lastPos = { x: 0, y: 0 };\n let animationId;\n\n const gravity = 0.5;\n const bounce = 0.7;\n const friction = 0.99;\n\n function dragStart(e) {\n if (e.type === \"touchstart\") {\n initialX = e.touches[0].clientX - xOffset;\n initialY = e.touches[0].clientY - yOffset;\n } else {\n initialX = e.clientX - xOffset;\n initialY = e.clientY - yOffset;\n }\n \n if (e.target === football) {\n isDragging = true;\n cancelAnimationFrame(animationId);\n }\n }\n\n function drag(e) {\n if (isDragging) {\n e.preventDefault();\n\n if (e.type === \"touchmove\") {\n currentX = e.touches[0].clientX - initialX;\n currentY = e.touches[0].clientY - initialY;\n } else {\n currentX = e.clientX - initialX;\n currentY = e.clientY - initialY;\n }\n\n xOffset = currentX;\n yOffset = currentY;\n\n velocity.x = currentX - lastPos.x;\n velocity.y = currentY - lastPos.y;\n \n lastPos.x = currentX;\n lastPos.y = currentY;\n\n setTranslate(currentX, currentY, football);\n }\n }\n\n function setTranslate(xPos, yPos, el) {\n el.style.transform = `translate(${xPos}px, ${yPos}px) rotate(${xPos * 0.2}deg)`;\n }\n\n function dragEnd() {\n if (isDragging) {\n isDragging = false;\n animate();\n }\n }\n\n function animate() {\n if (!isDragging) {\n velocity.y += gravity;\n velocity.x *= friction;\n \n xOffset += velocity.x;\n yOffset += velocity.y;\n\n const ground = window.innerHeight - 160;\n \n if (yOffset > ground) {\n yOffset = ground;\n velocity.y *= -bounce;\n }\n\n if (Math.abs(xOffset) > window.innerWidth/2) {\n velocity.x *= -1;\n xOffset = Math.sign(xOffset) * window.innerWidth/2;\n }\n\n setTranslate(xOffset, yOffset, football);\n \n if (Math.abs(velocity.y) > 0.1 || Math.abs(velocity.x) > 0.1) {\n animationId = requestAnimationFrame(animate);\n }\n }\n }\n\n football.addEventListener('mousedown', dragStart);\n football.addEventListener('touchstart', dragStart, { passive: false });\n document.addEventListener('mousemove', drag);\n document.addEventListener('touchmove', drag, { passive: false });\n document.addEventListener('mouseup', dragEnd);\n document.addEventListener('touchend', dragEnd);\n});\n\n---end---\n\nThis creates a fun interactive website where users can grab and bounce a realistic-looking football. The ball responds to physics with gravity, bounce, and friction effects. Key features:\n\n1. Realistic football design with seams and shading\n2. Physics-based bouncing animation\n3. Smooth drag and release mechanics\n4. Responsive design that works on both desktop and mobile\n5. Beautiful gradient sky background\n6. Grass ground effect\n7. Clear user instructions\n8. Smooth rotational effects while the ball moves\n9. Touch support for mobile devices\n10. Boundary detection to keep the ball on screen\n\nThe code uses requestAnimationFrame for smooth animations and includes touch event handling for mobile devices. The CSS creates a realistic football appearance with shadows and seams, while the JavaScript handles the physics simulation and user interactions."
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 292,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 1948
+ }
+ }
readme.scroll
Changed around line 1
+ # bouncyball.scroll.pub
+ Website generated by Claude from prompt: create a site that have a realistic football ball that can be hold with the mouse and when released it bounces
script.js
Changed around line 1
+ document.addEventListener('DOMContentLoaded', () => {
+ const football = document.querySelector('.football');
+ let isDragging = false;
+ let currentX, currentY, initialX, initialY;
+ let xOffset = 0;
+ let yOffset = 0;
+ let velocity = { x: 0, y: 0 };
+ let lastPos = { x: 0, y: 0 };
+ let animationId;
+
+ const gravity = 0.5;
+ const bounce = 0.7;
+ const friction = 0.99;
+
+ function dragStart(e) {
+ if (e.type === "touchstart") {
+ initialX = e.touches[0].clientX - xOffset;
+ initialY = e.touches[0].clientY - yOffset;
+ } else {
+ initialX = e.clientX - xOffset;
+ initialY = e.clientY - yOffset;
+ }
+
+ if (e.target === football) {
+ isDragging = true;
+ cancelAnimationFrame(animationId);
+ }
+ }
+
+ function drag(e) {
+ if (isDragging) {
+ e.preventDefault();
+
+ if (e.type === "touchmove") {
+ currentX = e.touches[0].clientX - initialX;
+ currentY = e.touches[0].clientY - initialY;
+ } else {
+ currentX = e.clientX - initialX;
+ currentY = e.clientY - initialY;
+ }
+
+ xOffset = currentX;
+ yOffset = currentY;
+
+ velocity.x = currentX - lastPos.x;
+ velocity.y = currentY - lastPos.y;
+
+ lastPos.x = currentX;
+ lastPos.y = currentY;
+
+ setTranslate(currentX, currentY, football);
+ }
+ }
+
+ function setTranslate(xPos, yPos, el) {
+ el.style.transform = `translate(${xPos}px, ${yPos}px) rotate(${xPos * 0.2}deg)`;
+ }
+
+ function dragEnd() {
+ if (isDragging) {
+ isDragging = false;
+ animate();
+ }
+ }
+
+ function animate() {
+ if (!isDragging) {
+ velocity.y += gravity;
+ velocity.x *= friction;
+
+ xOffset += velocity.x;
+ yOffset += velocity.y;
+
+ const ground = window.innerHeight - 160;
+
+ if (yOffset > ground) {
+ yOffset = ground;
+ velocity.y *= -bounce;
+ }
+
+ if (Math.abs(xOffset) > window.innerWidth/2) {
+ velocity.x *= -1;
+ xOffset = Math.sign(xOffset) * window.innerWidth/2;
+ }
+
+ setTranslate(xOffset, yOffset, football);
+
+ if (Math.abs(velocity.y) > 0.1 || Math.abs(velocity.x) > 0.1) {
+ animationId = requestAnimationFrame(animate);
+ }
+ }
+ }
+
+ football.addEventListener('mousedown', dragStart);
+ football.addEventListener('touchstart', dragStart, { passive: false });
+ document.addEventListener('mousemove', drag);
+ document.addEventListener('touchmove', drag, { passive: false });
+ document.addEventListener('mouseup', dragEnd);
+ document.addEventListener('touchend', dragEnd);
+ });
style.css
Changed around line 1
+ :root {
+ --ball-brown: #8B4513;
+ --seam-color: #F5F5F5;
+ --ground-color: #2E7D32;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ min-height: 100vh;
+ background: linear-gradient(180deg, #87CEEB, #E0F7FA);
+ overflow: hidden;
+ font-family: system-ui, sans-serif;
+ }
+
+ main {
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ position: relative;
+ }
+
+ .football-container {
+ flex: 1;
+ width: 100%;
+ position: relative;
+ }
+
+ .football {
+ width: 100px;
+ height: 60px;
+ background: var(--ball-brown);
+ border-radius: 50%;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%);
+ cursor: grab;
+ box-shadow: inset -10px -10px 15px rgba(0,0,0,0.3);
+ transition: transform 0.2s;
+ }
+
+ .football:active {
+ cursor: grabbing;
+ }
+
+ .seam {
+ position: absolute;
+ width: 100%;
+ height: 4px;
+ background: var(--seam-color);
+ top: 50%;
+ transform: translateY(-50%);
+ }
+
+ .rotate45 {
+ transform: rotate(45deg);
+ }
+
+ .instructions {
+ text-align: center;
+ padding: 1rem;
+ background: rgba(255,255,255,0.8);
+ border-radius: 10px;
+ margin: 1rem;
+ z-index: 10;
+ }
+
+ .ground {
+ width: 100%;
+ height: 100px;
+ background: var(--ground-color);
+ position: absolute;
+ bottom: 0;
+ }
+
+ footer {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ text-align: center;
+ padding: 1rem;
+ color: white;
+ background: rgba(0,0,0,0.5);
+ }
+
+ @media (max-width: 768px) {
+ .football {
+ width: 80px;
+ height: 48px;
+ }
+
+ .instructions {
+ font-size: 0.9rem;
+ }
+ }