diff --git a/.eslintrc.json b/.eslintrc.json index 308fadc..003421b 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,7 +10,7 @@ "sourceType": "script" }, "rules": { - "indent": "off", + "indent": ["error", 4], "linebreak-style": ["error", "unix"], "quotes": ["error", "single"], "semi": ["error", "always"], diff --git a/README.md b/README.md deleted file mode 100644 index b196211..0000000 --- a/README.md +++ /dev/null @@ -1,168 +0,0 @@ -# Ǧ̴̝̲̙̱̳̗̱͊̒̀̀̀l̶̰̲̯̗̾̊͌̀̊̃̓̚i̴̧̘͕̺͉̘̇̃̄̏͂̃͛̎̐t̷̢̨̙̗̞̯͖̗̳͌c̷̖͓̟̞͋h̷̨̻̝̻̩̼̤̣̟̓͗̑͝C̴̺̺̘͍̙̈͐̀̾̔̈́̒̃r̷̢̧̢̛̬̱̻̝̭̈́̍̐͒̇ā̸̤̜͌̓̋̉̓̉̚f̸̘̘̤͙̠̈́̐̍̀͋͊̕͝t̸̨̹̪̭̲̮̗̳̽̎ - -> **Artisanal text corruption, served fresh!** - -Transform your boring text into b̴̧̧̯̰̲̤̫̲͇̅̀̓̆̈́̈́̄̀e̵̫̥̱̿̾̊̉͊́̚a̸̫̺̘̤̰̝̿̐̍͗̇̋u̸̢̳̝̯̲̮̦̇̍̔̈́̎̊t̸̨̲̘̺̹̙̋͆̀̅̚i̸̧̦̩̥̫̭̬̍̑̎́̒f̵̰̰̺̹̤̋ù̴̧̡̢̘̱̇͛̉̇̂͌l̶̺̩̰̥̀̉̄̄̈́͝ć̵̨̧̦̞̤̤̠̃́̔̀͝h̴̭̙̋̊̾͛́a̴̻̦̹̰̖̅̀͌̃ō̴̳̜̝̮͇͍̄̓̋͌̍̔s̷̘̺̤̩͂̽̌̅̈͠! GlitchCraft is a Progressive Web App that generates zalgo text using Unicode combining characters. - -## ✨ F̴̛̪̞̯̀̔́ͅe̷̮̮̗̣̎a̸̤̺̜̾̃̓͜t̶̛̘̝̾u̴̢̬͇̒ṛ̴̭̖̈́e̷̲̺̔̓͝ş̷̝̑̀ - -- **🎨 Six Corruption Modes**: From subtle glitches to complete chaos -- **📱 Mobile-First Design**: Perfect experience on all devices -- **⚡ Real-Time Generation**: See corruption as you type -- **📋 One-Click Copy**: Tap the output to copy instantly -- **🔧 Adjustable Intensity**: Fine-tune your chaos level (1-10) -- **💾 PWA Ready**: Install as an app, works offline -- **🌐 Universal Support**: Works on all modern browsers - -## 🎭 Corruption Modes - -| Mode | Example | Description | -|------|---------|-------------| -| **Full Chaos** | ĥ̵̝̮̀è̸̘̩l̴̹̩̔l̵̲̎ô̶̰ ̷̳̎w̸̰̄o̶̜̅r̷̰̄l̴̨̾d̶̰̈ | Balanced corruption above, middle, and below | -| **Above Only** | h̸̘̤́ë̸́l̴̮̆l̸̘̀ö̴́ ̶̘̀w̴̮̌ö̴́ř̶̰l̴̮̀d̸̮̆ | Marks above characters only | -| **Below Only** | h̴̖̆ë̵l̵̰l̵̲ö̴ ̷̰w̴̰ö̴̰r̴̲l̵̲d̴̰ | Marks below characters only | -| **Middle Only** | h̶e̷l̷l̶o̵ ̴w̵o̴r̷l̴d̵ | Marks overlaying characters | -| **Mini Glitch** | ḧ̴e̵l̴l̷o̵ ̴w̶o̴r̷l̴d̵ | Subtle corruption | -| **Heavy Corruption** | h̸̨̬̘̤̖̱̗̘̄̀́̌̈́̀̇̚ë̴̛̖̘̩̰̱̳̤́̓̒̚l̷̢̧̰̲̫̲̝̹̈́̔̃̀̈́̇̚l̴̢̧̰̲̫̲̝̹̈́̔̃̀̈́̇̚ö̴́̓̒̚ ̷̰̔̈́w̸̰̄̌ö̴́̓̒̚r̷̰̄̌l̴̰̔̈́d̶̰̈́̌ | Maximum chaos overload | - -## 🚀 Quick Start - -### 🌐 Online -Visit the deployed app at: **[Your deployment URL]** - -### 💻 Local Development - -```bash -# Clone the repository -git clone -cd zalgo - -# Install dependencies -just install -# or: bun install - -# Start development server -just serve -# or: python3 server.py - -# Open http://localhost:8000 -``` - -## 🛠️ Development - -### Prerequisites -- **Bun** (for dependencies and linting) -- **Python 3** (for development server) -- **Just** (for task automation, optional) - -### Available Commands - -```bash -# Development -just serve # Start development server -just serve-bg # Start server in background -just stop # Stop background server - -# Code Quality -just lint-all # Lint JavaScript and Python -just format-all # Format all code -just check-all # Run all linting and validation - -# Testing & Validation -just validate # Full validation suite -just validate-references # Check file references exist -just validate-html # Validate HTML (requires Java) -just validate-manifest # Validate PWA manifest - -# PWA Icons -just icons-png # Generate PNG icons (requires canvas) -just icons-browser # Open browser icon generator - -# Project Info -just info # Show project information -just status # Check server status -``` - -## 📱 Mobile Experience - -GlitchCraft is designed mobile-first with: - -- **Touch-optimized controls** with larger touch targets -- **Responsive layout** that adapts from 320px to 4K -- **iOS zoom prevention** with proper font sizes -- **Haptic feedback** for copy actions (where supported) -- **Full-screen support** when installed as PWA -- **Offline functionality** via service worker - -### Mobile Features -- Tap output text to copy instantly -- Swipe-friendly interface -- Portrait and landscape support -- Works great on tablets - -## 🔧 Technical Details - -### Architecture -- **Pure JavaScript** - No frameworks, maximum performance -- **Service Worker** - Full offline support with cache-first strategy -- **Progressive Enhancement** - Works without JavaScript -- **Accessible** - Screen reader compatible, keyboard navigation - -### Zalgo Algorithm -The corruption engine uses Unicode combining diacritical marks from three categories: -- **Above** (U+0300-U+036F): Accents and marks above characters -- **Middle** (U+0315-U+0489): Overlaying marks -- **Below** (U+0316-U+0359): Marks below characters - -Each mode strategically applies different combinations for unique effects. - -### Browser Support -- ✅ Chrome/Chromium 88+ -- ✅ Firefox 85+ -- ✅ Safari 14+ -- ✅ Edge 88+ -- ✅ Mobile browsers (iOS Safari, Chrome Mobile) - -## 🎨 Examples - -Here are some z̴̳̈a̸̭̾l̵̰̔g̶̱̈ó̴̬ ̷̲̎t̸̰̄e̶̮̾x̷̲̄ẗ̴̰ examples: - -### Normal Text → Corrupted -``` -Hello World → H̸̖̄e̶̮̾l̵̰̔ḻ̶̈ó̴̬ ̷̲̎W̸̰̄ö̶̮̾r̵̰̔ḻ̶̈d̴̬̈ - -Welcome to GlitchCraft → Ẁ̴̛̪̞̯̔́ͅe̷̮̮̗̣̎l̴̹̩̔c̸̘̩̀ö̴̝̮̀m̵̲̎ë̸̘̩ ̶̰̔t̷̳̎ő̶̰ ̴̨̾G̴̮̀l̸̘̀i̵̲t̴̖̆c̵̰h̴̘Č̶̮r̴̮̀a̵̲f̴̰t̸̮̆ - -The quick brown fox → T̷̨̄h̶̨̍ë̴́ ̵̌q̷̇ű̴i̸̇c̸̈ǩ̶ ̴̈b̵̄ř̷ö̴́ẇ̸n̶̈ ̴̌f̷̄ö̴́ẋ̸ -``` - -### Heavy Corruption Mode -``` -CHAOS → C̸̨̧̬̘̤̖̱̗̘̄̀́̌̈́̀̇̚Ḧ̷̢̧̰̲̫̲̝̹́̔̃̀̈́̇̚Ä̴̢̧̰̲̫̲̝̹́̔̃̀̈́̇̚Ö̷̰́̓̒̚S̷̰̔̈́ -``` - -## 🤝 Contributing - -1. Fork the repository -2. Create a feature branch -3. Make your changes -4. Run `just check-all` to ensure quality -5. Submit a pull request - -## 📄 License - -MIT License - Feel free to use this for your own projects! - -## 🎭 Fun Facts - -- The name "zalgo" comes from a creepypasta character -- Unicode combining characters were designed for legitimate text rendering -- GlitchCraft generates infinite unique corruptions -- The glitch animations are pure CSS - no JavaScript! -- Works offline once loaded (thanks to service worker) - ---- - -**Made with ❤️ and ḉ̴̨̧̰̲̫̲̝̹̈́̔̃̀̈́̇̚h̷̰̔̈́ä̸̰́̌ō̶̰̔̈́s̷̰̔̈́** - -*Transform your text, embrace the glitch, spread the chaos!* \ No newline at end of file diff --git a/app/app.js b/app/app.js index 7e73d09..d151350 100644 --- a/app/app.js +++ b/app/app.js @@ -13,7 +13,6 @@ const inputText = document.getElementById('inputText'); const outputText = document.getElementById('outputText'); const intensitySlider = document.getElementById('intensity'); const intensityValue = document.getElementById('intensityValue'); -const zalgoModeSelect = document.getElementById('zalgoMode'); const clearBtn = document.getElementById('clearBtn'); const copyNotification = document.getElementById('copyNotification'); @@ -23,10 +22,9 @@ const copyNotification = document.getElementById('copyNotification'); function updateOutput() { const text = inputText.value; const intensity = parseInt(intensitySlider.value); - const mode = zalgoModeSelect.value; if (text) { - outputText.value = zalgo.generate(text, intensity, mode); + outputText.value = zalgo.generate(text, intensity); } else { outputText.value = ''; } @@ -76,8 +74,6 @@ intensitySlider.addEventListener('input', () => { updateOutput(); }); -zalgoModeSelect.addEventListener('change', updateOutput); - outputText.addEventListener('click', copyToClipboard); clearBtn.addEventListener('click', clearAll); diff --git a/app/index.html b/app/index.html index a8dc4f4..b4703c7 100644 --- a/app/index.html +++ b/app/index.html @@ -24,23 +24,9 @@
-
- - -
- -
- - - 5 -
+ + + 5
diff --git a/app/styles.css b/app/styles.css index 26d23a7..7099903 100644 --- a/app/styles.css +++ b/app/styles.css @@ -96,8 +96,8 @@ h1 { .controls { display: flex; - flex-wrap: wrap; - gap: 20px; + align-items: center; + gap: 15px; margin-bottom: 30px; padding: 20px; background: var(--bg-tertiary); @@ -105,42 +105,9 @@ h1 { border: 1px solid var(--border); } -.control-group { - display: flex; - align-items: center; - gap: 10px; - flex: 1; - min-width: 200px; -} - .controls label { color: var(--text-secondary); font-size: 0.95rem; - white-space: nowrap; - min-width: 80px; -} - -#zalgoMode { - flex: 1; - padding: 8px 12px; - background: var(--bg-primary); - border: 2px solid var(--border); - border-radius: 8px; - color: var(--text-primary); - font-size: 0.95rem; - outline: none; - transition: all 0.3s ease; - min-width: 120px; -} - -#zalgoMode:focus { - border-color: var(--accent); - box-shadow: 0 0 10px var(--shadow); -} - -#zalgoMode option { - background: var(--bg-primary); - color: var(--text-primary); } #intensity { @@ -310,126 +277,24 @@ footer p { } /* Mobile responsiveness */ -@media (max-width: 768px) { - body { - padding: 10px; - } - +@media (max-width: 600px) { .container { - padding: 20px; - max-width: 100%; + padding: 25px; } h1 { font-size: 2rem; } - .subtitle { - font-size: 1rem; - } - .controls { - flex-direction: column; - gap: 15px; - padding: 15px; - } - - .control-group { flex-direction: column; align-items: stretch; - gap: 8px; - min-width: auto; - } - - .controls label { - min-width: auto; - font-size: 0.9rem; - } - - #zalgoMode { - width: 100%; - padding: 12px; - font-size: 1rem; - min-width: auto; - } - - #intensity { - width: 100%; - height: 8px; - } - - #intensity::-webkit-slider-thumb { - width: 24px; - height: 24px; - } - - #intensity::-moz-range-thumb { - width: 24px; - height: 24px; - } - - textarea { - min-height: 140px; - font-size: 1rem; - padding: 15px; - } - - .clear-btn { - padding: 18px; - font-size: 1.1rem; - } - - .copy-notification { - padding: 15px 25px; - font-size: 1rem; - } -} - -/* Small mobile devices */ -@media (max-width: 480px) { - .container { - padding: 15px; - } - - h1 { - font-size: 1.8rem; - } - - .controls { - padding: 12px; - gap: 12px; + gap: 10px; } textarea { min-height: 120px; - font-size: 16px; /* Prevents zoom on iOS */ - } - - #zalgoMode { - font-size: 16px; /* Prevents zoom on iOS */ - } -} - -/* Touch-friendly improvements */ -@media (hover: none) and (pointer: coarse) { - /* Touch device specific styles */ - textarea { - font-size: 16px; /* Prevents zoom on mobile browsers */ - } - - #zalgoMode { - font-size: 16px; - padding: 15px; - } - - .clear-btn { - min-height: 48px; /* Minimum touch target size */ - } - - #outputText { - cursor: pointer; - -webkit-user-select: all; - user-select: all; + font-size: 0.95rem; } } diff --git a/app/zalgo.js b/app/zalgo.js index b0021b7..5bfba06 100644 --- a/app/zalgo.js +++ b/app/zalgo.js @@ -215,13 +215,12 @@ class ZalgoGenerator { } /** - * Generate zalgo text with specified intensity and mode + * Generate zalgo text with specified intensity * @param {string} text - The input text to corrupt * @param {number} intensity - Corruption intensity (1-10) - * @param {string} mode - Corruption mode (full, above, below, middle, mini, heavy) * @returns {string} - The corrupted zalgo text */ - generate(text, intensity = 5, mode = 'full') { + generate(text, intensity = 5) { if (!text) return ''; // Normalize intensity to 1-10 range @@ -237,52 +236,20 @@ class ZalgoGenerator { continue; } - // Calculate how many combining characters to add based on intensity and mode + // Calculate how many combining characters to add based on intensity + // Higher intensity = more corruption const factor = intensity / 10; - let aboveCount = 0; - let middleCount = 0; - let belowCount = 0; - - switch (mode) { - case 'above': - aboveCount = Math.floor(Math.random() * (6 * factor)); - break; - - case 'below': - belowCount = Math.floor(Math.random() * (6 * factor)); - break; - - case 'middle': - middleCount = Math.floor(Math.random() * (4 * factor)); - break; - - case 'mini': - // Light corruption - fewer characters - aboveCount = Math.floor(Math.random() * (2 * factor)); - middleCount = Math.floor(Math.random() * (1 * factor)); - belowCount = Math.floor(Math.random() * (2 * factor)); - break; - - case 'heavy': - // Heavy corruption - more characters - aboveCount = Math.floor(Math.random() * (8 * factor)) + 1; - middleCount = Math.floor(Math.random() * (5 * factor)) + 1; - belowCount = Math.floor(Math.random() * (8 * factor)) + 1; - break; - - case 'full': - default: - // Balanced corruption - aboveCount = Math.floor(Math.random() * (4 * factor)); - middleCount = Math.floor(Math.random() * (3 * factor)); - belowCount = Math.floor(Math.random() * (4 * factor)); - break; - } - - // Add the calculated characters + // Add characters above (0-3 based on intensity) + const aboveCount = Math.floor(Math.random() * (4 * factor)); result += this.randomChars(this.above, aboveCount); + + // Add characters in middle (0-2 based on intensity) + const middleCount = Math.floor(Math.random() * (3 * factor)); result += this.randomChars(this.middle, middleCount); + + // Add characters below (0-3 based on intensity) + const belowCount = Math.floor(Math.random() * (4 * factor)); result += this.randomChars(this.below, belowCount); } diff --git a/justfile b/justfile index d9c880d..4f1acdd 100644 --- a/justfile +++ b/justfile @@ -91,8 +91,7 @@ setup: install icons-png # Testing and validation # Validate HTML files validate-html: - @echo "Validating HTML files..." - @command -v java >/dev/null 2>&1 && java -jar node_modules/vnu-jar/build/dist/vnu.jar app/index.html app/generate-icons.html || (echo "✓ HTML files exist (install Java for full validation)" && test -f app/index.html && test -f app/generate-icons.html) + bunx vnu-jar app/index.html app/generate-icons.html # Test PWA manifest validate-manifest: