File size: 5,799 Bytes
3ed48fd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import { applyEffect, getAvailableEffects } from './effects.js';

// フォントの読み込みを管理する関数
async function loadGoogleFont(fontFamily) {
    // フォントファミリー名を正しく整形
    const formattedFamily = fontFamily.replace(/ /g, '+');
    
    // Google Fonts APIのURLを構築
    const url = `https://fonts.googleapis.com/css2?family=${formattedFamily}&display=swap`;
    
    // 既存のリンクタグがあれば削除
    const existingLink = document.querySelector(`link[href*="${formattedFamily}"]`);
    if (existingLink) {
        existingLink.remove();
    }

    // 新しいリンクタグを追加
    const link = document.createElement('link');
    link.href = url;
    link.rel = 'stylesheet';
    document.head.appendChild(link);

    // フォントの読み込みを待つ
    await new Promise((resolve, reject) => {
        link.onload = async () => {
            try {
                // フォントの読み込みを確認
                await document.fonts.load(`16px "${fontFamily}"`);
                // 少し待機して確実にフォントを利用可能にする
                setTimeout(resolve, 100);
            } catch (error) {
                reject(error);
            }
        };
        link.onerror = reject;
    });
}

// テキストを画像に変換する関数を更新
async function textToImage(text, fontFamily, fontSize = '48px', effectType = 'simple') {
    console.debug(`テキスト描画開始: ${effectType}`, { text, fontFamily, fontSize });
    try {
        await document.fonts.load(`${fontSize} "${fontFamily}"`);
        const fontSizeNum = parseInt(fontSize);
        const verticalText = document.getElementById('verticalText').checked;
        
        // エフェクトを適用
        const imageUrl = await applyEffect(effectType, text, {
            font: fontFamily,
            fontSize: fontSizeNum,
            vertical: verticalText
        });

        return imageUrl;
    } catch (error) {
        console.error('フォント描画エラー:', error);
        throw error;
    }
}

// デバウンス関数の実装
let renderTimeout = null;
let isRendering = false;

function debounceRender(callback, delay = 200) {
    if (renderTimeout) {
        clearTimeout(renderTimeout);
    }
    
    if (isRendering) {
        return;
    }
    
    renderTimeout = setTimeout(async () => {
        isRendering = true;
        try {
            await callback();
        } finally {
            isRendering = false;
        }
    }, delay);
}

// イベントリスナーの設定を更新
document.addEventListener('DOMContentLoaded', async () => {
    const fontSelect = document.getElementById('googleFontInput');
    const textInput = document.getElementById('textInput');
    const fontSizeInput = document.getElementById('fontSize');
    const verticalTextInput = document.getElementById('verticalText');
    const effectGrid = document.querySelector('.effect-grid');
    
    await loadGoogleFont(fontSelect.value);

    // 縦書きモードの状態をグリッドに反映
    verticalTextInput.addEventListener('change', (e) => {
        effectGrid.dataset.vertical = e.target.checked;
        renderAllPresets();
    });

    // すべてのプリセットを描画する関数
    async function renderAllPresets() {
        effectGrid.innerHTML = '';
        const text = textInput.value || 'プレビュー';
        const fontFamily = fontSelect.value;
        const fontSize = fontSizeInput.value + 'px';

        const effects = getAvailableEffects();
        for (const effect of effects) {
            try {
                const imageUrl = await textToImage(text, fontFamily, fontSize, effect.name);
                
                const presetCard = document.createElement('div');
                presetCard.className = 'effect-item';
                presetCard.innerHTML = `

                    <div class="effect-name">${effect.name}</div>

                    <div class="preview-container">

                        <img src="${imageUrl}" alt="${effect.name}">

                    </div>

                `;
                
                effectGrid.appendChild(presetCard);
            } catch (error) {
                console.error(`プリセット ${effect.name} の描画エラー:`, error);
                
                const errorCard = document.createElement('div');
                errorCard.className = 'effect-item error';
                errorCard.innerHTML = `

                    <div class="effect-name text-danger">${effect.name}</div>

                    <div class="preview-container">

                        <div class="text-danger">

                            <small>エラー: ${error.message}</small>

                        </div>

                    </div>

                `;
                effectGrid.appendChild(errorCard);
            }
        }
    }

    // フォント変更時の処理
    fontSelect.addEventListener('change', async (e) => {
        try {
            const fontFamily = e.target.value;
            await loadGoogleFont(fontFamily);
            await renderAllPresets();
        } catch (error) {
            console.error('フォント読み込みエラー:', error);
        }
    });
    
    // テキストとフォントサイズの変更時にすべてのプリセットを再描画
    [textInput, fontSizeInput, verticalTextInput].forEach(element => {
        element.addEventListener('input', () => {
            debounceRender(renderAllPresets);
        });
    });

    // 初期描画
    await renderAllPresets();
});