const { createApp, ref, onMounted, watch, nextTick } = Vue; const codeSnippets = { python: `def hello_world(): print("Hello, Trae!") return True # Build something amazing if __name__ == "__main__": hello_world()`, javascript: `function greet(name) { return \`Hello, \${name}!\`; } // Welcome to Code Snapshot Studio console.log(greet('Developer'));`, typescript: `interface User { id: number; name: string; } const user: User = { id: 1, name: "Trae User" }; console.log(user);`, html: `
Welcome to my website.
`, css: `.container { display: flex; justify-content: center; align-items: center; height: 100vh; background: #f0f0f0; }`, java: `public class Main { public static void main(String[] args) { System.out.println("Hello, World!"); } }`, go: `package main import "fmt" func main() { fmt.Println("Hello, Go!") }`, rust: `fn main() { println!("Hello, Rust!"); }`, sql: `SELECT id, username, email FROM users WHERE status = 'active' ORDER BY created_at DESC;`, bash: `#!/bin/bash echo "Starting deployment..." npm install npm run build echo "Done!"`, json: `{ "name": "code-snapshot-studio", "version": "1.0.0", "private": true }` }; createApp({ setup() { const code = ref(codeSnippets.python); const language = ref('python'); const theme = ref('tomorrow'); const padding = ref(64); const showWindowControls = ref(true); const showLineNumbers = ref(true); const showShadow = ref(true); const windowTitle = ref('main.py'); const snapshotCard = ref(null); const codeBlock = ref(null); const isExporting = ref(false); const showSidebar = ref(true); // For mobile toggle // Background presets const backgrounds = [ { name: 'Gradient 1', value: 'linear-gradient(135deg, #FF9D6C 0%, #BB4E75 100%)' }, { name: 'Gradient 2', value: 'linear-gradient(135deg, #85FFBD 0%, #FFFB7D 100%)' }, { name: 'Gradient 3', value: 'linear-gradient(135deg, #8EC5FC 0%, #E0C3FC 100%)' }, { name: 'Gradient 4', value: 'linear-gradient(135deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%)' }, { name: 'Solid Dark', value: '#1e293b' }, { name: 'Solid Light', value: '#f8fafc' }, { name: 'Mesh Gradient', value: 'radial-gradient(at 40% 20%, hsla(28,100%,74%,1) 0px, transparent 50%), radial-gradient(at 80% 0%, hsla(189,100%,56%,1) 0px, transparent 50%), radial-gradient(at 0% 50%, hsla(355,100%,93%,1) 0px, transparent 50%)' } ]; const currentBg = ref(backgrounds[3]); const themeBgColor = ref('#2d2d2d'); // Default for Tomorrow const changeTheme = () => { const link = document.getElementById('prism-theme'); const baseUrl = 'https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism'; if (theme.value === 'default') { link.href = `${baseUrl}.min.css`; themeBgColor.value = '#f5f2f0'; } else { link.href = `${baseUrl}-${theme.value}.min.css`; // Update bg color approximation if(theme.value === 'tomorrow') themeBgColor.value = '#2d2d2d'; if(theme.value === 'okaidia') themeBgColor.value = '#272822'; if(theme.value === 'solarizedlight') themeBgColor.value = '#fdf6e3'; if(theme.value === 'twilight') themeBgColor.value = '#141414'; } }; const refreshHighlight = () => { nextTick(() => { if (window.Prism) { Prism.highlightAll(); } }); }; // Auto-load snippet when language changes (if code is empty or matches another snippet) const onLanguageChange = () => { // Optional: You could ask user or just automatically switch if it's default // For now, let's just refresh highlight refreshHighlight(); }; const loadExample = () => { if (codeSnippets[language.value]) { code.value = codeSnippets[language.value]; } }; watch([code, language, showLineNumbers], () => { refreshHighlight(); }); onMounted(() => { refreshHighlight(); // Check screen size for initial sidebar state if (window.innerWidth < 1024) { showSidebar.value = false; } }); const clearCode = () => { code.value = ''; }; const copyImage = async () => { if (!snapshotCard.value || isExporting.value) return; isExporting.value = true; try { await nextTick(); const canvas = await html2canvas(snapshotCard.value, { scale: 2, useCORS: true, backgroundColor: null, logging: false, allowTaint: true }); canvas.toBlob(async (blob) => { try { await navigator.clipboard.write([ new ClipboardItem({ [blob.type]: blob }) ]); alert('图片已复制到剪贴板'); } catch (err) { console.error('Copy failed:', err); alert('复制失败,浏览器可能不支持此功能'); } }); } catch (err) { console.error('Render failed:', err); alert('生成图片失败,请重试'); } finally { isExporting.value = false; } }; const exportImage = async () => { if (!snapshotCard.value || isExporting.value) return; isExporting.value = true; try { // Wait for any renders await nextTick(); const canvas = await html2canvas(snapshotCard.value, { scale: 2, // Retina support useCORS: true, backgroundColor: null, logging: false, allowTaint: true }); const link = document.createElement('a'); link.download = `code-snapshot-${Date.now()}.png`; link.href = canvas.toDataURL('image/png'); link.click(); } catch (err) { console.error('Export failed:', err); alert('导出失败,请重试'); } finally { isExporting.value = false; } }; const toggleSidebar = () => { showSidebar.value = !showSidebar.value; }; return { code, language, theme, padding, showWindowControls, showLineNumbers, showShadow, windowTitle, backgrounds, currentBg, snapshotCard, codeBlock, copyImage, clearCode, exportImage, changeTheme, refreshHighlight, themeBgColor, onLanguageChange, loadExample, isExporting, showSidebar, toggleSidebar }; } }).mount('#app');