Changes to particles3.scroll.pub

ffff:12.186.22.250
ffff:12.186.22.250
22 days ago
updated script.js
script.js
Changed around line 68: class ParticleSystem {
- this.colorMode = this.colorMode === "blue" ? "red" : "blue";
+ this.colorMode = this.colorMode === "blue" ? "rainbow" : "blue";
ffff:12.186.22.250
ffff:12.186.22.250
22 days ago
updated script.js
script.js
Changed around line 23: class Particle {
- this.canvas = document.getElementById('particleCanvas');
- this.ctx = this.canvas.getContext('2d');
+ this.canvas = document.getElementById("particleCanvas");
+ this.ctx = this.canvas.getContext("2d");
- this.colorMode = 'blue';
+ this.colorMode = "blue";
-
+
Changed around line 50: class ParticleSystem {
- window.addEventListener('resize', () => this.resize());
-
- document.getElementById('particleCount').addEventListener('input', (e) => {
+ window.addEventListener("resize", () => this.resize());
+
+ document.getElementById("particleCount").addEventListener("input", (e) => {
-
- document.getElementById('particleSpeed').addEventListener('input', (e) => {
+
+ document.getElementById("particleSpeed").addEventListener("input", (e) => {
-
- 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";
- if (this.colorMode === 'blue') {
- const alpha = 1 - (distance / this.connectionRadius);
+ if (this.colorMode === "blue") {
+ const alpha = 1 - distance / this.connectionRadius;
Changed around line 84: class ParticleSystem {
-
+
-
+
-
+
Changed around line 103: class ParticleSystem {
-
+
- this.ctx.fillStyle = '#ffffff';
+ this.ctx.fillStyle = "#ffffff";
- this.particles.forEach(p => p.update(this.speed));
+ this.particles.forEach((p) => p.update(this.speed));
- document.addEventListener('DOMContentLoaded', () => {
+ document.addEventListener("DOMContentLoaded", () => {
- });
+ });
ffff:12.186.22.250
ffff:12.186.22.250
22 days ago
updated body.html
body.html
Changed around line 1
-
+
-
+
-
+
-
+
-
+
-
+
-
+
+ type="range"
+ id="connectionRadius"
+ min="50"
+ max="200"
+ value="100"
+ />
-
+
-

Created with passion for interactive web experiences

-
+

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

Particle Symphony

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Created with passion for interactive web experiences

+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://particles.scroll.pub
+ metaTags
+ editButton /edit.html
+ title Interactive Particle Symphony
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "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
\n \n \n
\n

Particle Symphony

\n \n
\n \n \n
\n \n
\n \n \n
\n \n
\n \n \n
\n \n \n
\n
\n\n
\n

Created with passion for interactive web experiences

\n
\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
+ }
+ }
readme.scroll
Changed around line 1
+ # particles3.scroll.pub
+ Website generated by Claude from prompt: a particle website showing lots of particles with some cool controls and interactivity
script.js
Changed around line 1
+ 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();
+ });
style.css
Changed around line 1
+ :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;
+ }
+ }