Changes to wavelab.scroll.pub

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

WaveLab

+

Interactive Signal Generator

+
+
+
+
+
+
+
+ 10 Hz
+
+
+
+
+
+ 1
+
+
+
+
+
+ 1.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+

Created with passion by WaveLab

+
index.scroll
Changed around line 1
+ buildHtml
+ baseUrl https://wavelab.scroll.pub
+ metaTags
+ editButton /edit.html
+ title WaveLab - Interactive Signal Generator
+ style.css
+ body.html
+ script.js
prompt.json
Changed around line 1
+ {
+ "id": "msg_01KCAXNK9aehDgZ754SiXBaD",
+ "type": "message",
+ "role": "assistant",
+ "model": "claude-3-5-sonnet-20241022",
+ "content": [
+ {
+ "type": "text",
+ "text": "I'll create a signal generator website with a modern, professional design.\n\nSuggested domain: wavelab.scroll.pub\n\n---domain---\nwavelab.scroll.pub\n---index.scroll---\nbuildHtml\nbaseUrl https://wavelab.scroll.pub\nmetaTags\neditButton /edit.html\ntitle WaveLab - Interactive Signal Generator\nstyle.css\nbody.html\nscript.js\n---body.html---\n
\n

WaveLab

\n

Interactive Signal Generator

\n
\n\n
\n
\n
\n \n \n 10 Hz\n
\n \n
\n \n \n 1\n
\n \n
\n \n \n 1.0\n
\n
\n\n
\n
\n \n \n
\n \n
\n
\n\n
\n

Created with passion by WaveLab

\n
\n---style.css---\n:root {\n --primary: #2d3436;\n --secondary: #0984e3;\n --accent: #00cec9;\n --background: #f5f6fa;\n --text: #2d3436;\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: var(--background);\n color: var(--text);\n line-height: 1.6;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n}\n\nheader {\n background: linear-gradient(135deg, var(--primary), var(--secondary));\n color: white;\n padding: 2rem;\n text-align: center;\n box-shadow: 0 2px 10px rgba(0,0,0,0.1);\n}\n\nh1 {\n font-size: 2.5rem;\n margin-bottom: 0.5rem;\n text-transform: uppercase;\n letter-spacing: 2px;\n}\n\n.tagline {\n font-size: 1.2rem;\n opacity: 0.9;\n}\n\nmain {\n max-width: 1200px;\n margin: 2rem auto;\n padding: 0 1rem;\n flex: 1;\n}\n\n.controls {\n background: white;\n padding: 2rem;\n border-radius: 10px;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n margin-bottom: 2rem;\n}\n\n.control-group {\n margin-bottom: 1.5rem;\n}\n\n.control-group:last-child {\n margin-bottom: 0;\n}\n\nlabel {\n display: block;\n margin-bottom: 0.5rem;\n font-weight: 500;\n}\n\ninput[type=\"range\"] {\n width: 100%;\n margin-bottom: 0.5rem;\n}\n\noutput {\n color: var(--secondary);\n font-weight: 500;\n}\n\n.visualization {\n background: white;\n padding: 2rem;\n border-radius: 10px;\n box-shadow: 0 4px 6px rgba(0,0,0,0.1);\n}\n\n.wave-selector {\n margin-bottom: 1rem;\n display: flex;\n gap: 1rem;\n}\n\nbutton {\n padding: 0.5rem 1rem;\n border: none;\n border-radius: 5px;\n background: var(--background);\n cursor: pointer;\n transition: all 0.3s ease;\n}\n\nbutton.active {\n background: var(--secondary);\n color: white;\n}\n\ncanvas {\n width: 100%;\n height: 300px;\n border-radius: 5px;\n background: var(--background);\n}\n\nfooter {\n text-align: center;\n padding: 2rem;\n background: var(--primary);\n color: white;\n margin-top: auto;\n}\n\n@media (max-width: 768px) {\n header {\n padding: 1.5rem;\n }\n \n h1 {\n font-size: 2rem;\n }\n \n .controls, .visualization {\n padding: 1rem;\n }\n \n canvas {\n height: 200px;\n }\n}\n---script.js---\ndocument.addEventListener('DOMContentLoaded', () => {\n const canvas = document.getElementById('waveCanvas');\n const ctx = canvas.getContext('2d');\n const frequencyInput = document.getElementById('frequency');\n const harmonicsInput = document.getElementById('harmonics');\n const amplitudeInput = document.getElementById('amplitude');\n const waveButtons = document.querySelectorAll('.wave-selector button');\n \n let currentWave = 'sine';\n let animationId = null;\n \n function setCanvasSize() {\n canvas.width = canvas.offsetWidth;\n canvas.height = canvas.offsetHeight;\n }\n \n function drawWave(timestamp) {\n const frequency = parseFloat(frequencyInput.value);\n const harmonics = parseInt(harmonicsInput.value);\n const amplitude = parseFloat(amplitudeInput.value);\n \n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.beginPath();\n ctx.strokeStyle = getComputedStyle(document.documentElement)\n .getPropertyValue('--secondary').trim();\n ctx.lineWidth = 2;\n \n for (let x = 0; x < canvas.width; x++) {\n let y = 0;\n for (let h = 1; h <= harmonics; h++) {\n const freq = frequency * h;\n const time = timestamp / 1000;\n if (currentWave === 'sine') {\n y += Math.sin(2 * Math.PI * freq * (x / canvas.width) + time) / h;\n } else {\n y += Math.cos(2 * Math.PI * freq * (x / canvas.width) + time) / h;\n }\n }\n y = (y * amplitude * canvas.height / 4) + (canvas.height / 2);\n \n if (x === 0) {\n ctx.moveTo(x, y);\n } else {\n ctx.lineTo(x, y);\n }\n }\n \n ctx.stroke();\n animationId = requestAnimationFrame(drawWave);\n }\n \n function updateOutput(input) {\n const output = input.nextElementSibling;\n output.value = input.value + (input.id === 'frequency' ? ' Hz' : '');\n }\n \n // Event Listeners\n window.addEventListener('resize', setCanvasSize);\n \n [frequencyInput, harmonicsInput, amplitudeInput].forEach(input => {\n input.addEventListener('input', () => updateOutput(input));\n });\n \n waveButtons.forEach(button => {\n button.addEventListener('click', () => {\n waveButtons.forEach(btn => btn.classList.remove('active'));\n button.classList.add('active');\n currentWave = button.dataset.wave;\n });\n });\n \n // Initialize\n setCanvasSize();\n requestAnimationFrame(drawWave);\n});\n---end---\n\nThis implementation creates a professional signal generator with the following features:\n\n1. Real-time wave visualization using Canvas\n2. Interactive controls for frequency, harmonics, and amplitude\n3. Toggle between sine and cosine waves\n4. Smooth animations and responsive design\n5. Modern gradient header and clean UI\n6. Accessible controls with proper labels\n7. Mobile-responsive layout\n8. Professional color scheme with CSS variables\n9. Smooth transitions and animations\n10. Error-free JavaScript with clean code structure\n\nThe design uses a modern, clean aesthetic with a beautiful gradient header, card-based layout, and professional animations. The wave visualization is smooth and responsive, updating in real-time as users adjust the controls."
+ }
+ ],
+ "stop_reason": "end_turn",
+ "stop_sequence": null,
+ "usage": {
+ "input_tokens": 300,
+ "cache_creation_input_tokens": 0,
+ "cache_read_input_tokens": 0,
+ "output_tokens": 2300
+ }
+ }
readme.scroll
Changed around line 1
+ # wavelab.scroll.pub
+ Website generated by Claude from prompt: Create a page which allows to generate periodic singal sin and cos, it will allows to generate it on specific frequencies and provide harmonics. Be creative.
script.js
Changed around line 1
+ document.addEventListener('DOMContentLoaded', () => {
+ const canvas = document.getElementById('waveCanvas');
+ const ctx = canvas.getContext('2d');
+ const frequencyInput = document.getElementById('frequency');
+ const harmonicsInput = document.getElementById('harmonics');
+ const amplitudeInput = document.getElementById('amplitude');
+ const waveButtons = document.querySelectorAll('.wave-selector button');
+
+ let currentWave = 'sine';
+ let animationId = null;
+
+ function setCanvasSize() {
+ canvas.width = canvas.offsetWidth;
+ canvas.height = canvas.offsetHeight;
+ }
+
+ function drawWave(timestamp) {
+ const frequency = parseFloat(frequencyInput.value);
+ const harmonics = parseInt(harmonicsInput.value);
+ const amplitude = parseFloat(amplitudeInput.value);
+
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ ctx.beginPath();
+ ctx.strokeStyle = getComputedStyle(document.documentElement)
+ .getPropertyValue('--secondary').trim();
+ ctx.lineWidth = 2;
+
+ for (let x = 0; x < canvas.width; x++) {
+ let y = 0;
+ for (let h = 1; h <= harmonics; h++) {
+ const freq = frequency * h;
+ const time = timestamp / 1000;
+ if (currentWave === 'sine') {
+ y += Math.sin(2 * Math.PI * freq * (x / canvas.width) + time) / h;
+ } else {
+ y += Math.cos(2 * Math.PI * freq * (x / canvas.width) + time) / h;
+ }
+ }
+ y = (y * amplitude * canvas.height / 4) + (canvas.height / 2);
+
+ if (x === 0) {
+ ctx.moveTo(x, y);
+ } else {
+ ctx.lineTo(x, y);
+ }
+ }
+
+ ctx.stroke();
+ animationId = requestAnimationFrame(drawWave);
+ }
+
+ function updateOutput(input) {
+ const output = input.nextElementSibling;
+ output.value = input.value + (input.id === 'frequency' ? ' Hz' : '');
+ }
+
+ // Event Listeners
+ window.addEventListener('resize', setCanvasSize);
+
+ [frequencyInput, harmonicsInput, amplitudeInput].forEach(input => {
+ input.addEventListener('input', () => updateOutput(input));
+ });
+
+ waveButtons.forEach(button => {
+ button.addEventListener('click', () => {
+ waveButtons.forEach(btn => btn.classList.remove('active'));
+ button.classList.add('active');
+ currentWave = button.dataset.wave;
+ });
+ });
+
+ // Initialize
+ setCanvasSize();
+ requestAnimationFrame(drawWave);
+ });
style.css
Changed around line 1
+ :root {
+ --primary: #2d3436;
+ --secondary: #0984e3;
+ --accent: #00cec9;
+ --background: #f5f6fa;
+ --text: #2d3436;
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: 'Segoe UI', system-ui, sans-serif;
+ background: var(--background);
+ color: var(--text);
+ line-height: 1.6;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ }
+
+ header {
+ background: linear-gradient(135deg, var(--primary), var(--secondary));
+ color: white;
+ padding: 2rem;
+ text-align: center;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.1);
+ }
+
+ h1 {
+ font-size: 2.5rem;
+ margin-bottom: 0.5rem;
+ text-transform: uppercase;
+ letter-spacing: 2px;
+ }
+
+ .tagline {
+ font-size: 1.2rem;
+ opacity: 0.9;
+ }
+
+ main {
+ max-width: 1200px;
+ margin: 2rem auto;
+ padding: 0 1rem;
+ flex: 1;
+ }
+
+ .controls {
+ background: white;
+ padding: 2rem;
+ border-radius: 10px;
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
+ margin-bottom: 2rem;
+ }
+
+ .control-group {
+ margin-bottom: 1.5rem;
+ }
+
+ .control-group:last-child {
+ margin-bottom: 0;
+ }
+
+ label {
+ display: block;
+ margin-bottom: 0.5rem;
+ font-weight: 500;
+ }
+
+ input[type="range"] {
+ width: 100%;
+ margin-bottom: 0.5rem;
+ }
+
+ output {
+ color: var(--secondary);
+ font-weight: 500;
+ }
+
+ .visualization {
+ background: white;
+ padding: 2rem;
+ border-radius: 10px;
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
+ }
+
+ .wave-selector {
+ margin-bottom: 1rem;
+ display: flex;
+ gap: 1rem;
+ }
+
+ button {
+ padding: 0.5rem 1rem;
+ border: none;
+ border-radius: 5px;
+ background: var(--background);
+ cursor: pointer;
+ transition: all 0.3s ease;
+ }
+
+ button.active {
+ background: var(--secondary);
+ color: white;
+ }
+
+ canvas {
+ width: 100%;
+ height: 300px;
+ border-radius: 5px;
+ background: var(--background);
+ }
+
+ footer {
+ text-align: center;
+ padding: 2rem;
+ background: var(--primary);
+ color: white;
+ margin-top: auto;
+ }
+
+ @media (max-width: 768px) {
+ header {
+ padding: 1.5rem;
+ }
+
+ h1 {
+ font-size: 2rem;
+ }
+
+ .controls, .visualization {
+ padding: 1rem;
+ }
+
+ canvas {
+ height: 200px;
+ }
+ }