glitchcraft/app/zalgo.js

301 lines
7.7 KiB
JavaScript
Raw Normal View History

/**
* Zalgo Text Generator
* Generates corrupted/glitched text using Unicode combining characters
*/
/* exported ZalgoGenerator */
/* eslint-disable-next-line no-unused-vars */
class ZalgoGenerator {
constructor() {
// Combining diacritical marks that appear above characters
this.above = [
'\u0300',
'\u0301',
'\u0302',
'\u0303',
'\u0304',
'\u0305',
'\u0306',
'\u0307',
'\u0308',
'\u0309',
'\u030A',
'\u030B',
'\u030C',
'\u030D',
'\u030E',
'\u030F',
'\u0310',
'\u0311',
'\u0312',
'\u0313',
'\u0314',
'\u0315',
'\u0316',
'\u0317',
'\u0318',
'\u0319',
'\u031A',
'\u031B',
'\u031C',
'\u031D',
'\u031E',
'\u031F',
'\u0320',
'\u0321',
'\u0322',
'\u0323',
'\u0324',
'\u0325',
'\u0326',
'\u0327',
'\u0328',
'\u0329',
'\u032A',
'\u032B',
'\u032C',
'\u032D',
'\u032E',
'\u032F',
'\u0330',
'\u0331',
'\u0332',
'\u0333',
'\u0334',
'\u0335',
'\u0336',
'\u0337',
'\u0338',
'\u0339',
'\u033A',
'\u033B',
'\u033C',
'\u033D',
'\u033E',
'\u033F',
'\u0340',
'\u0341',
'\u0342',
'\u0343',
'\u0344',
'\u0345',
'\u0346',
'\u0347',
'\u0348',
'\u0349',
'\u034A',
'\u034B',
'\u034C',
'\u034D',
'\u034E',
'\u034F',
'\u0350',
'\u0351',
'\u0352',
'\u0353',
'\u0354',
'\u0355',
'\u0356',
'\u0357',
'\u0358',
'\u0359',
'\u035A',
'\u035B',
'\u035C',
'\u035D',
'\u035E',
'\u035F',
'\u0360',
'\u0361',
'\u0362',
'\u0363',
'\u0364',
'\u0365',
'\u0366',
'\u0367',
'\u0368',
'\u0369',
'\u036A',
'\u036B',
'\u036C',
'\u036D',
'\u036E',
'\u036F',
];
// Combining diacritical marks that appear in the middle
this.middle = [
'\u0315',
'\u031B',
'\u0340',
'\u0341',
'\u0358',
'\u0321',
'\u0322',
'\u0327',
'\u0328',
'\u0334',
'\u0335',
'\u0336',
'\u034F',
'\u035C',
'\u035D',
'\u035E',
'\u035F',
'\u0360',
'\u0362',
'\u0338',
'\u0337',
'\u0361',
'\u0489',
];
// Combining diacritical marks that appear below characters
this.below = [
'\u0316',
'\u0317',
'\u0318',
'\u0319',
'\u031C',
'\u031D',
'\u031E',
'\u031F',
'\u0320',
'\u0324',
'\u0325',
'\u0326',
'\u0329',
'\u032A',
'\u032B',
'\u032C',
'\u032D',
'\u032E',
'\u032F',
'\u0330',
'\u0331',
'\u0332',
'\u0333',
'\u0339',
'\u033A',
'\u033B',
'\u033C',
'\u0345',
'\u0347',
'\u0348',
'\u0349',
'\u034D',
'\u034E',
'\u0353',
'\u0354',
'\u0355',
'\u0356',
'\u0359',
'\u035A',
'\u0323',
];
}
/**
* Get a random character from an array
*/
randomChar(array) {
return array[Math.floor(Math.random() * array.length)];
}
/**
* Generate a specified number of random characters from an array
*/
randomChars(array, count) {
let result = '';
for (let i = 0; i < count; i++) {
result += this.randomChar(array);
}
return result;
}
/**
* Generate zalgo text with specified intensity and mode
* @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') {
if (!text) return '';
// Normalize intensity to 1-10 range
intensity = Math.max(1, Math.min(10, intensity));
let result = '';
for (let char of text) {
result += char;
// Skip whitespace and newlines
if (/\s/.test(char)) {
continue;
}
// Calculate how many combining characters to add based on intensity and mode
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
result += this.randomChars(this.above, aboveCount);
result += this.randomChars(this.middle, middleCount);
result += this.randomChars(this.below, belowCount);
}
return result;
}
/**
* Remove zalgo corruption from text
* @param {string} text - The corrupted text
* @returns {string} - Clean text without combining characters
*/
clean(text) {
// Remove all combining characters (Unicode category Mn)
return text.replace(/[\u0300-\u036f\u0489]/g, '');
}
}