From db988ed4cffd2b12a173ccfa0efda09fd82e0acc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 08:51:43 +0000 Subject: [PATCH 1/4] Initial plan From 14bacaa431281db5cdcfed8ed4179e528a125a3f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 09:01:14 +0000 Subject: [PATCH 2/4] Add share button with URL query parameter support Co-authored-by: ilesinge <501674+ilesinge@users.noreply.github.com> --- sketch.js | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 155 insertions(+), 2 deletions(-) diff --git a/sketch.js b/sketch.js index c93e672..509ac4e 100644 --- a/sketch.js +++ b/sketch.js @@ -28,7 +28,7 @@ let fontSelect let paletteSelect let audioNameLabel let playButton, fontUploadTrigger, audioUploadTrigger -let helpButton, infoBox, toggleButton +let helpButton, infoBox, toggleButton, shareButton let colorPalettes = { 'RGB': [[255, 0, 0], [0, 255, 0], [0, 0, 255]], // #FF0000 #00FF00 #0000FF 'Monochrome': [[255, 255, 255], [150, 150, 150], [75, 75, 75]], // #FFFFFF #969696 #4B4B4B @@ -92,6 +92,12 @@ function setup() { toggleButton.addClass('ui-toggle'); toggleButton.mousePressed(() => toggleUI(toggleButton)); + // Add share button in top right + shareButton = createButton('⎘'); + shareButton.position(windowWidth - 60, 10); + shareButton.addClass('ui-help'); + shareButton.mousePressed(copyPresetToClipboard); + // Add help button in top right helpButton = createButton('?'); helpButton.position(windowWidth - 30, 10); @@ -365,6 +371,9 @@ function setup() { genType() + // Load parameters from URL if present + loadParametersFromURL(); + // Check for saved audio and font loadSavedAudio(); loadSavedFont(); @@ -837,7 +846,8 @@ function mouseWheel(event) { function windowResized() { resizeCanvas(windowWidth, windowHeight); genType(); // Regenerate text points for new canvas size - // Reposition help button and info box + // Reposition share button, help button and info box + if (shareButton) shareButton.position(windowWidth - 60, 10); if (helpButton) helpButton.position(windowWidth - 30, 10); if (infoBox) infoBox.position(windowWidth - 290, 45); } @@ -1037,4 +1047,147 @@ async function loadSavedFont() { genType(); }); } +} + +// Copy preset as URL to clipboard +function copyPresetToClipboard() { + let params = new URLSearchParams(); + + // Add all slider values + for (let name in sliders) { + params.set(name, sliders[name].value()); + } + + // Add checkbox values + params.set('audioReactiveStroke', audioReactiveStrokeCheckbox.checked()); + params.set('audioReactiveSize', audioReactiveSizeCheckbox.checked()); + params.set('colorWaveOffset', colorWaveOffsetCheckbox.checked()); + params.set('filledCircles', filledCirclesCheckbox.checked()); + params.set('transparentBg', transparentBgCheckbox.checked()); + + // Add palette selection + params.set('palette', paletteSelect.value()); + + // Add font selection (only if it's a built-in font) + let selectedFont = fontSelect.value(); + if (builtInFonts[selectedFont]) { + params.set('font', selectedFont); + } + + // Add text content + params.set('text', currentText); + + // Add pan and zoom values + params.set('panX', panX.toFixed(2)); + params.set('panY', panY.toFixed(2)); + params.set('zoom', zoomLevel.toFixed(2)); + + // Create the URL with query parameters + let url = window.location.origin + window.location.pathname + '?' + params.toString(); + + // Copy to clipboard + navigator.clipboard.writeText(url).then(() => { + // Visual feedback - change button temporarily + let originalText = shareButton.html(); + shareButton.html('✓'); + setTimeout(() => { + shareButton.html(originalText); + }, 2000); + }).catch(err => { + console.error('Failed to copy to clipboard:', err); + alert('Failed to copy to clipboard. Please copy manually:\n' + url); + }); +} + +// Load parameters from URL query string +function loadParametersFromURL() { + let params = new URLSearchParams(window.location.search); + + if (params.toString() === '') { + return; // No URL parameters + } + + // Load slider values + for (let name in sliders) { + if (params.has(name)) { + let value = parseFloat(params.get(name)); + sliders[name].value(value); + saveSliderValue(name + 'slider', value); + } + } + + // Load checkbox values + if (params.has('audioReactiveStroke')) { + let value = params.get('audioReactiveStroke') === 'true'; + audioReactiveStrokeCheckbox.checked(value); + storeItem('audioReactiveStroke', value.toString()); + } + if (params.has('audioReactiveSize')) { + let value = params.get('audioReactiveSize') === 'true'; + audioReactiveSizeCheckbox.checked(value); + storeItem('audioReactiveSize', value.toString()); + } + if (params.has('colorWaveOffset')) { + let value = params.get('colorWaveOffset') === 'true'; + colorWaveOffsetCheckbox.checked(value); + storeItem('colorWaveOffset', value.toString()); + } + if (params.has('filledCircles')) { + let value = params.get('filledCircles') === 'true'; + filledCirclesCheckbox.checked(value); + storeItem('filledCircles', value.toString()); + } + if (params.has('transparentBg')) { + let value = params.get('transparentBg') === 'true'; + transparentBgCheckbox.checked(value); + storeItem('transparentBg', value.toString()); + updateUIColors(); + } + + // Load palette selection + if (params.has('palette')) { + let palette = params.get('palette'); + if (colorPalettes[palette]) { + paletteSelect.selected(palette); + storeItem('selectedPalette', palette); + } + } + + // Load font selection (only built-in fonts) + if (params.has('font')) { + let fontName = params.get('font'); + if (builtInFonts[fontName]) { + fontSelect.selected(fontName); + font = fonts[fontName]; + storeItem('selectedFont', fontName); + } + } + + // Load text content + if (params.has('text')) { + let text = params.get('text'); + textInput.value(text); + currentText = text; + storeItem('textContent', text); + } + + // Load pan and zoom values + if (params.has('panX')) { + panX = parseFloat(params.get('panX')); + storeItem('panX', panX); + } + if (params.has('panY')) { + panY = parseFloat(params.get('panY')); + storeItem('panY', panY); + } + if (params.has('zoom')) { + zoomLevel = parseFloat(params.get('zoom')); + storeItem('zoomLevel', zoomLevel); + } + + // Update labels and regenerate text (only if font is loaded) + updateLabels(); + if (font) { + genType(); + } } \ No newline at end of file From 36a648b28fa0178d10ba13b504e46a7b3f4ef9a0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 16 Dec 2025 09:05:21 +0000 Subject: [PATCH 3/4] Changes before error encountered Co-authored-by: ilesinge <501674+ilesinge@users.noreply.github.com> --- mockup.html | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) create mode 100644 mockup.html diff --git a/mockup.html b/mockup.html new file mode 100644 index 0000000..bfd68e4 --- /dev/null +++ b/mockup.html @@ -0,0 +1,138 @@ + + +
+
+ Location: Top right corner, next to the help button
+ Icon: ⎘ (copy/share icon)
+ Function: Copies current preset as URL to clipboard
+
navigator.clipboard.writeText()Click the share button above to see it in action ↑
+
- Location: Top right corner, next to the help button
- Icon: ⎘ (copy/share icon)
- Function: Copies current preset as URL to clipboard
-
navigator.clipboard.writeText()Click the share button above to see it in action ↑
-