feat: json export and import
This commit is contained in:
		@ -379,6 +379,72 @@
 | 
				
			|||||||
			stickyNotes.splice(index, 1);
 | 
								stickyNotes.splice(index, 1);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function exportCanvas() {
 | 
				
			||||||
 | 
							const canvasState = {
 | 
				
			||||||
 | 
								selectedDeck,
 | 
				
			||||||
 | 
								shuffleMode,
 | 
				
			||||||
 | 
								cards: cards.map(card => ({...card})),
 | 
				
			||||||
 | 
								stickyNotes: stickyNotes.map(note => ({...note})),
 | 
				
			||||||
 | 
								canvasOffset,
 | 
				
			||||||
 | 
								deckPosition,
 | 
				
			||||||
 | 
								maxZIndex,
 | 
				
			||||||
 | 
								nextNoteId,
 | 
				
			||||||
 | 
								timestamp: new Date().toISOString()
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const dataStr = JSON.stringify(canvasState, null, 2);
 | 
				
			||||||
 | 
							const dataBlob = new Blob([dataStr], { type: 'application/json' });
 | 
				
			||||||
 | 
							const url = URL.createObjectURL(dataBlob);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							const link = document.createElement('a');
 | 
				
			||||||
 | 
							link.href = url;
 | 
				
			||||||
 | 
							link.download = `canvas-${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.json`;
 | 
				
			||||||
 | 
							document.body.appendChild(link);
 | 
				
			||||||
 | 
							link.click();
 | 
				
			||||||
 | 
							document.body.removeChild(link);
 | 
				
			||||||
 | 
							URL.revokeObjectURL(url);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function importCanvas() {
 | 
				
			||||||
 | 
							const input = document.createElement('input');
 | 
				
			||||||
 | 
							input.type = 'file';
 | 
				
			||||||
 | 
							input.accept = '.json';
 | 
				
			||||||
 | 
							input.onchange = (event) => {
 | 
				
			||||||
 | 
								const file = (event.target as HTMLInputElement).files?.[0];
 | 
				
			||||||
 | 
								if (!file) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								const reader = new FileReader();
 | 
				
			||||||
 | 
								reader.onload = (e) => {
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
 | 
										const canvasState = JSON.parse(e.target?.result as string);
 | 
				
			||||||
 | 
										
 | 
				
			||||||
 | 
										// Validate the imported data structure
 | 
				
			||||||
 | 
										if (!canvasState.cards || !Array.isArray(canvasState.cards)) {
 | 
				
			||||||
 | 
											alert('Invalid canvas file format');
 | 
				
			||||||
 | 
											return;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Restore state
 | 
				
			||||||
 | 
										selectedDeck = canvasState.selectedDeck || 0;
 | 
				
			||||||
 | 
										shuffleMode = canvasState.shuffleMode || 'normal';
 | 
				
			||||||
 | 
										cards = canvasState.cards || [];
 | 
				
			||||||
 | 
										stickyNotes = canvasState.stickyNotes || [];
 | 
				
			||||||
 | 
										canvasOffset = canvasState.canvasOffset || { x: 0, y: 0 };
 | 
				
			||||||
 | 
										deckPosition = canvasState.deckPosition || { x: 50, y: 300 };
 | 
				
			||||||
 | 
										maxZIndex = canvasState.maxZIndex || cards.length;
 | 
				
			||||||
 | 
										nextNoteId = canvasState.nextNoteId || 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									} catch (error) {
 | 
				
			||||||
 | 
										alert('Error reading canvas file: ' + error);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
								reader.readAsText(file);
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
							document.body.appendChild(input);
 | 
				
			||||||
 | 
							input.click();
 | 
				
			||||||
 | 
							document.body.removeChild(input);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class="game-container">
 | 
					<div class="game-container">
 | 
				
			||||||
@ -408,6 +474,8 @@
 | 
				
			|||||||
		<button onclick={dealCards}>Deal Cards</button>
 | 
							<button onclick={dealCards}>Deal Cards</button>
 | 
				
			||||||
		<button onclick={flipAllCards}>Flip All</button>
 | 
							<button onclick={flipAllCards}>Flip All</button>
 | 
				
			||||||
		<button onclick={addStickyNote}>Add Note</button>
 | 
							<button onclick={addStickyNote}>Add Note</button>
 | 
				
			||||||
 | 
							<button onclick={exportCanvas}>Export</button>
 | 
				
			||||||
 | 
							<button onclick={importCanvas}>Import</button>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	<div 
 | 
						<div 
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user