diff --git a/packages/assets/src/loader/parsers/loadWebFont.ts b/packages/assets/src/loader/parsers/loadWebFont.ts index 51c0d19289..f711dafef5 100644 --- a/packages/assets/src/loader/parsers/loadWebFont.ts +++ b/packages/assets/src/loader/parsers/loadWebFont.ts @@ -1,13 +1,22 @@ import { extensions, ExtensionType, settings, utils } from '@pixi/core'; +import { checkDataUrl } from '../../utils/checkDataUrl'; +import { checkExtension } from '../../utils/checkExtension'; import { LoaderParserPriority } from './LoaderParser'; import type { LoadAsset } from '../types'; import type { LoaderParser } from './LoaderParser'; -const validWeights = ['normal', 'bold', +const validWeights = [ + 'normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900', ]; -const validFonts = ['woff', 'woff2', 'ttf', 'otf']; +const validFontExtensions = ['.ttf', '.otf', '.woff', '.woff2']; +const validFontMIMEs = [ + 'font/ttf', + 'font/otf', + 'font/woff', + 'font/woff2', +]; export type LoadFontData = { family: string; @@ -51,10 +60,7 @@ export const loadWebFont = { test(url: string): boolean { - const tempURL = url.split('?')[0]; - const extension = tempURL.split('.').pop(); - - return validFonts.includes(extension); + return checkDataUrl(url, validFontMIMEs) || checkExtension(url, validFontExtensions); }, async load(url: string, options?: LoadAsset): Promise diff --git a/packages/assets/src/loader/parsers/textures/loadTexture.ts b/packages/assets/src/loader/parsers/textures/loadTexture.ts index 72fd780521..4ba9a30999 100644 --- a/packages/assets/src/loader/parsers/textures/loadTexture.ts +++ b/packages/assets/src/loader/parsers/textures/loadTexture.ts @@ -1,7 +1,8 @@ import { BaseTexture, extensions, ExtensionType, settings, utils } from '@pixi/core'; +import { checkDataUrl } from '../../../utils/checkDataUrl'; +import { checkExtension } from '../../../utils/checkExtension'; import { LoaderParserPriority } from '../LoaderParser'; import { WorkerManager } from '../WorkerManager'; -import { checkExtension } from './utils/checkExtension'; import { createTexture } from './utils/createTexture'; import type { IBaseTextureOptions, Texture } from '@pixi/core'; @@ -9,7 +10,13 @@ import type { Loader } from '../../Loader'; import type { LoadAsset } from '../../types'; import type { LoaderParser } from '../LoaderParser'; -const validImages = ['.jpg', '.png', '.jpeg', '.avif', '.webp']; +const validImageExtensions = ['.jpeg', '.jpg', '.png', '.webp', '.avif']; +const validImageMIMEs = [ + 'image/jpeg', + 'image/png', + 'image/webp', + 'image/avif', +]; /** * Returns a promise that resolves an ImageBitmaps. @@ -51,18 +58,7 @@ export const loadTextures = { test(url: string): boolean { - let isValidBase64Suffix = false; - - for (let i = 0; i < validImages.length; i++) - { - if (url.startsWith(`data:image/${validImages[i].slice(1)}`)) - { - isValidBase64Suffix = true; - break; - } - } - - return isValidBase64Suffix || checkExtension(url, validImages); + return checkDataUrl(url, validImageMIMEs) || checkExtension(url, validImageExtensions); }, async load(url: string, asset: LoadAsset, loader: Loader): Promise diff --git a/packages/assets/src/loader/parsers/textures/utils/index.ts b/packages/assets/src/loader/parsers/textures/utils/index.ts index 330853232e..3240e67946 100644 --- a/packages/assets/src/loader/parsers/textures/utils/index.ts +++ b/packages/assets/src/loader/parsers/textures/utils/index.ts @@ -1,2 +1 @@ -export * from './checkExtension'; export * from './createTexture'; diff --git a/packages/assets/src/utils/checkDataUrl.ts b/packages/assets/src/utils/checkDataUrl.ts new file mode 100644 index 0000000000..392b496cbe --- /dev/null +++ b/packages/assets/src/utils/checkDataUrl.ts @@ -0,0 +1,14 @@ +export function checkDataUrl(url: string, mimes: string | string[]): boolean +{ + if (Array.isArray(mimes)) + { + for (const mime of mimes) + { + if (url.startsWith(`data:${mime}`)) return true; + } + + return false; + } + + return url.startsWith(`data:${mimes}`); +} diff --git a/packages/assets/src/loader/parsers/textures/utils/checkExtension.ts b/packages/assets/src/utils/checkExtension.ts similarity index 100% rename from packages/assets/src/loader/parsers/textures/utils/checkExtension.ts rename to packages/assets/src/utils/checkExtension.ts diff --git a/packages/assets/src/utils/index.ts b/packages/assets/src/utils/index.ts index e6ab887292..8d2cc28980 100644 --- a/packages/assets/src/utils/index.ts +++ b/packages/assets/src/utils/index.ts @@ -1,3 +1,5 @@ +export * from './checkDataUrl'; +export * from './checkExtension'; export * from './convertToList'; export * from './createStringVariations'; export * from './isSingleItem'; diff --git a/packages/assets/test/assets.tests.ts b/packages/assets/test/assets.tests.ts index dd3353e91c..43d39b9909 100644 --- a/packages/assets/test/assets.tests.ts +++ b/packages/assets/test/assets.tests.ts @@ -334,30 +334,29 @@ describe('Assets', () => expect(assets.bunny.baseTexture).toBe(null); }); - it('should load PNG base64 assets', async () => + it('should load PNG assets from data URL', async () => { - // Other formats (JPG, JPEG, WEBP, AVIF) can be added similarly. - let bunnyBase64 = ` - data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhIB8c - Hh4jJzIqIyUvJR4eKzssLzM1ODg4ISo9QTw2QTI3ODX/2wBDAQkKCg0LDRkODhk1JB4kNTU1NTU1NTU1NTU1NTU1NTU1NTU1NT - U1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTX/wgARCAAlABoDAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABgUHBP/E - ABkBAAMBAQEAAAAAAAAAAAAAAAIDBAUBBv/aAAwDAQACEAMQAAAAfoMjG9G5byxWYwUHfPaNTTmebMAqZ1zJphvFntQwkNP49f - dWrUdeIEs1xcBAWmGH/8QANRAAAQMCBAQDAg8AAAAAAAAAAgEDBAURAAYSEwcUIWEQFSIxUjI0NkJFVFVicXWBoqTCw//aAAgB - AQABPwDiRsHGobM3rBfqoBKb+abaNOlYk/Eb4qz8Cmee0mhjsQpnJIwywC7J6XV5nsl27It/h4y6xSIHEFlnLjLLEN+mPG8DCa - BMxcZ037oh+Gd810nMgQIlIkrKciTleds0aBoRp0LoappLqSexcMsTtp0xjPSmWiu6+KtiLaGSoKKikirbsmMpVFqhV2NLqLjp - gEN5g3WoxuKpkTCp6ARVS+2eEz7lv7bgB9x19AMeyivVFxxGyrScswoE6jxliPvz9o7PHo0K06VkBV0j1HFAybCqFGalSTdU3e - vpW1sUygRJ+fjo07dditRX3LA8bSqYG0KLcFRfYZYHIGWg+g4B93GdZfqS9Vxxk+T9J/M/8H8QuKjNBY5BX4jmz7xpcMZCqPm3 - EMZmtHN+myTund1jw4zhbIwzvqEsH9Hv3Qm/74oFO8oy5TqfubvKRWmNdratIoN7YyRTdji/mj1/E9f8lxHv228P/8QAHxEAAg - IDAAMBAQAAAAAAAAAAAQIAAwQREgUQIRRR/9oACAECAQE/AL2CoWJi5VfJJaY1osJ0dzqZ1qikgwVJYpcHWp426sM4Hydj+zMr - U0kzGwBbV0TPHY6qz7nCzL+0tqUfqRNBfk8cGBfv1YNrqARF0xPr/8QAHhEAAgICAwEBAAAAAAAAAAAAAQIAAxESBBAhMTL/2g - AIAQMBAT8AQEnAgqckSxWA9646HfML6kLOUjEAzQyh23xLeQVbAl9hKjE3Mp/Yli1M32cnGAB0h9hhPnX/2Q== + // Other formats (JPEG, WEBP, AVIF) can be added similarly. + let bunnyDataURL = ` + data:image/png;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhIB8cHh + 4jJzIqIyUvJR4eKzssLzM1ODg4ISo9QTw2QTI3ODX/2wBDAQkKCg0LDRkODhk1JB4kNTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NT + U1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTX/wgARCAAlABoDAREAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABgUHBP/EABkBAA + MBAQEAAAAAAAAAAAAAAAIDBAUBBv/aAAwDAQACEAMQAAAAfoMjG9G5byxWYwUHfPaNTTmebMAqZ1zJphvFntQwkNP49fdWrUdeIE + s1xcBAWmGH/8QANRAAAQMCBAQDAg8AAAAAAAAAAgEDBAURAAYSEwcUIWEQFSIxUjI0NkJFVFVicXWBoqTCw//aAAgBAQABPwDiRs + HGobM3rBfqoBKb+abaNOlYk/Eb4qz8Cmee0mhjsQpnJIwywC7J6XV5nsl27It/h4y6xSIHEFlnLjLLEN+mPG8DCaBMxcZ037oh+G + d810nMgQIlIkrKciTleds0aBoRp0LoappLqSexcMsTtp0xjPSmWiu6+KtiLaGSoKKikirbsmMpVFqhV2NLqLjpgEN5g3WoxuKpkT + Cp6ARVS+2eEz7lv7bgB9x19AMeyivVFxxGyrScswoE6jxliPvz9o7PHo0K06VkBV0j1HFAybCqFGalSTdU3evpW1sUygRJ+fjo07 + dditRX3LA8bSqYG0KLcFRfYZYHIGWg+g4B93GdZfqS9Vxxk+T9J/M/8H8QuKjNBY5BX4jmz7xpcMZCqPm3EMZmtHN+myTund1jw4 + zhbIwzvqEsH9Hv3Qm/74oFO8oy5TqfubvKRWmNdratIoN7YyRTdji/mj1/E9f8lxHv228P/8QAHxEAAgIDAAMBAQAAAAAAAAAAAQ + IAAwQREgUQIRRR/9oACAECAQE/AL2CoWJi5VfJJaY1osJ0dzqZ1qikgwVJYpcHWp426sM4Hydj+zMrU0kzGwBbV0TPHY6qz7nCzL + +0tqUfqRNBfk8cGBfv1YNrqARF0xPr/8QAHhEAAgICAwEBAAAAAAAAAAAAAQIAAxESBBAhMTL/2gAIAQMBAT8AQEnAgqckSxWA96 + 46HfML6kLOUjEAzQyh23xLeQVbAl9hKjE3Mp/Yli1M32cnGAB0h9hhPnX/2Q== `; - // to prevent eslint max-len warning - bunnyBase64 = bunnyBase64.replace(/\s/g, ''); + // Prevent eslint max-len warning + bunnyDataURL = bunnyDataURL.replace(/\s/g, ''); - Assets.add('bunny', bunnyBase64); - const bunny = await Assets.load('bunny'); + const bunny = await Assets.load(bunnyDataURL); expect(bunny).toBeInstanceOf(Texture); });