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();
});
|