commit 393716e918c77bc3926db226eca7a393cba38084
Author: ffff:12.186.22.250 <ffff:12.186.22.250@hub.scroll.pub> Date: 2024-12-31 01:10:51 +0000 Subject: updated script.js diff --git a/script.js b/script.js index 4d87736..b40071c 100644 --- a/script.js +++ b/script.js @@ -68,7 +68,7 @@ class ParticleSystem { }); document.getElementById("colorToggle").addEventListener("click", () => { - this.colorMode = this.colorMode === "blue" ? "red" : "blue"; + this.colorMode = this.colorMode === "blue" ? "rainbow" : "blue"; }); }
commit 342fcfd262f9083f7096233e71d512f27b872b52
Author: ffff:12.186.22.250 <ffff:12.186.22.250@hub.scroll.pub> Date: 2024-12-31 01:10:41 +0000 Subject: updated script.js diff --git a/script.js b/script.js index f6ad1d5..4d87736 100644 --- a/script.js +++ b/script.js @@ -23,14 +23,14 @@ class Particle { class ParticleSystem { constructor() { - this.canvas = document.getElementById('particleCanvas'); - this.ctx = this.canvas.getContext('2d'); + this.canvas = document.getElementById("particleCanvas"); + this.ctx = this.canvas.getContext("2d"); this.particles = []; - this.colorMode = 'blue'; + this.colorMode = "blue"; this.particleCount = 200; this.speed = 5; this.connectionRadius = 100; - + this.resize(); this.init(); this.setupEventListeners(); @@ -50,29 +50,31 @@ class ParticleSystem { } setupEventListeners() { - window.addEventListener('resize', () => this.resize()); - - document.getElementById('particleCount').addEventListener('input', (e) => { + window.addEventListener("resize", () => this.resize()); + + document.getElementById("particleCount").addEventListener("input", (e) => { this.particleCount = parseInt(e.target.value); this.init(); }); - - document.getElementById('particleSpeed').addEventListener('input', (e) => { + + document.getElementById("particleSpeed").addEventListener("input", (e) => { this.speed = parseInt(e.target.value); }); - - document.getElementById('connectionRadius').addEventListener('input', (e) => { - this.connectionRadius = parseInt(e.target.value); - }); - - document.getElementById('colorToggle').addEventListener('click', () => { - this.colorMode = this.colorMode === 'blue' ? 'rainbow' : 'blue'; + + document + .getElementById("connectionRadius") + .addEventListener("input", (e) => { + this.connectionRadius = parseInt(e.target.value); + }); + + document.getElementById("colorToggle").addEventListener("click", () => { + this.colorMode = this.colorMode === "blue" ? "red" : "blue"; }); } getColor(distance) { - if (this.colorMode === 'blue') { - const alpha = 1 - (distance / this.connectionRadius); + if (this.colorMode === "blue") { + const alpha = 1 - distance / this.connectionRadius; return `rgba(0, 159, 253, ${alpha})`; } else { const hue = (distance / this.connectionRadius) * 360; @@ -82,16 +84,16 @@ class ParticleSystem { draw() { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); - + for (let i = 0; i < this.particles.length; i++) { const p1 = this.particles[i]; - + for (let j = i + 1; j < this.particles.length; j++) { const p2 = this.particles[j]; const dx = p1.x - p2.x; const dy = p1.y - p2.y; const distance = Math.sqrt(dx * dx + dy * dy); - + if (distance < this.connectionRadius) { this.ctx.beginPath(); this.ctx.strokeStyle = this.getColor(distance); @@ -101,21 +103,21 @@ class ParticleSystem { this.ctx.stroke(); } } - + this.ctx.beginPath(); - this.ctx.fillStyle = '#ffffff'; + this.ctx.fillStyle = "#ffffff"; this.ctx.arc(p1.x, p1.y, p1.radius, 0, Math.PI * 2); this.ctx.fill(); } } animate() { - this.particles.forEach(p => p.update(this.speed)); + this.particles.forEach((p) => p.update(this.speed)); this.draw(); requestAnimationFrame(() => this.animate()); } } -document.addEventListener('DOMContentLoaded', () => { +document.addEventListener("DOMContentLoaded", () => { new ParticleSystem(); -}); \ No newline at end of file +});
commit cab0fa0d236bdebfcb43f26856eac2a90ffa9b77
Author: ffff:12.186.22.250 <ffff:12.186.22.250@hub.scroll.pub> Date: 2024-12-31 01:10:13 +0000 Subject: updated body.html diff --git a/body.html b/body.html index c9d2808..990abdb 100644 --- a/body.html +++ b/body.html @@ -1,28 +1,34 @@ <main> <canvas id="particleCanvas"></canvas> - + <div class="controls"> <h1>Particle Symphony</h1> - + <div class="control-group"> <label for="particleCount">Particle Count</label> - <input type="range" id="particleCount" min="50" max="500" value="200"> + <input type="range" id="particleCount" min="50" max="500" value="200" /> </div> - + <div class="control-group"> <label for="particleSpeed">Speed</label> - <input type="range" id="particleSpeed" min="1" max="10" value="5"> + <input type="range" id="particleSpeed" min="1" max="10" value="5" /> </div> - + <div class="control-group"> <label for="connectionRadius">Connection Radius</label> - <input type="range" id="connectionRadius" min="50" max="200" value="100"> + <input + type="range" + id="connectionRadius" + min="50" + max="200" + value="100" + /> </div> - + <button id="colorToggle">Toggle Colors</button> </div> </main> <footer> - <p>Created with passion for interactive web experiences</p> -</footer> \ No newline at end of file + <p></p> +</footer>
commit fe1a88d623b4369e6a2330456351a0fd4f15d60c
Author: root <root@hub.scroll.pub> Date: 2024-12-31 01:09:21 +0000 Subject: Initial commit diff --git a/body.html b/body.html new file mode 100644 index 0000000..c9d2808 --- /dev/null +++ b/body.html @@ -0,0 +1,28 @@ +<main> + <canvas id="particleCanvas"></canvas> + + <div class="controls"> + <h1>Particle Symphony</h1> + + <div class="control-group"> + <label for="particleCount">Particle Count</label> + <input type="range" id="particleCount" min="50" max="500" value="200"> + </div> + + <div class="control-group"> + <label for="particleSpeed">Speed</label> + <input type="range" id="particleSpeed" min="1" max="10" value="5"> + </div> + + <div class="control-group"> + <label for="connectionRadius">Connection Radius</label> + <input type="range" id="connectionRadius" min="50" max="200" value="100"> + </div> + + <button id="colorToggle">Toggle Colors</button> + </div> +</main> + +<footer> + <p>Created with passion for interactive web experiences</p> +</footer> \ No newline at end of file diff --git a/index.scroll b/index.scroll new file mode 100644 index 0000000..f487a37 --- /dev/null +++ b/index.scroll @@ -0,0 +1,8 @@ +buildHtml +baseUrl https://particles.scroll.pub +metaTags +editButton /edit.html +title Interactive Particle Symphony +style.css +body.html +script.js \ No newline at end of file diff --git a/prompt.json b/prompt.json new file mode 100644 index 0000000..09446d1 --- /dev/null +++ b/prompt.json @@ -0,0 +1,20 @@ +{ + "id": "msg_01Uny8dhmaP52HcMtxpp4hUc", + "type": "message", + "role": "assistant", + "model": "claude-3-5-sonnet-20241022", + "content": [ + { + "type": "text", + "text": "Let me create an interactive particle website with an elegant design.\n\n---domain---\nparticles.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://particles.scroll.pub\nmetaTags\neditButton /edit.html\ntitle Interactive Particle Symphony\nstyle.css\nbody.html\nscript.js\n---body.html---\n<main>\n <canvas id=\"particleCanvas\"></canvas>\n \n <div class=\"controls\">\n <h1>Particle Symphony</h1>\n \n <div class=\"control-group\">\n <label for=\"particleCount\">Particle Count</label>\n <input type=\"range\" id=\"particleCount\" min=\"50\" max=\"500\" value=\"200\">\n </div>\n \n <div class=\"control-group\">\n <label for=\"particleSpeed\">Speed</label>\n <input type=\"range\" id=\"particleSpeed\" min=\"1\" max=\"10\" value=\"5\">\n </div>\n \n <div class=\"control-group\">\n <label for=\"connectionRadius\">Connection Radius</label>\n <input type=\"range\" id=\"connectionRadius\" min=\"50\" max=\"200\" value=\"100\">\n </div>\n \n <button id=\"colorToggle\">Toggle Colors</button>\n </div>\n</main>\n\n<footer>\n <p>Created with passion for interactive web experiences</p>\n</footer>\n---style.css---\n:root {\n --primary-color: #2a2a72;\n --secondary-color: #009ffd;\n --text-color: #ffffff;\n --control-bg: rgba(0, 0, 0, 0.7);\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nbody {\n font-family: system-ui, -apple-system, sans-serif;\n background: var(--primary-color);\n color: var(--text-color);\n overflow: hidden;\n height: 100vh;\n}\n\ncanvas {\n position: fixed;\n top: 0;\n left: 0;\n z-index: 1;\n}\n\n.controls {\n position: fixed;\n right: 2rem;\n top: 50%;\n transform: translateY(-50%);\n background: var(--control-bg);\n padding: 2rem;\n border-radius: 1rem;\n z-index: 2;\n backdrop-filter: blur(10px);\n box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);\n}\n\nh1 {\n font-size: 1.5rem;\n margin-bottom: 1.5rem;\n text-align: center;\n background: linear-gradient(45deg, var(--text-color), var(--secondary-color));\n -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n}\n\n.control-group {\n margin-bottom: 1.5rem;\n}\n\nlabel {\n display: block;\n margin-bottom: 0.5rem;\n font-size: 0.9rem;\n}\n\ninput[type=\"range\"] {\n width: 100%;\n background: var(--secondary-color);\n height: 6px;\n border-radius: 3px;\n appearance: none;\n outline: none;\n}\n\ninput[type=\"range\"]::-webkit-slider-thumb {\n appearance: none;\n width: 16px;\n height: 16px;\n background: var(--text-color);\n border-radius: 50%;\n cursor: pointer;\n transition: transform 0.2s;\n}\n\ninput[type=\"range\"]::-webkit-slider-thumb:hover {\n transform: scale(1.2);\n}\n\nbutton {\n width: 100%;\n padding: 0.8rem;\n background: var(--secondary-color);\n border: none;\n border-radius: 0.5rem;\n color: var(--text-color);\n font-weight: bold;\n cursor: pointer;\n transition: transform 0.2s, background 0.2s;\n}\n\nbutton:hover {\n transform: scale(1.05);\n background: #00b4ff;\n}\n\nfooter {\n position: fixed;\n bottom: 1rem;\n left: 0;\n width: 100%;\n text-align: center;\n z-index: 2;\n font-size: 0.9rem;\n opacity: 0.7;\n}\n\n@media (max-width: 768px) {\n .controls {\n right: 50%;\n transform: translateX(50%);\n bottom: 2rem;\n top: auto;\n width: 90%;\n max-width: 400px;\n }\n \n footer {\n display: none;\n }\n}\n---script.js---\nclass Particle {\n constructor(canvas) {\n this.canvas = canvas;\n this.reset();\n }\n\n reset() {\n this.x = Math.random() * this.canvas.width;\n this.y = Math.random() * this.canvas.height;\n this.vx = (Math.random() - 0.5) * 2;\n this.vy = (Math.random() - 0.5) * 2;\n this.radius = Math.random() * 2 + 1;\n }\n\n update(speed) {\n this.x += this.vx * speed;\n this.y += this.vy * speed;\n\n if (this.x < 0 || this.x > this.canvas.width) this.vx *= -1;\n if (this.y < 0 || this.y > this.canvas.height) this.vy *= -1;\n }\n}\n\nclass ParticleSystem {\n constructor() {\n this.canvas = document.getElementById('particleCanvas');\n this.ctx = this.canvas.getContext('2d');\n this.particles = [];\n this.colorMode = 'blue';\n this.particleCount = 200;\n this.speed = 5;\n this.connectionRadius = 100;\n \n this.resize();\n this.init();\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 init() {\n this.particles = [];\n for (let i = 0; i < this.particleCount; i++) {\n this.particles.push(new Particle(this.canvas));\n }\n }\n\n setupEventListeners() {\n window.addEventListener('resize', () => this.resize());\n \n document.getElementById('particleCount').addEventListener('input', (e) => {\n this.particleCount = parseInt(e.target.value);\n this.init();\n });\n \n document.getElementById('particleSpeed').addEventListener('input', (e) => {\n this.speed = parseInt(e.target.value);\n });\n \n document.getElementById('connectionRadius').addEventListener('input', (e) => {\n this.connectionRadius = parseInt(e.target.value);\n });\n \n document.getElementById('colorToggle').addEventListener('click', () => {\n this.colorMode = this.colorMode === 'blue' ? 'rainbow' : 'blue';\n });\n }\n\n getColor(distance) {\n if (this.colorMode === 'blue') {\n const alpha = 1 - (distance / this.connectionRadius);\n return `rgba(0, 159, 253, ${alpha})`;\n } else {\n const hue = (distance / this.connectionRadius) * 360;\n return `hsla(${hue}, 100%, 50%, ${1 - distance / this.connectionRadius})`;\n }\n }\n\n draw() {\n this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);\n \n for (let i = 0; i < this.particles.length; i++) {\n const p1 = this.particles[i];\n \n for (let j = i + 1; j < this.particles.length; j++) {\n const p2 = this.particles[j];\n const dx = p1.x - p2.x;\n const dy = p1.y - p2.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n \n if (distance < this.connectionRadius) {\n this.ctx.beginPath();\n this.ctx.strokeStyle = this.getColor(distance);\n this.ctx.lineWidth = 1;\n this.ctx.moveTo(p1.x, p1.y);\n this.ctx.lineTo(p2.x, p2.y);\n this.ctx.stroke();\n }\n }\n \n this.ctx.beginPath();\n this.ctx.fillStyle = '#ffffff';\n this.ctx.arc(p1.x, p1.y, p1.radius, 0, Math.PI * 2);\n this.ctx.fill();\n }\n }\n\n animate() {\n this.particles.forEach(p => p.update(this.speed));\n this.draw();\n requestAnimationFrame(() => this.animate());\n }\n}\n\ndocument.addEventListener('DOMContentLoaded', () => {\n new ParticleSystem();\n});\n---end---\n\nThis creates a beautiful, interactive particle system with the following features:\n\n1. Responsive canvas that fills the entire screen\n2. Elegant control panel with blur effect\n3. Adjustable parameters:\n - Particle count\n - Movement speed\n - Connection radius\n - Color mode toggle\n4. Smooth animations and transitions\n5. Mobile-responsive design\n6. Optimized performance\n7. Clean, modern aesthetic\n\nThe particles move naturally and create connections when they're close to each other. The connection lines' opacity changes based on distance, creating a dynamic, organic feel. The color toggle switches between a cool blue theme and a rainbow effect." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 285, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "output_tokens": 2531 + } +} \ No newline at end of file diff --git a/readme.scroll b/readme.scroll new file mode 100644 index 0000000..5deea8e --- /dev/null +++ b/readme.scroll @@ -0,0 +1,2 @@ +# particles3.scroll.pub +Website generated by Claude from prompt: a particle website showing lots of particles with some cool controls and interactivity \ No newline at end of file diff --git a/script.js b/script.js new file mode 100644 index 0000000..f6ad1d5 --- /dev/null +++ b/script.js @@ -0,0 +1,121 @@ +class Particle { + constructor(canvas) { + this.canvas = canvas; + this.reset(); + } + + reset() { + this.x = Math.random() * this.canvas.width; + this.y = Math.random() * this.canvas.height; + this.vx = (Math.random() - 0.5) * 2; + this.vy = (Math.random() - 0.5) * 2; + this.radius = Math.random() * 2 + 1; + } + + update(speed) { + this.x += this.vx * speed; + this.y += this.vy * speed; + + if (this.x < 0 || this.x > this.canvas.width) this.vx *= -1; + if (this.y < 0 || this.y > this.canvas.height) this.vy *= -1; + } +} + +class ParticleSystem { + constructor() { + this.canvas = document.getElementById('particleCanvas'); + this.ctx = this.canvas.getContext('2d'); + this.particles = []; + this.colorMode = 'blue'; + this.particleCount = 200; + this.speed = 5; + this.connectionRadius = 100; + + this.resize(); + this.init(); + this.setupEventListeners(); + this.animate(); + } + + resize() { + this.canvas.width = window.innerWidth; + this.canvas.height = window.innerHeight; + } + + init() { + this.particles = []; + for (let i = 0; i < this.particleCount; i++) { + this.particles.push(new Particle(this.canvas)); + } + } + + setupEventListeners() { + window.addEventListener('resize', () => this.resize()); + + document.getElementById('particleCount').addEventListener('input', (e) => { + this.particleCount = parseInt(e.target.value); + this.init(); + }); + + document.getElementById('particleSpeed').addEventListener('input', (e) => { + this.speed = parseInt(e.target.value); + }); + + document.getElementById('connectionRadius').addEventListener('input', (e) => { + this.connectionRadius = parseInt(e.target.value); + }); + + document.getElementById('colorToggle').addEventListener('click', () => { + this.colorMode = this.colorMode === 'blue' ? 'rainbow' : 'blue'; + }); + } + + getColor(distance) { + if (this.colorMode === 'blue') { + const alpha = 1 - (distance / this.connectionRadius); + return `rgba(0, 159, 253, ${alpha})`; + } else { + const hue = (distance / this.connectionRadius) * 360; + return `hsla(${hue}, 100%, 50%, ${1 - distance / this.connectionRadius})`; + } + } + + draw() { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + + for (let i = 0; i < this.particles.length; i++) { + const p1 = this.particles[i]; + + for (let j = i + 1; j < this.particles.length; j++) { + const p2 = this.particles[j]; + const dx = p1.x - p2.x; + const dy = p1.y - p2.y; + const distance = Math.sqrt(dx * dx + dy * dy); + + if (distance < this.connectionRadius) { + this.ctx.beginPath(); + this.ctx.strokeStyle = this.getColor(distance); + this.ctx.lineWidth = 1; + this.ctx.moveTo(p1.x, p1.y); + this.ctx.lineTo(p2.x, p2.y); + this.ctx.stroke(); + } + } + + this.ctx.beginPath(); + this.ctx.fillStyle = '#ffffff'; + this.ctx.arc(p1.x, p1.y, p1.radius, 0, Math.PI * 2); + this.ctx.fill(); + } + } + + animate() { + this.particles.forEach(p => p.update(this.speed)); + this.draw(); + requestAnimationFrame(() => this.animate()); + } +} + +document.addEventListener('DOMContentLoaded', () => { + new ParticleSystem(); +}); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..6ca5299 --- /dev/null +++ b/style.css @@ -0,0 +1,126 @@ +:root { + --primary-color: #2a2a72; + --secondary-color: #009ffd; + --text-color: #ffffff; + --control-bg: rgba(0, 0, 0, 0.7); +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +body { + font-family: system-ui, -apple-system, sans-serif; + background: var(--primary-color); + color: var(--text-color); + overflow: hidden; + height: 100vh; +} + +canvas { + position: fixed; + top: 0; + left: 0; + z-index: 1; +} + +.controls { + position: fixed; + right: 2rem; + top: 50%; + transform: translateY(-50%); + background: var(--control-bg); + padding: 2rem; + border-radius: 1rem; + z-index: 2; + backdrop-filter: blur(10px); + box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); +} + +h1 { + font-size: 1.5rem; + margin-bottom: 1.5rem; + text-align: center; + background: linear-gradient(45deg, var(--text-color), var(--secondary-color)); + -webkit-background-clip: text; + background-clip: text; + color: transparent; +} + +.control-group { + margin-bottom: 1.5rem; +} + +label { + display: block; + margin-bottom: 0.5rem; + font-size: 0.9rem; +} + +input[type="range"] { + width: 100%; + background: var(--secondary-color); + height: 6px; + border-radius: 3px; + appearance: none; + outline: none; +} + +input[type="range"]::-webkit-slider-thumb { + appearance: none; + width: 16px; + height: 16px; + background: var(--text-color); + border-radius: 50%; + cursor: pointer; + transition: transform 0.2s; +} + +input[type="range"]::-webkit-slider-thumb:hover { + transform: scale(1.2); +} + +button { + width: 100%; + padding: 0.8rem; + background: var(--secondary-color); + border: none; + border-radius: 0.5rem; + color: var(--text-color); + font-weight: bold; + cursor: pointer; + transition: transform 0.2s, background 0.2s; +} + +button:hover { + transform: scale(1.05); + background: #00b4ff; +} + +footer { + position: fixed; + bottom: 1rem; + left: 0; + width: 100%; + text-align: center; + z-index: 2; + font-size: 0.9rem; + opacity: 0.7; +} + +@media (max-width: 768px) { + .controls { + right: 50%; + transform: translateX(50%); + bottom: 2rem; + top: auto; + width: 90%; + max-width: 400px; + } + + footer { + display: none; + } +} \ No newline at end of file