feat(comparisonStore): add checkFontsLoading method to improve isLoading flag
This commit is contained in:
@@ -34,6 +34,7 @@ class ComparisonStore {
|
|||||||
#fontB = $state<UnifiedFont | undefined>();
|
#fontB = $state<UnifiedFont | undefined>();
|
||||||
#sampleText = $state('The quick brown fox jumps over the lazy dog');
|
#sampleText = $state('The quick brown fox jumps over the lazy dog');
|
||||||
#isRestoring = $state(true);
|
#isRestoring = $state(true);
|
||||||
|
#fontsReady = $state(false);
|
||||||
#typography = createTypographyControlManager(DEFAULT_TYPOGRAPHY_CONTROLS_DATA, 'glyphdiff:comparison:typography');
|
#typography = createTypographyControlManager(DEFAULT_TYPOGRAPHY_CONTROLS_DATA, 'glyphdiff:comparison:typography');
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -49,6 +50,7 @@ class ComparisonStore {
|
|||||||
|
|
||||||
// If we already have a selection, do nothing
|
// If we already have a selection, do nothing
|
||||||
if (this.#fontA && this.#fontB) {
|
if (this.#fontA && this.#fontB) {
|
||||||
|
this.#checkFontsLoaded();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,6 +68,48 @@ class ComparisonStore {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if fonts are actually loaded in the browser at current weight.
|
||||||
|
* Uses CSS Font Loading API to prevent FOUT.
|
||||||
|
*/
|
||||||
|
async #checkFontsLoaded() {
|
||||||
|
if (!('fonts' in document)) {
|
||||||
|
this.#fontsReady = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.#fontsReady = false;
|
||||||
|
|
||||||
|
const weight = this.#typography.weight;
|
||||||
|
const size = this.#typography.renderedSize;
|
||||||
|
const fontAName = this.#fontA?.name;
|
||||||
|
const fontBName = this.#fontB?.name;
|
||||||
|
|
||||||
|
if (!fontAName || !fontBName) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Step 1: Load fonts into memory
|
||||||
|
await Promise.all([
|
||||||
|
document.fonts.load(`${weight} ${size}px "${fontAName}"`),
|
||||||
|
document.fonts.load(`${weight} ${size}px "${fontBName}"`),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Step 2: Wait for browser to be ready to render
|
||||||
|
await document.fonts.ready;
|
||||||
|
|
||||||
|
// Step 3: Force a layout/paint cycle (critical!)
|
||||||
|
await new Promise(resolve => {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
requestAnimationFrame(resolve); // Double rAF ensures paint completes
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.#fontsReady = true;
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[ComparisonStore] Font loading failed:', error);
|
||||||
|
setTimeout(() => this.#fontsReady = true, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Restore state from persistent storage
|
* Restore state from persistent storage
|
||||||
*/
|
*/
|
||||||
@@ -141,13 +185,12 @@ class ComparisonStore {
|
|||||||
* Check if both fonts are selected
|
* Check if both fonts are selected
|
||||||
*/
|
*/
|
||||||
get isReady() {
|
get isReady() {
|
||||||
return !!this.#fontA && !!this.#fontB;
|
return !!this.#fontA && !!this.#fontB && this.#fontsReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
get isLoading() {
|
get isLoading() {
|
||||||
return this.#isRestoring;
|
return this.#isRestoring || !this.#fontsReady;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Public initializer (optional, as constructor starts it)
|
* Public initializer (optional, as constructor starts it)
|
||||||
* Kept for compatibility if manual re-init is needed
|
* Kept for compatibility if manual re-init is needed
|
||||||
|
|||||||
Reference in New Issue
Block a user