Enter Your Text
Font Selection & Styles
Preview will appear here…
Advanced Configuration
80 characters
Tools & Utilities
ASCII Art Results
🎨 Welcome to Advanced ASCII Art Generator!
Use the tabs above to input text, select fonts, adjust settings, and access powerful tools!
${currentASCIIArt}
`);
printWindow.document.close();
printWindow.print();
showNotification('Print dialog opened!');
}
function showAbout() {
asciiResultsContainer.innerHTML = `
🎨 Advanced ASCII Art Generator
Version: 2.0 Professional
Features: 16 ASCII fonts, Advanced controls, Multiple output formats
Created: ${new Date().getFullYear()}
This advanced ASCII art generator provides professional-grade text-to-ASCII conversion with extensive customization options.
Supported Features:
- 16 Different ASCII Font Styles
- Character Width & Height Controls
- Text Alignment Options
- Border Styles & Line Spacing
- Multiple Color Schemes
- Export to HTML, Markdown, BBCode
- Print & Share Functionality
- Save/Load Settings
`;
}
function showHelp() {
asciiResultsContainer.innerHTML = `
📖 Help & Usage Guide
🎯 Quick Start:
- Enter your text in the Text Input tab
- Choose a font style in the Fonts & Styles tab
- Adjust settings in the Advanced Settings tab
- Use tools in the Tools & Utilities tab
⚙️ Controls Explained:
- Character Width: Controls spacing between characters
- Character Height: Adjusts vertical spacing and proportion
- Text Alignment: Positions text within the output area
- Line Spacing: Controls space between lines
- Border Style: Adds decorative borders around text
- Output Width: Sets maximum width in characters
🎨 Tips for Best Results:
- Keep text under 20 characters for optimal display
- Use UPPERCASE for better visibility
- Try different fonts for various effects
- Adjust character width for tighter/looser spacing
- Use borders for framing important text
📋 Keyboard Shortcuts:
- Ctrl+Enter: Generate ASCII art
- Ctrl+C: Copy result
- Ctrl+S: Save settings
`;
}
// ASCII Art Styles and Generators
const asciiStyles = {
'block': {
name: 'Block Letters',
preview: '███ ██ █\n█ █ █ █\n███ ██ █',
generator: generateBlockASCII
},
'thin': {
name: 'Thin Lines',
preview: '┌─┐ ┌─ ┌─┐\n├─┤ ├─ │ \n┘ └ └─ └─┘',
generator: generateThinASCII
},
'double': {
name: 'Double Lines',
preview: '╔══ ╔══ ╔══\n║ ║ ║ \n╚══ ╚══ ╚══',
generator: generateDoubleASCII
},
'shadow': {
name: '3D Shadow',
preview: '▄▄▄ ▄▄ ▄▄▄\n█▄▄ █▄▄ █▄▄\n███ ███ ███',
generator: generateShadowASCII
},
'dots': {
name: 'Dotted Style',
preview: '••• ••• ••\n• • • ••\n••• ••• ••',
generator: generateDotsASCII
},
'slant': {
name: 'Slanted',
preview: ' __ ___\n / / / __\n /_/ /___/',
generator: generateSlantASCII
},
'small': {
name: 'Small',
preview: 'o-o |-| o\n| |-| |\no-o |-| o',
generator: generateSmallASCII
},
'big': {
name: 'Big Bold',
preview: '██████ ██████\n██ ██ ██\n██████ ██████',
generator: generateBigASCII
},
'outline': {
name: 'Outline Style',
preview: '╭─╮ ╭─╮ ╭─╮\n│ │ │ │ │ │\n╰─╯ ╰─╯ ╰─╯',
generator: generateOutlineASCII
},
'bubble': {
name: 'Bubble Letters',
preview: '○○○ ○○ ○\n○ ○ ○ ○\n○○○ ○○ ○',
generator: generateBubbleASCII
},
'star': {
name: 'Star Pattern',
preview: '★★★ ★★ ★\n★ ★ ★ ★\n★★★ ★★ ★',
generator: generateStarASCII
},
'digital': {
name: 'Digital Display',
preview: '▓▓▓ ▓▓▓ ▓▓▓\n▓ ▓ ▓ ▓▓▓\n▓▓▓ ▓▓▓ ▓▓▓',
generator: generateDigitalASCII
},
'neon': {
name: 'Neon Style',
preview: '░█░ ░█░ ░█░\n░█░ ░█░ ░█░\n░█░ ░█░ ░█░',
generator: generateNeonASCII
},
'rounded': {
name: 'Rounded Corners',
preview: '╭─╮ ╭─╮ ╭─╮\n├─┤ ├─┤ │ │\n╰─╯ ╰─╯ ╰─╯',
generator: generateRoundedASCII
},
'morse': {
name: 'Morse Code',
preview: '••• ••• ••\n• ••• ••\n••• ••• ••',
generator: generateMorseASCII
},
'pixel': {
name: 'Pixel Art',
preview: '▪▪▪ ▪▪▪ ▪▪▪\n▪ ▪ ▪ ▪ \n▪▪▪ ▪▪▪ ▪▪▪',
generator: generatePixelASCII
}
};
// Character mappings for different ASCII styles
const charMaps = {
block: {
'A': ['███', '█ █', '███', '█ █', '█ █'],
'B': ['██ ', '█ █', '██ ', '█ █', '██ '],
'C': ['███', '█ ', '█ ', '█ ', '███'],
'D': ['██ ', '█ █', '█ █', '█ █', '██ '],
'E': ['███', '█ ', '██ ', '█ ', '███'],
'F': ['███', '█ ', '██ ', '█ ', '█ '],
'G': ['███', '█ ', '█ █', '█ █', '███'],
'H': ['█ █', '█ █', '███', '█ █', '█ █'],
'I': ['███', ' █ ', ' █ ', ' █ ', '███'],
'J': ['███', ' █', ' █', '█ █', '███'],
'K': ['█ █', '██ ', '█ ', '██ ', '█ █'],
'L': ['█ ', '█ ', '█ ', '█ ', '███'],
'M': ['█ █', '███', '███', '█ █', '█ █'],
'N': ['█ █', '███', '███', '███', '█ █'],
'O': ['███', '█ █', '█ █', '█ █', '███'],
'P': ['██ ', '█ █', '██ ', '█ ', '█ '],
'Q': ['███', '█ █', '█ █', '███', ' █'],
'R': ['██ ', '█ █', '██ ', '█ █', '█ █'],
'S': ['███', '█ ', '███', ' █', '███'],
'T': ['███', ' █ ', ' █ ', ' █ ', ' █ '],
'U': ['█ █', '█ █', '█ █', '█ █', '███'],
'V': ['█ █', '█ █', '█ █', '█ █', ' █ '],
'W': ['█ █', '█ █', '███', '███', '█ █'],
'X': ['█ █', ' █ ', ' █ ', ' █ ', '█ █'],
'Y': ['█ █', '█ █', ' █ ', ' █ ', ' █ '],
'Z': ['███', ' █', ' █ ', '█ ', '███'],
'0': ['███', '█ █', '█ █', '█ █', '███'],
'1': [' █ ', '██ ', ' █ ', ' █ ', '███'],
'2': ['███', ' █', '███', '█ ', '███'],
'3': ['███', ' █', '███', ' █', '███'],
'4': ['█ █', '█ █', '███', ' █', ' █'],
'5': ['███', '█ ', '███', ' █', '███'],
'6': ['███', '█ ', '███', '█ █', '███'],
'7': ['███', ' █', ' █', ' █', ' █'],
'8': ['███', '█ █', '███', '█ █', '███'],
'9': ['███', '█ █', '███', ' █', '███'],
' ': [' ', ' ', ' ', ' ', ' '],
'!': [' █ ', ' █ ', ' █ ', ' ', ' █ '],
'?': ['███', ' █', ' █ ', ' ', ' █ '],
'.': [' ', ' ', ' ', ' ', ' █ '],
',': [' ', ' ', ' ', ' █ ', '█ '],
':': [' ', ' █ ', ' ', ' █ ', ' '],
';': [' ', ' █ ', ' ', ' █ ', '█ '],
'-': [' ', ' ', '███', ' ', ' '],
'_': [' ', ' ', ' ', ' ', '███'],
'=': [' ', '███', ' ', '███', ' '],
'+': [' ', ' █ ', '███', ' █ ', ' '],
'*': [' ', '█ █', ' █ ', '█ █', ' '],
'/': [' █', ' █', ' █ ', '█ ', '█ '],
'\\': ['█ ', '█ ', ' █ ', ' █', ' █'],
'|': [' █ ', ' █ ', ' █ ', ' █ ', ' █ '],
'(': [' █ ', '█ ', '█ ', '█ ', ' █ '],
')': [' █ ', ' █', ' █', ' █', ' █ '],
'[': ['██ ', '█ ', '█ ', '█ ', '██ '],
']': [' ██', ' █', ' █', ' █', ' ██'],
'{': [' ██', '█ ', '██ ', '█ ', ' ██'],
'}': ['██ ', ' █', ' ██', ' █', '██ '],
'<': [' █', ' █ ', '█ ', ' █ ', ' █'],
'>': ['█ ', ' █ ', ' █', ' █ ', '█ '],
'@': ['███', '█ █', '███', '█ ', '███'],
'#': ['█ █', '███', '█ █', '███', '█ █'],
'$': [' █ ', '███', '█ ', '███', ' █ '],
'%': ['█ █', ' █', ' █ ', '█ ', '█ █'],
'^': [' █ ', '█ █', ' ', ' ', ' '],
'&': ['██ ', '█ █', '██ ', '█ █', '███'],
'~': [' ', '█ █', ' ██', ' ', ' ']
},
thin: {
'A': ['┌─┐', '├─┤', '│ │', '│ │', '└ ┘'],
'B': ['├─┐', '├─┤', '├─┤', '├─┤', '├─┘'],
'C': ['┌─┐', '│ ', '│ ', '│ ', '└─┘'],
'D': ['├─┐', '│ │', '│ │', '│ │', '├─┘'],
'E': ['┌─┐', '├─ ', '├─ ', '├─ ', '└─┘'],
'F': ['┌─┐', '├─ ', '├─ ', '│ ', '└ '],
'G': ['┌─┐', '│ ', '│ ┌', '│ │', '└─┘'],
'H': ['│ │', '├─┤', '│ │', '│ │', '└ ┘'],
'I': ['┌─┐', ' │ ', ' │ ', ' │ ', '└─┘'],
'J': ['┌─┐', ' │', ' │', '│ │', '└─┘'],
'K': ['│ │', '├─┘', '├─ ', '├─┐', '└ ┘'],
'L': ['│ ', '│ ', '│ ', '│ ', '└─┘'],
'M': ['│ │', '├┬┤', '│││', '│││', '└┴┘'],
'N': ['│ │', '├┬┤', '│││', '│││', '└┴┘'],
'O': ['┌─┐', '│ │', '│ │', '│ │', '└─┘'],
'P': ['├─┐', '├─┤', '├─┘', '│ ', '└ '],
'Q': ['┌─┐', '│ │', '│ │', '└─┤', ' └'],
'R': ['├─┐', '├─┤', '├─┘', '├─┐', '└ ┘'],
'S': ['┌─┐', '├─ ', '└─┐', ' │', '└─┘'],
'T': ['┌─┐', ' │ ', ' │ ', ' │ ', ' └ '],
'U': ['│ │', '│ │', '│ │', '│ │', '└─┘'],
'V': ['│ │', '│ │', '│ │', '└┬┘', ' └ '],
'W': ['│ │', '│ │', '│││', '├┬┤', '└┴┘'],
'X': ['│ │', '└┬┘', ' │ ', '┌┴┐', '└ ┘'],
'Y': ['│ │', '└┬┘', ' │ ', ' │ ', ' └ '],
'Z': ['┌─┐', ' ┌', ' ┌ ', '┌ ', '└─┘'],
'0': ['┌─┐', '│ │', '│ │', '│ │', '└─┘'],
'1': [' ┌ ', ' │ ', ' │ ', ' │ ', ' └ '],
'2': ['┌─┐', ' │', '┌─┘', '│ ', '└─┘'],
'3': ['┌─┐', ' │', '├─┐', ' │', '└─┘'],
'4': ['│ │', '│ │', '└─┤', ' │', ' └'],
'5': ['┌─┐', '├─ ', '└─┐', ' │', '└─┘'],
'6': ['┌─┐', '├─ ', '├─┐', '│ │', '└─┘'],
'7': ['┌─┐', ' │', ' │', ' │', ' └'],
'8': ['┌─┐', '├─┤', '├─┤', '│ │', '└─┘'],
'9': ['┌─┐', '│ │', '└─┤', ' │', '└─┘'],
' ': [' ', ' ', ' ', ' ', ' '],
'!': [' │ ', ' │ ', ' │ ', ' ', ' • '],
'?': ['┌─┐', ' │', ' ┌ ', ' ', ' • '],
'.': [' ', ' ', ' ', ' ', ' • '],
',': [' ', ' ', ' ', ' • ', '┌ '],
':': [' ', ' • ', ' ', ' • ', ' '],
';': [' ', ' • ', ' ', ' • ', '┌ '],
'-': [' ', ' ', '───', ' ', ' '],
'_': [' ', ' ', ' ', ' ', '───'],
'=': [' ', '───', ' ', '───', ' '],
'+': [' ', ' │ ', '─┼─', ' │ ', ' '],
'*': [' ', '│•│', '─•─', '│•│', ' '],
'/': [' ┌', ' │', ' ┌ ', '┌ ', '│ '],
'\\': ['┐ ', '│ ', ' ┐ ', ' ┐', ' │'],
'|': [' │ ', ' │ ', ' │ ', ' │ ', ' │ '],
'(': [' ┌ ', '┌ ', '│ ', '└ ', ' └ '],
')': [' ┐ ', ' ┐', ' │', ' ┌', ' ┌ '],
'[': ['┌─ ', '│ ', '│ ', '│ ', '└─ '],
']': [' ─┐', ' │', ' │', ' │', ' ─┘'],
'{': [' ─┐', '┌ ', '├─ ', '└ ', ' ─┘'],
'}': ['┌─ ', ' ┐', ' ─┤', ' ┌', '└─ '],
'<': [' ┌', ' ┌ ', '┌ ', ' └ ', ' └'],
'>': ['┐ ', ' └ ', ' └', ' ┌ ', '┌ '],
'@': ['┌─┐', '│•│', '├─┤', '│ ', '└─┘'],
'#': ['│•│', '├─┤', '│•│', '├─┤', '└•┘'],
'$': [' │ ', '┌─┤', '└─┐', '├─┘', ' │ '],
'%': ['┌•┐', ' ┌', ' ┌ ', '┌ ', '└•┘'],
'^': [' ┌ ', '┌ └', ' ', ' ', ' '],
'&': ['┌─ ', '├─┐', '├─┘', '├─┐', '└─┘'],
'~': [' ', '┌•┐', '└ └', ' ', ' ']
}
};
// Generate different ASCII art styles
function generateBlockASCII(text) {
return generateFromCharMap(text.toUpperCase(), charMaps.block, 5);
}
function generateThinASCII(text) {
return generateFromCharMap(text.toUpperCase(), charMaps.thin, 5);
}
function generateDoubleASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.thin[char] || charMaps.thin[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/─/g, '═').replace(/│/g, '║').replace(/┌/g, '╔').replace(/┐/g, '╗').replace(/└/g, '╚').replace(/┘/g, '╝').replace(/├/g, '╠').replace(/┤/g, '╣').replace(/┬/g, '╦').replace(/┴/g, '╩').replace(/┼/g, '╬') + ' ';
}
}
return lines.join('\n');
}
function generateShadowASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
let line = pattern[i].replace(/█/g, '▓').replace(/ /g, '░');
lines[i] += line + '▒';
}
}
// Add shadow effect
for (let i = 1; i < 5; i++) {
lines[i] += '▒'.repeat(text.length);
}
lines.push('▒'.repeat(lines[0].length));
return lines.join('\n');
}
function generateDotsASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '●').replace(/ /g, '·') + ' ';
}
}
return lines.join('\n');
}
function generateSlantASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '/').replace(/ /g, ' ') + ' ';
}
}
return lines.join('\n');
}
function generateSmallASCII(text) {
let result = '';
for (let char of text.toUpperCase()) {
if (char === ' ') {
result += ' ';
} else if (char.match(/[A-Z]/)) {
result += char.toLowerCase() + ' ';
} else {
result += char + ' ';
}
}
return result.trim();
}
function generateBigASCII(text) {
const lines = ['', '', '', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '██').replace(/ /g, ' ') + ' ';
lines[i + 2] += pattern[i].replace(/█/g, '██').replace(/ /g, ' ') + ' ';
}
}
return lines.slice(0, 7).join('\n');
}
function generateOutlineASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.thin[char] || charMaps.thin[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/─/g, '─').replace(/│/g, '│').replace(/┌/g, '╭').replace(/┐/g, '╮').replace(/└/g, '╰').replace(/┘/g, '╯').replace(/├/g, '├').replace(/┤/g, '┤') + ' ';
}
}
return lines.join('\n');
}
function generateBubbleASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '○').replace(/ /g, ' ') + ' ';
}
}
return lines.join('\n');
}
function generateStarASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '★').replace(/ /g, ' ') + ' ';
}
}
return lines.join('\n');
}
function generateDigitalASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '▓').replace(/ /g, '░') + ' ';
}
}
return lines.join('\n');
}
function generateNeonASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '█').replace(/ /g, '░') + ' ';
}
}
return lines.join('\n');
}
function generateRoundedASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.thin[char] || charMaps.thin[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/┌/g, '╭').replace(/┐/g, '╮').replace(/└/g, '╰').replace(/┘/g, '╯').replace(/├/g, '├').replace(/┤/g, '┤').replace(/┬/g, '┬').replace(/┴/g, '┴') + ' ';
}
}
return lines.join('\n');
}
function generateMorseASCII(text) {
const morseCode = {
'A': '•−', 'B': '−•••', 'C': '−•−•', 'D': '−••', 'E': '•', 'F': '••−•',
'G': '−−•', 'H': '••••', 'I': '••', 'J': '•−−−', 'K': '−•−', 'L': '•−••',
'M': '−−', 'N': '−•', 'O': '−−−', 'P': '•−−•', 'Q': '−−•−', 'R': '•−•',
'S': '•••', 'T': '−', 'U': '••−', 'V': '•••−', 'W': '•−−', 'X': '−••−',
'Y': '−•−−', 'Z': '−−••', '0': '−−−−−', '1': '•−−−−', '2': '••−−−',
'3': '•••−−', '4': '••••−', '5': '•••••', '6': '−••••', '7': '−−•••',
'8': '−−−••', '9': '−−−−•', ' ': '/'
};
let result = '';
for (let char of text.toUpperCase()) {
result += (morseCode[char] || '?') + ' ';
}
return result.trim();
}
function generatePixelASCII(text) {
const lines = ['', '', '', '', ''];
for (let char of text.toUpperCase()) {
const pattern = charMaps.block[char] || charMaps.block[' '];
for (let i = 0; i < 5; i++) {
lines[i] += pattern[i].replace(/█/g, '▪').replace(/ /g, '▫') + ' ';
}
}
return lines.join('\n');
}
function generateFromCharMap(text, charMap, height) {
const lines = Array(height).fill('');
for (let char of text) {
const pattern = charMap[char] || charMap[' '];
for (let i = 0; i < height; i++) {
lines[i] += pattern[i] + ' ';
}
}
return lines.join('\n');
}
// Initialize ASCII styles
function initializeStyles() {
asciiStyleGrid.innerHTML = '';
Object.entries(asciiStyles).forEach(([key, style]) => {
const card = document.createElement('div');
card.className = 'ascii-style-card';
card.setAttribute('data-style', key);
card.onclick = () => selectStyle(key, card);
card.innerHTML = `
${style.name}
${style.preview}
`;
asciiStyleGrid.appendChild(card);
});
}
// Select ASCII style
function selectStyle(styleKey, element) {
// Remove previous selection
document.querySelectorAll('.ascii-style-card').forEach(card => {
card.classList.remove('selected');
});
// Select new style
element.classList.add('selected');
selectedStyle = styleKey;
// Show notification
showNotification(`Style Selected: ${asciiStyles[styleKey].name}`);
// Generate ASCII art if text exists
const text = asciiInputText.value.trim();
if (text) {
generateASCIIArt(text);
} else {
generateASCIIArt('SAMPLE');
}
// Scroll to results
setTimeout(() => {
asciiResults.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}, 300);
}
// Generate ASCII art
function generateASCIIArt(text) {
const style = asciiStyles[currentSettings.font];
if (!style) return;
let asciiArt = style.generator(text);
currentASCIIArt = asciiArt;
// Apply settings
asciiArt = applySettings(asciiArt);
asciiResultsContainer.innerHTML = `
${asciiArt}
`;
// Apply color scheme
setTimeout(() => {
applyColorScheme();
}, 100);
}
function applySettings(asciiArt) {
let lines = asciiArt.split('\n');
// Apply line spacing
if (currentSettings.lineSpacing === 'tight') {
lines = lines.filter((line, index) => index % 2 === 0 || line.trim() !== '');
} else if (currentSettings.lineSpacing === 'loose') {
const spacedLines = [];
lines.forEach(line => {
spacedLines.push(line);
spacedLines.push('');
});
lines = spacedLines;
} else if (currentSettings.lineSpacing === 'double') {
const doubleLines = [];
lines.forEach(line => {
doubleLines.push(line);
doubleLines.push('');
doubleLines.push('');
});
lines = doubleLines;
}
// Apply alignment
const maxWidth = Math.max(...lines.map(line => line.length));
if (currentSettings.alignment === 'center') {
lines = lines.map(line => {
const padding = Math.max(0, Math.floor((maxWidth - line.length) / 2));
return ' '.repeat(padding) + line;
});
} else if (currentSettings.alignment === 'right') {
lines = lines.map(line => {
const padding = Math.max(0, maxWidth - line.length);
return ' '.repeat(padding) + line;
});
}
// Apply border
if (currentSettings.borderStyle !== 'none') {
lines = addBorder(lines, currentSettings.borderStyle);
}
return lines.join('\n');
}
function addBorder(lines, borderStyle) {
const maxWidth = Math.max(...lines.map(line => line.length));
const paddedLines = lines.map(line => line + ' '.repeat(maxWidth - line.length));
let borderChars;
switch (borderStyle) {
case 'simple':
borderChars = { h: '-', v: '|', tl: '+', tr: '+', bl: '+', br: '+' };
break;
case 'double':
borderChars = { h: '═', v: '║', tl: '╔', tr: '╗', bl: '╚', br: '╝' };
break;
case 'rounded':
borderChars = { h: '─', v: '│', tl: '╭', tr: '╮', bl: '╰', br: '╯' };
break;
case 'thick':
borderChars = { h: '━', v: '┃', tl: '┏', tr: '┓', bl: '┗', br: '┛' };
break;
default:
return lines;
}
const topBorder = borderChars.tl + borderChars.h.repeat(maxWidth + 2) + borderChars.tr;
const bottomBorder = borderChars.bl + borderChars.h.repeat(maxWidth + 2) + borderChars.br;
const borderedLines = [topBorder];
paddedLines.forEach(line => {
borderedLines.push(borderChars.v + ' ' + line + ' ' + borderChars.v);
});
borderedLines.push(bottomBorder);
return borderedLines;
}
// Copy ASCII art to clipboard
async function copyASCIIArt() {
try {
await navigator.clipboard.writeText(currentASCIIArt);
showNotification('ASCII Art Copied Successfully!');
} catch (err) {
console.error('Failed to copy: ', err);
// Fallback method for older browsers
const textArea = document.createElement('textarea');
textArea.value = currentASCIIArt;
document.body.appendChild(textArea);
textArea.select();
try {
document.execCommand('copy');
showNotification('ASCII Art Copied Successfully!');
} catch (fallbackErr) {
showNotification('Copy Failed - Please manually select and copy');
}
document.body.removeChild(textArea);
}
}
// Show notification
function showNotification(message) {
// Remove existing notification
const existingNotification = document.querySelector('.ascii-notification');
if (existingNotification) {
existingNotification.remove();
}
// Create new notification
const notification = document.createElement('div');
notification.className = 'ascii-notification';
notification.innerHTML = `
${message}
`;
document.body.appendChild(notification);
// Show notification
setTimeout(() => {
notification.classList.add('show');
}, 50);
// Hide notification after 3 seconds
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 400);
}, 3000);
}
// Update character counter
function updateCharCounter() {
const length = asciiInputText.value.length;
const maxLength = 50;
asciiCharCounter.textContent = `${length} / ${maxLength} characters`;
if (length > 40) {
asciiCharCounter.className = 'ascii-char-counter warning';
} else if (length > 45) {
asciiCharCounter.className = 'ascii-char-counter error';
} else {
asciiCharCounter.className = 'ascii-char-counter';
}
}
// Event listeners
asciiInputText.addEventListener('input', (e) => {
updateCharCounter();
generateLivePreview();
});
asciiInputText.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
e.preventDefault();
generateLivePreview();
}
});
// Keyboard shortcuts
document.addEventListener('keydown', function(e) {
if (e.ctrlKey) {
switch (e.key) {
case 'Enter':
e.preventDefault();
generateLivePreview();
break;
case 's':
e.preventDefault();
saveSettings();
break;
}
}
});
// Initialize
document.addEventListener('DOMContentLoaded', () => {
updateCharCounter();
updateFontPreview();
// Load favorite font if available
const favoriteFont = localStorage.getItem('favoriteFont');
if (favoriteFont && asciiStyles[favoriteFont]) {
asciiFontSelect.value = favoriteFont;
currentSettings.font = favoriteFont;
updateFontPreview();
}
});