PC

한글 닉네임 생성기

zzs 2024. 10. 9. 02:54
728x90
한글 닉네임 생성기

한글 닉네임 생성기

여기에 닉네임이 나타납니다.

 

index.html
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>한글 닉네임 생성기</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>한글 닉네임 생성기</h1>
        
        <div class="input-group">
            <label for="prefix">앞에 추가할 문자:</label>
            <input type="text" id="prefix" maxlength="5">
        </div>
        
        <div class="input-group">
            <label for="suffix">뒤에 추가할 문자:</label>
            <input type="text" id="suffix" maxlength="5">
        </div>
        
        <div class="input-group">
            <label for="length">닉네임 길이 (2-20):</label>
            <input type="number" id="length" min="2" max="20" value="5">
        </div>
        
        <div class="input-group">
            <label for="maxBatchim">받침 최대 갯수:</label>
            <input type="number" id="maxBatchim" min="0" max="2" value="1">
        </div>
        
        <div class="input-group">
            <input type="checkbox" id="includeDoubleConsonants" checked>
            <label for="includeDoubleConsonants">쌍자음 포함</label>
        </div>
        
        <div class="input-group">
            <input type="checkbox" id="includeDoubleVowels" checked>
            <label for="includeDoubleVowels">쌍모음 포함</label>
        </div>
        
        <button id="generateBtn">닉네임 생성</button>
        <button id="copyBtn">닉네임 복사</button>
        
        <div id="result">여기에 닉네임이 나타납니다.</div>
    </div>

    <script src="script.js"></script>
</body>
</html>

 

styles.css
/* styles.css */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    background-color: #f4f4f9;
    margin: 0;
}

.container {
    text-align: center;
    padding: 20px;
    background-color: #fff;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
    max-width: 400px;
    width: 90%;
}

h1 {
    margin-bottom: 20px;
    font-size: 1.8rem;
    font-weight: 700;
    color: #333;
}

.input-group {
    margin: 10px 0;
}

label {
    display: block;
    margin-bottom: 5px;
    font-size: 1rem;
    color: #555;
}

input[type="text"],
input[type="number"] {
    width: 100%;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    font-size: 1rem;
}

input[type="checkbox"] {
    margin-right: 10px;
    transform: scale(1.2);
}

button {
    width: 100%;
    padding: 15px;
    font-size: 1.2rem;
    background-color: #007BFF;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    margin: 10px 0; /* 간격 추가 */
    transition: background-color 0.3s ease;
}

button:hover {
    background-color: #0056b3;
}

#result {
    margin-top: 20px;
    font-size: 1.5rem;
    font-weight: bold;
    color: #222;
}

@media (max-width: 600px) {
    h1 {
        font-size: 1.5rem;
    }

    input, button {
        font-size: 0.9rem;
    }

    #result {
        font-size: 1.2rem;
    }
}

 

script.js
document.getElementById('generateBtn').addEventListener('click', generateNickname);
document.getElementById('copyBtn').addEventListener('click', copyToClipboard);

// 표준 초성 (초성의 유니코드 순서대로)
const allInitialConsonants = ['ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'];

// 표준 중성 (모음의 유니코드 순서대로)
const allVowels = ['ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'];

// 초기 자음 (초성) 배열
const initialConsonantsSingle = ['ㄱ', 'ㄴ', 'ㄷ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅅ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'];
const initialConsonantsDouble = ['ㄲ', 'ㄸ', 'ㅃ', 'ㅆ', 'ㅉ'];

// 중성 (모음) 배열
const vowelsSingle = ['ㅏ', 'ㅐ', 'ㅑ', 'ㅓ', 'ㅔ', 'ㅕ', 'ㅗ', 'ㅘ', 'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ', 'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ', 'ㅣ'];
const vowelsDouble = ['ㅖ', 'ㅒ']; // 추가된 쌍모음

