-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfont-loader.js
More file actions
111 lines (97 loc) · 2.74 KB
/
font-loader.js
File metadata and controls
111 lines (97 loc) · 2.74 KB
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
/**
* Lazy load fonts using the FontFace API and IntersectionObserver.
* @author Andreas Nymark <andreas@nymark.co>
* @license MIT
* @version 1.2.0
* @link https://github.com/andreasnymark/font-loader
*/
export const config = Object.assign( {
eagerSelector: '[data-font-load="eager"]',
lazySelector: '[data-font-load="lazy"]',
metadataSelector: '#font-metadata',
fontsLoadedClass: 'fonts-loaded',
fontLoadedClass: 'font-loaded',
rootMargin: '300px',
threshold: 0,
applyFont: false,
}, window.FontLoaderConfig || {} );
const metadataElement = document.querySelector( config.metadataSelector );
if ( ! metadataElement ) {
console.warn( 'font-metadata element not found, font loading disabled' );
}
let fontMetadata = {};
if ( metadataElement ) {
try {
fontMetadata = JSON.parse( metadataElement.textContent );
} catch ( err ) {
console.error( 'Failed to parse font metadata:', err );
}
}
const fontLoadPromises = new Map();
export function loadFont( fontFamily ) {
if ( fontLoadPromises.has( fontFamily ) ) {
return fontLoadPromises.get( fontFamily );
}
const fontData = fontMetadata[ fontFamily ];
if ( ! fontData ) {
console.warn( 'Font not found:', fontFamily );
return Promise.resolve();
}
const promise = new FontFace(
fontData.family,
`url(${fontData.url})`,
{
weight: fontData.weight || 'normal',
style: fontData.style || 'normal',
stretch: fontData.stretch || 'normal',
}
)
.load()
.then( loadedFace => {
document.fonts.add( loadedFace );
})
.catch( err => {
console.error( 'Failed to load font:', fontData.name, err );
});
fontLoadPromises.set( fontFamily, promise );
return promise;
}
const previewObserver = new IntersectionObserver(
( entries ) => {
entries.forEach( entry => {
if ( entry.isIntersecting ) {
const preview = entry.target;
const fontFamily = preview.dataset.fontFamily;
if ( fontFamily ) {
loadFont( fontFamily ).then( () => {
preview.classList.add( config.fontLoadedClass );
if ( config.applyFont ) preview.style.fontFamily = `'${fontFamily}'`;
});
}
previewObserver.unobserve( preview );
}
} );
},{
rootMargin: config.rootMargin,
threshold: config.threshold
}
);
function init() {
document.querySelectorAll( config.eagerSelector ).forEach( preview => {
const fontFamily = preview.dataset.fontFamily;
if ( fontFamily ) {
loadFont( fontFamily ).then( () => {
preview.classList.add( config.fontsLoadedClass );
if ( config.applyFont ) preview.style.fontFamily = `'${fontFamily}'`;
});
}
});
document.querySelectorAll( config.lazySelector ).forEach( preview => {
previewObserver.observe( preview );
});
}
if ( document.readyState === 'loading' ) {
document.addEventListener( 'DOMContentLoaded', init );
} else {
init();
}