// 종성 (받침) 배열
const finalConsonants = ['', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ', 'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ', 'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'];

// 종성 개수를 세기 위한 매핑
const finalConsonantsSingle = ['', 'ㄱ', 'ㄴ', 'ㄷ', 'ㄹ', 'ㅁ', 'ㅂ', 'ㅅ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ'];
const finalConsonantsDouble = ['ㄲ', 'ㄳ', 'ㄵ', 'ㄶ', 'ㄺ', 'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ', 'ㅀ', 'ㅄ', 'ㅆ'];

function generateNickname() {
    const prefix = document.getElementById('prefix').value;
    const suffix = document.getElementById('suffix').value;
    const length = parseInt(document.getElementById('length').value);
    const maxBatchim = parseInt(document.getElementById('maxBatchim').value); // 받침 최대 갯수
    const includeDoubleConsonants = document.getElementById('includeDoubleConsonants').checked;
    const includeDoubleVowels = document.getElementById('includeDoubleVowels').checked;

    if (prefix.length + suffix.length > length) {
        alert('접두사와 접미사의 길이가 전체 닉네임 길이를 초과합니다.');
        return;
    }

    // 초기 자음과 중성 자음 배열 구성
    let allowedInitialConsonants = [...initialConsonantsSingle];
    if (includeDoubleConsonants) {
        allowedInitialConsonants = allowedInitialConsonants.concat(initialConsonantsDouble);
    }

    let allowedVowels = [...vowelsSingle];
    if (includeDoubleVowels) {
        allowedVowels = allowedVowels.concat(vowelsDouble);
    }

    // 종성 배열 구성
    let allowedFinalConsonants = [...finalConsonantsSingle];
    if (includeDoubleConsonants) {
        allowedFinalConsonants = allowedFinalConsonants.concat(finalConsonantsDouble);
    }

    let randomName = '';

    // 랜덤 한글 조합 생성 (length에서 prefix와 suffix 길이를 뺀 값만큼)
    const syllableCount = length - (prefix.length + suffix.length);
    for (let i = 0; i < syllableCount; i++) {
        let randomChar = generateHangulWithBatchimLimit(maxBatchim, allowedInitialConsonants, allowedVowels, allowedFinalConsonants);
        randomName += randomChar;
    }

    const finalName = prefix + randomName + suffix;

    document.getElementById('result').textContent = finalName;
}

function generateHangulWithBatchimLimit(maxBatchim, allowedInitialConsonants, allowedVowels, allowedFinalConsonants) {
    let syllable;
    let attempts = 0;
    const maxAttempts = 1000; // 무한 루프 방지를 위한 시도 횟수 제한

    do {
        // 랜덤 초성 선택
        const initialChar = allowedInitialConsonants[Math.floor(Math.random() * allowedInitialConsonants.length)];
        // 랜덤 중성 선택
        const vowelChar = allowedVowels[Math.floor(Math.random() * allowedVowels.length)];
        // 랜덤 종성 선택
        const finalConsonant = allowedFinalConsonants[Math.floor(Math.random() * allowedFinalConsonants.length)];

        // 표준 초성 및 중성 인덱스 찾기
        const initialIndex = allInitialConsonants.indexOf(initialChar);
        const vowelIndex = allVowels.indexOf(vowelChar);
        const finalIndex = finalConsonants.indexOf(finalConsonant);

        // 유효성 검사
        if (initialIndex === -1 || vowelIndex === -1 || finalIndex === -1) {
            continue; // 유효하지 않은 선택일 경우 건너뜀
        }

        // 음절 조립
        const syllableCode = 0xAC00 + (initialIndex * 21 + vowelIndex) * 28 + finalIndex;
        syllable = String.fromCharCode(syllableCode);

        attempts++;
        if (attempts > maxAttempts) {
            console.error('종성 제한에 맞는 음절을 찾을 수 없습니다.');
            return '가'; // 기본 음절 반환
        }
    } while (getBatchimCount(syllable) > maxBatchim);

    return syllable;
}

function getBatchimCount(char) {
    const hangulBase = 0xAC00;
    const charCode = char.charCodeAt(0) - hangulBase;

    if (charCode < 0 || charCode >= 11172) { // 한글 음절 범위 체크
        return 0;
    }

    const jongIndex = charCode % 28;
    const finalConsonant = finalConsonants[jongIndex];

    if (!finalConsonant) {
        return 0;
    }

    if (finalConsonantsDouble.includes(finalConsonant)) {
        return 2;
    }

    return 1;
}

function copyToClipboard() {
    const resultText = document.getElementById('result').textContent;

    if (resultText) {
        const tempTextarea = document.createElement('textarea');
        tempTextarea.value = resultText;
        document.body.appendChild(tempTextarea);

        tempTextarea.select();
        document.execCommand('copy');

        document.body.removeChild(tempTextarea);

        alert('닉네임이 클립보드에 복사되었습니다.');
    } else {
        alert('복사할 닉네임이 없습니다.');
    }
}
728x90