@hkdigital/lib-core 0.3.11 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -149
- package/dist/assets/autospuiten/car-paint-picker.js +41 -41
- package/dist/assets/autospuiten/labels.js +7 -7
- package/dist/classes/data/IterableTree.js +242 -242
- package/dist/classes/data/Selector.js +190 -190
- package/dist/classes/data/index.js +2 -2
- package/dist/classes/data/typedef.js +9 -9
- package/dist/classes/event-emitter/EventEmitter.js +273 -273
- package/dist/classes/event-emitter/index.js +2 -2
- package/dist/classes/index.js +4 -4
- package/dist/classes/promise/HkPromise.js +384 -384
- package/dist/classes/promise/index.js +1 -1
- package/dist/classes/stores/SubscribersCount.js +107 -107
- package/dist/classes/stores/index.js +1 -1
- package/dist/classes/streams/LogTransformStream.js +19 -19
- package/dist/classes/streams/ServerEventsStore.js +111 -111
- package/dist/classes/streams/TimeStampSource.js +26 -26
- package/dist/classes/streams/index.js +3 -3
- package/dist/classes/svelte/finite-state-machine/FiniteStateMachine.svelte.js +133 -133
- package/dist/classes/svelte/finite-state-machine/index.js +1 -1
- package/dist/classes/svelte/index.js +1 -11
- package/dist/classes/svelte/loading-state-machine/LoadingStateMachine.svelte.js +109 -109
- package/dist/classes/svelte/loading-state-machine/constants.js +16 -16
- package/dist/classes/svelte/loading-state-machine/index.js +3 -3
- package/dist/config/README.md +197 -196
- package/dist/config/generators/imagetools.js +189 -189
- package/dist/config/generators/vite.js +148 -142
- package/dist/config/imagetools.d.ts +72 -72
- package/dist/config/vite.js +4 -4
- package/dist/constants/bases/index.js +13 -13
- package/dist/constants/http/headers.js +6 -6
- package/dist/constants/http/index.js +2 -2
- package/dist/constants/http/methods.js +14 -14
- package/dist/constants/index.js +6 -6
- package/dist/constants/mime/application.js +5 -5
- package/dist/constants/mime/audio.js +13 -13
- package/dist/constants/mime/image.js +3 -3
- package/dist/constants/mime/index.js +4 -4
- package/dist/constants/mime/text.js +2 -2
- package/dist/constants/regexp/README.md +96 -95
- package/dist/constants/regexp/index.js +31 -31
- package/dist/constants/regexp/inspiratie.js__ +95 -95
- package/dist/constants/regexp/text.d.ts +4 -4
- package/dist/constants/regexp/text.js +49 -49
- package/dist/constants/regexp/url.js +3 -3
- package/dist/constants/regexp/user.js +29 -29
- package/dist/constants/states/drag.js +6 -6
- package/dist/constants/states/drop.js +6 -6
- package/dist/constants/states/index.js +4 -4
- package/dist/constants/states/input.js +11 -11
- package/dist/constants/states/submit.js +4 -4
- package/dist/constants/time/index.js +28 -28
- package/dist/css/utilities.css +43 -43
- package/dist/design/README.md +405 -405
- package/dist/design/config/design-config.js +73 -73
- package/dist/design/generators/index.js +288 -288
- package/dist/design/index.js +96 -96
- package/dist/design/plugins/skeleton.js +208 -208
- package/dist/design/tailwind-theme-extend.js +158 -158
- package/dist/design/themes/README.md +102 -102
- package/dist/design/themes/hkdev/components/blocks/text-block.css +34 -34
- package/dist/design/themes/hkdev/components/boxes/game-box.css +11 -11
- package/dist/design/themes/hkdev/components/buttons/button-icon-steeze.css +22 -22
- package/dist/design/themes/hkdev/components/buttons/button-text.css +32 -32
- package/dist/design/themes/hkdev/components/buttons/button.css +146 -146
- package/dist/design/themes/hkdev/components/buttons/skip-button.css +5 -5
- package/dist/design/themes/hkdev/components/drag-drop/draggable.css +73 -73
- package/dist/design/themes/hkdev/components/drag-drop/drop-zone.css +58 -58
- package/dist/design/themes/hkdev/components/icons/icon-steeze.css +15 -15
- package/dist/design/themes/hkdev/components/inputs/text-input.css +102 -102
- package/dist/design/themes/hkdev/components/panels/panel.css +25 -25
- package/dist/design/themes/hkdev/components/rows/panel-grid-row.css +4 -4
- package/dist/design/themes/hkdev/components/rows/panel-row-2.css +5 -5
- package/dist/design/themes/hkdev/components.css +29 -29
- package/dist/design/themes/hkdev/debug.css +1 -1
- package/dist/design/themes/hkdev/global/layout.css +32 -32
- package/dist/design/themes/hkdev/global/on-colors.css +32 -32
- package/dist/design/themes/hkdev/globals.css +3 -3
- package/dist/design/themes/hkdev/responsive.css +12 -12
- package/dist/design/themes/hkdev/theme-ext.js +12 -12
- package/dist/design/themes/hkdev/theme.css +218 -218
- package/dist/design/utils/clamp.js +66 -66
- package/dist/design/utils/root-vars.js +102 -102
- package/dist/design/utils/scaling.js +228 -228
- package/dist/design/utils/states.js +22 -22
- package/dist/errors/api.js +9 -9
- package/dist/errors/generic.js +20 -20
- package/dist/errors/http.js +16 -16
- package/dist/errors/index.js +5 -5
- package/dist/errors/jwt.js +5 -5
- package/dist/errors/promise.js +25 -25
- package/dist/logging/README.md +158 -0
- package/dist/logging/index.d.ts +3 -1
- package/dist/logging/index.js +11 -7
- package/dist/logging/internal/adapters/console.js +114 -114
- package/dist/logging/internal/adapters/index.js +2 -2
- package/dist/logging/internal/adapters/pino.js +160 -142
- package/dist/logging/internal/adapters/typedef.js +10 -10
- package/dist/logging/internal/{unified-logger/constants.js → constants.js} +22 -22
- package/dist/logging/internal/factories/client.d.ts +1 -1
- package/dist/logging/internal/factories/client.js +21 -21
- package/dist/logging/internal/factories/server.d.ts +1 -1
- package/dist/logging/internal/factories/server.js +22 -22
- package/dist/logging/internal/factories/universal.d.ts +2 -2
- package/dist/logging/internal/factories/universal.js +22 -22
- package/dist/logging/internal/{unified-logger → logger}/Logger.d.ts +2 -2
- package/dist/logging/internal/{unified-logger → logger}/Logger.js +217 -217
- package/dist/logging/internal/logger/index.d.ts +1 -0
- package/dist/logging/internal/logger/index.js +1 -0
- package/dist/logging/internal/{unified-logger/typedef.d.ts → typedef.d.ts} +2 -1
- package/dist/logging/internal/{unified-logger/typedef.js → typedef.js} +21 -17
- package/dist/network/README.md +172 -172
- package/dist/network/cache/IndexedDbCache.js +1407 -1407
- package/dist/network/cache/MemoryResponseCache.js +138 -138
- package/dist/network/cache/index.js +5 -5
- package/dist/network/cache/typedef.js +41 -41
- package/dist/network/cache.js +3 -3
- package/dist/network/http/caching.js +261 -261
- package/dist/network/http/errors.js +97 -97
- package/dist/network/http/headers.js +75 -75
- package/dist/network/http/http-request.js +578 -578
- package/dist/network/http/index.js +22 -22
- package/dist/network/http/json-request.js +224 -224
- package/dist/network/http/mocks.js +65 -65
- package/dist/network/http/response.js +318 -318
- package/dist/network/http/test-data__/content-length-test-hkdigital-small.V4HfZyBQ.avif +0 -0
- package/dist/network/http/typedef.js +93 -93
- package/dist/network/http/url.js +52 -52
- package/dist/network/http.js +5 -5
- package/dist/network/loaders/README.md +254 -254
- package/dist/network/loaders/audio/AudioLoader.svelte.js +58 -58
- package/dist/network/loaders/audio/AudioScene.svelte.js +324 -324
- package/dist/network/loaders/audio/mocks.js +35 -35
- package/dist/network/loaders/audio.js +1 -1
- package/dist/network/loaders/image/ImageLoader.svelte.js +44 -44
- package/dist/network/loaders/image/ImageScene.svelte.js +248 -248
- package/dist/network/loaders/image/ImageVariantsLoader.svelte.js +150 -150
- package/dist/network/loaders/image/index.js +4 -4
- package/dist/network/loaders/image/mocks.js +35 -35
- package/dist/network/loaders/image/typedef.js +8 -8
- package/dist/network/loaders/image/utils/index.js +86 -86
- package/dist/network/loaders/image.js +7 -7
- package/dist/network/loaders/typedef.js +38 -38
- package/dist/network/loaders.js +2 -2
- package/dist/network/states/NetworkLoader.svelte.js +338 -338
- package/dist/network/states/constants.js +3 -3
- package/dist/network/states/index.js +3 -3
- package/dist/network/states/mocks.js +30 -30
- package/dist/network/states/typedef.js +8 -8
- package/dist/network/typedef.js +9 -9
- package/dist/services/README.md +200 -0
- package/dist/services/index.d.ts +6 -1
- package/dist/services/index.js +8 -1
- package/dist/services/{internal/service-base → service-base}/ServiceBase.d.ts +2 -2
- package/dist/services/{internal/service-base → service-base}/ServiceBase.js +462 -462
- package/dist/services/{internal/service-base → service-base}/constants.d.ts +0 -12
- package/dist/services/{internal/service-base → service-base}/constants.js +98 -110
- package/dist/services/{internal/service-base → service-base}/index.js +3 -3
- package/dist/services/{internal/service-base → service-base}/typedef.d.ts +1 -1
- package/dist/services/{internal/service-base → service-base}/typedef.js +101 -101
- package/dist/services/{internal/service-manager → service-manager}/ServiceManager.d.ts +2 -2
- package/dist/services/{internal/service-manager → service-manager}/ServiceManager.js +608 -608
- package/dist/services/{internal/service-manager → service-manager}/constants.js +6 -6
- package/dist/services/{internal/service-manager → service-manager}/typedef.js +90 -90
- package/dist/states/index.js +1 -1
- package/dist/states/navigation.svelte.js +55 -55
- package/dist/stores/index.js +1 -1
- package/dist/stores/theme.js +80 -80
- package/dist/typedef/context.js +6 -6
- package/dist/typedef/drag.js +25 -25
- package/dist/typedef/drop.js +12 -12
- package/dist/typedef/index.d.ts +1 -0
- package/dist/typedef/index.js +4 -4
- package/dist/ui/components/button-group/ButtonGroup.svelte +82 -82
- package/dist/ui/components/button-group/typedef.js +10 -10
- package/dist/ui/components/compare-left-right/CompareLeftRight.svelte +179 -179
- package/dist/ui/components/compare-left-right/index.js +1 -1
- package/dist/ui/components/game-box/GameBox.svelte +577 -577
- package/dist/ui/components/game-box/gamebox.util.js +83 -83
- package/dist/ui/components/hk-app-layout/HkAppLayout.state.svelte.js +25 -25
- package/dist/ui/components/hk-app-layout/HkAppLayout.svelte +251 -251
- package/dist/ui/components/image-box/ImageBox.svelte +210 -210
- package/dist/ui/components/image-box/index.js +5 -5
- package/dist/ui/components/image-box/typedef.js +32 -32
- package/dist/ui/components/index.js +23 -23
- package/dist/ui/components/presenter/ImageSlide.svelte +64 -64
- package/dist/ui/components/presenter/Presenter.state.svelte.js +638 -638
- package/dist/ui/components/presenter/Presenter.svelte +142 -142
- package/dist/ui/components/presenter/constants.js +7 -7
- package/dist/ui/components/presenter/index.js +10 -10
- package/dist/ui/components/presenter/typedef.js +106 -106
- package/dist/ui/components/presenter/util.js +210 -210
- package/dist/ui/components/virtual-viewport/VirtualViewport.svelte +196 -196
- package/dist/ui/primitives/area/HkArea.svelte +49 -49
- package/dist/ui/primitives/area/HkGridArea.svelte +77 -77
- package/dist/ui/primitives/area/index.js +2 -2
- package/dist/ui/primitives/buttons/button/Button.svelte +82 -82
- package/dist/ui/primitives/buttons/button-icon-steeze/SteezeIconButton.svelte +30 -30
- package/dist/ui/primitives/buttons/button-text/TextButton.svelte +21 -21
- package/dist/ui/primitives/buttons/index.js +3 -3
- package/dist/ui/primitives/debug/debug-panel-design-scaling/DebugPanelDesignScaling.svelte +146 -146
- package/dist/ui/primitives/debug/index.js +1 -1
- package/dist/ui/primitives/drag-drop/DragController.js +44 -44
- package/dist/ui/primitives/drag-drop/DragDropContext.svelte +111 -111
- package/dist/ui/primitives/drag-drop/Draggable.svelte +519 -519
- package/dist/ui/primitives/drag-drop/DropZone.svelte +258 -258
- package/dist/ui/primitives/drag-drop/DropZoneArea.svelte +119 -119
- package/dist/ui/primitives/drag-drop/DropZoneList.svelte +125 -125
- package/dist/ui/primitives/drag-drop/actions.js +26 -26
- package/dist/ui/primitives/drag-drop/drag-state.svelte.js +322 -322
- package/dist/ui/primitives/drag-drop/index.js +7 -7
- package/dist/ui/primitives/drag-drop/util.js +85 -85
- package/dist/ui/primitives/hkdev/blocks/TextBlock.svelte +46 -46
- package/dist/ui/primitives/hkdev/buttons/CheckButton.svelte +62 -62
- package/dist/ui/primitives/icons/HkIcon.svelte +86 -86
- package/dist/ui/primitives/icons/HkTabIcon.svelte +116 -116
- package/dist/ui/primitives/icons/SteezeIcon.svelte +97 -97
- package/dist/ui/primitives/icons/index.js +6 -6
- package/dist/ui/primitives/icons/typedef.js +16 -16
- package/dist/ui/primitives/index.js +2 -2
- package/dist/ui/primitives/inputs/index.js +1 -1
- package/dist/ui/primitives/inputs/text-input/TestTextInput.svelte__ +102 -0
- package/dist/ui/primitives/inputs/text-input/TextInput.svelte +223 -223
- package/dist/ui/primitives/inputs/text-input/TextInput.svelte___ +83 -0
- package/dist/ui/primitives/inputs/text-input/assets/IconInvalid.svelte +14 -14
- package/dist/ui/primitives/inputs/text-input/assets/IconValid.svelte +12 -12
- package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte +63 -63
- package/dist/ui/primitives/layout/grid-layers/GridLayers.svelte__heightFrom__ +372 -0
- package/dist/ui/primitives/layout/grid-layers/util.js +74 -74
- package/dist/ui/primitives/layout/index.js +1 -1
- package/dist/ui/primitives/panels/index.js +1 -1
- package/dist/ui/primitives/panels/panel/Panel.svelte +43 -43
- package/dist/ui/primitives/rows/index.js +3 -3
- package/dist/ui/primitives/rows/panel-grid-row/PanelGridRow.svelte +104 -104
- package/dist/ui/primitives/rows/panel-row-2/PanelRow2.svelte +40 -40
- package/dist/ui/primitives/tab-bar/HkTabBar.state.svelte.js +149 -149
- package/dist/ui/primitives/tab-bar/HkTabBar.svelte +74 -74
- package/dist/ui/primitives/tab-bar/HkTabBarSelector.state.svelte.js +93 -93
- package/dist/ui/primitives/tab-bar/HkTabBarSelector.svelte +49 -49
- package/dist/ui/primitives/tab-bar/index.js +17 -17
- package/dist/ui/primitives/tab-bar/typedef.js +11 -11
- package/dist/util/array/index.js +436 -436
- package/dist/util/bases/base58.js +262 -262
- package/dist/util/bases/index.js +1 -1
- package/dist/util/compare/index.js +247 -247
- package/dist/util/css/css-vars.js +83 -83
- package/dist/util/css/index.js +1 -1
- package/dist/util/env/index.js +9 -9
- package/dist/util/exceptions/index.d.ts +4 -3
- package/dist/util/exceptions/index.js +26 -23
- package/dist/util/expect/arrays.js +47 -47
- package/dist/util/expect/index.js +259 -259
- package/dist/util/expect/primitives.js +55 -55
- package/dist/util/expect/url.js +60 -60
- package/dist/util/function/index.js +218 -218
- package/dist/util/geo/index.js +26 -26
- package/dist/util/index.js +7 -7
- package/dist/util/is/index.js +147 -147
- package/dist/util/iterate/index.js +204 -204
- package/dist/util/object/index.js +1345 -1345
- package/dist/util/singleton/index.js +97 -97
- package/dist/util/string/array-path.js +75 -75
- package/dist/util/string/convert.js +54 -54
- package/dist/util/string/fs.js +226 -226
- package/dist/util/string/index.js +5 -5
- package/dist/util/string/interpolate.js +61 -61
- package/dist/util/string/pad.js +10 -10
- package/dist/util/svelte/index.js +4 -4
- package/dist/util/svelte/loading/loading-tracker.svelte.js +108 -108
- package/dist/util/svelte/observe/index.js +49 -49
- package/dist/util/svelte/state-context/index.js +117 -117
- package/dist/util/svelte/wait/index.js +38 -38
- package/dist/util/sveltekit/index.js +1 -1
- package/dist/util/sveltekit/route-folders/index.js +101 -101
- package/dist/util/time/index.js +328 -328
- package/dist/util/unique/index.js +231 -231
- package/dist/valibot/README.md +61 -50
- package/dist/valibot/index.js +8 -8
- package/dist/valibot/parsers/date.js__ +10 -0
- package/dist/valibot/parsers/email.d.ts +12 -0
- package/dist/valibot/parsers/email.js +34 -0
- package/dist/valibot/parsers/url.js +110 -110
- package/dist/valibot/parsers/user.js +23 -23
- package/dist/valibot/parsers.js +3 -3
- package/package.json +131 -131
- package/dist/logging/internal/unified-logger/index.d.ts +0 -3
- package/dist/logging/internal/unified-logger/index.js +0 -6
- package/dist/services/internal/index.d.ts +0 -6
- package/dist/services/internal/index.js +0 -8
- /package/dist/logging/internal/{unified-logger/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/services/{internal/service-base → service-base}/index.d.ts +0 -0
- /package/dist/services/{internal/service-manager → service-manager}/constants.d.ts +0 -0
- /package/dist/services/{internal/service-manager → service-manager}/typedef.d.ts +0 -0
|
@@ -1,150 +1,150 @@
|
|
|
1
|
-
import { calculateEffectiveWidth } from './utils/index.js';
|
|
2
|
-
|
|
3
|
-
import ImageLoader from './ImageLoader.svelte.js';
|
|
4
|
-
|
|
5
|
-
/** @typedef {import('../typedef.js').ImageMeta} ImageMeta */
|
|
6
|
-
|
|
7
|
-
export default class ImageVariantsLoader {
|
|
8
|
-
/** @type {number} */
|
|
9
|
-
#devicePixelRatio;
|
|
10
|
-
|
|
11
|
-
/** @type {ImageMeta[]} */
|
|
12
|
-
#imagesMeta;
|
|
13
|
-
|
|
14
|
-
/** @type {ImageMeta|null} */
|
|
15
|
-
#imageVariant = $state(null);
|
|
16
|
-
|
|
17
|
-
/** @type {ImageLoader|null} */
|
|
18
|
-
#imageLoader = $state(null);
|
|
19
|
-
|
|
20
|
-
#progress = $derived.by(() => {
|
|
21
|
-
if (this.#imageLoader) {
|
|
22
|
-
return this.#imageLoader.progress;
|
|
23
|
-
} else {
|
|
24
|
-
return { bytesLoaded: 0, size: 0, loaded: false };
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
#loaded = $derived.by(() => this.#progress?.loaded || false);
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @param {ImageMeta[]} imagesMeta
|
|
32
|
-
*/
|
|
33
|
-
constructor(imagesMeta, { devicePixelRatio = 1 } = {}) {
|
|
34
|
-
this.#devicePixelRatio = devicePixelRatio ?? 1;
|
|
35
|
-
this.#imagesMeta = [...imagesMeta].sort((a, b) => a.width - b.width);
|
|
36
|
-
// console.debug("imagesMeta",imagesMeta);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Set new optimal image variant or keep current
|
|
41
|
-
*
|
|
42
|
-
* @param {object} params
|
|
43
|
-
* @param {number} [params.containerWidth] Container width
|
|
44
|
-
* @param {number} [params.containerHeight] Container height
|
|
45
|
-
* @param {'cover'|'contain'|'fill'} [params.fit='contain'] Fit mode
|
|
46
|
-
*/
|
|
47
|
-
updateOptimalImageMeta({ containerWidth, containerHeight, fit = 'contain' }) {
|
|
48
|
-
const baseImage = this.#imagesMeta[0];
|
|
49
|
-
const imageAspectRatio = baseImage.width / baseImage.height;
|
|
50
|
-
|
|
51
|
-
const effectiveWidth = calculateEffectiveWidth({
|
|
52
|
-
containerWidth,
|
|
53
|
-
containerHeight,
|
|
54
|
-
imageAspectRatio,
|
|
55
|
-
fit
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
const newVariant = this.getOptimalImageMeta(effectiveWidth);
|
|
59
|
-
|
|
60
|
-
// console.debug("updateOptimalImageMeta", effectiveWidth, newVariant );
|
|
61
|
-
|
|
62
|
-
if (
|
|
63
|
-
!newVariant ||
|
|
64
|
-
!this.#imageVariant ||
|
|
65
|
-
newVariant.width > this.#imageVariant.width
|
|
66
|
-
) {
|
|
67
|
-
this.#imageVariant = newVariant;
|
|
68
|
-
|
|
69
|
-
// Create and start loader here directly when variant changes
|
|
70
|
-
if (this.#imageLoader?.initial) {
|
|
71
|
-
this.#imageLoader.unload();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
this.#imageLoader = new ImageLoader(newVariant);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
this.#imageLoader.load();
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
get loaded() {
|
|
82
|
-
return this.#loaded;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
get variant() {
|
|
86
|
-
return this.#imageVariant;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Get object URL that can be used as src parameter of an HTML image
|
|
91
|
-
*
|
|
92
|
-
* @note the objectURL should be revoked when no longer used
|
|
93
|
-
*
|
|
94
|
-
* @returns {string|null}
|
|
95
|
-
*/
|
|
96
|
-
getObjectURL() {
|
|
97
|
-
// Example usage:
|
|
98
|
-
//
|
|
99
|
-
// $effect(() => {
|
|
100
|
-
// if (variantsLoader.loaded) {
|
|
101
|
-
// // @ts-ignore
|
|
102
|
-
// imageUrl = variantsLoader.getObjectURL();
|
|
103
|
-
// }
|
|
104
|
-
|
|
105
|
-
// return () => {
|
|
106
|
-
// if (imageUrl) {
|
|
107
|
-
// URL.revokeObjectURL(imageUrl);
|
|
108
|
-
// imageUrl = null;
|
|
109
|
-
// }
|
|
110
|
-
// };
|
|
111
|
-
// });
|
|
112
|
-
|
|
113
|
-
const blob = this.#imageLoader?.getBlob();
|
|
114
|
-
|
|
115
|
-
const url = blob ? URL.createObjectURL(blob) : null;
|
|
116
|
-
|
|
117
|
-
return url;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
get progress() {
|
|
121
|
-
return this.#progress;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Get optimal image variant
|
|
126
|
-
*
|
|
127
|
-
* @param {number} containerWidth
|
|
128
|
-
*
|
|
129
|
-
* @returns {ImageMeta|null}
|
|
130
|
-
*/
|
|
131
|
-
getOptimalImageMeta(containerWidth) {
|
|
132
|
-
if (!containerWidth) {
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Calculate the required width (container * DPR)
|
|
137
|
-
const requiredWidth = containerWidth * this.#devicePixelRatio;
|
|
138
|
-
|
|
139
|
-
const imagesMeta = this.#imagesMeta;
|
|
140
|
-
|
|
141
|
-
// Find the smallest image that's larger than our required width
|
|
142
|
-
|
|
143
|
-
const optimal = imagesMeta.find(
|
|
144
|
-
(current) => current.width >= requiredWidth
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
// Fall back to the largest image if nothing is big enough
|
|
148
|
-
return optimal || imagesMeta[imagesMeta.length - 1];
|
|
149
|
-
}
|
|
150
|
-
} // end class
|
|
1
|
+
import { calculateEffectiveWidth } from './utils/index.js';
|
|
2
|
+
|
|
3
|
+
import ImageLoader from './ImageLoader.svelte.js';
|
|
4
|
+
|
|
5
|
+
/** @typedef {import('../typedef.js').ImageMeta} ImageMeta */
|
|
6
|
+
|
|
7
|
+
export default class ImageVariantsLoader {
|
|
8
|
+
/** @type {number} */
|
|
9
|
+
#devicePixelRatio;
|
|
10
|
+
|
|
11
|
+
/** @type {ImageMeta[]} */
|
|
12
|
+
#imagesMeta;
|
|
13
|
+
|
|
14
|
+
/** @type {ImageMeta|null} */
|
|
15
|
+
#imageVariant = $state(null);
|
|
16
|
+
|
|
17
|
+
/** @type {ImageLoader|null} */
|
|
18
|
+
#imageLoader = $state(null);
|
|
19
|
+
|
|
20
|
+
#progress = $derived.by(() => {
|
|
21
|
+
if (this.#imageLoader) {
|
|
22
|
+
return this.#imageLoader.progress;
|
|
23
|
+
} else {
|
|
24
|
+
return { bytesLoaded: 0, size: 0, loaded: false };
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
#loaded = $derived.by(() => this.#progress?.loaded || false);
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {ImageMeta[]} imagesMeta
|
|
32
|
+
*/
|
|
33
|
+
constructor(imagesMeta, { devicePixelRatio = 1 } = {}) {
|
|
34
|
+
this.#devicePixelRatio = devicePixelRatio ?? 1;
|
|
35
|
+
this.#imagesMeta = [...imagesMeta].sort((a, b) => a.width - b.width);
|
|
36
|
+
// console.debug("imagesMeta",imagesMeta);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Set new optimal image variant or keep current
|
|
41
|
+
*
|
|
42
|
+
* @param {object} params
|
|
43
|
+
* @param {number} [params.containerWidth] Container width
|
|
44
|
+
* @param {number} [params.containerHeight] Container height
|
|
45
|
+
* @param {'cover'|'contain'|'fill'} [params.fit='contain'] Fit mode
|
|
46
|
+
*/
|
|
47
|
+
updateOptimalImageMeta({ containerWidth, containerHeight, fit = 'contain' }) {
|
|
48
|
+
const baseImage = this.#imagesMeta[0];
|
|
49
|
+
const imageAspectRatio = baseImage.width / baseImage.height;
|
|
50
|
+
|
|
51
|
+
const effectiveWidth = calculateEffectiveWidth({
|
|
52
|
+
containerWidth,
|
|
53
|
+
containerHeight,
|
|
54
|
+
imageAspectRatio,
|
|
55
|
+
fit
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
const newVariant = this.getOptimalImageMeta(effectiveWidth);
|
|
59
|
+
|
|
60
|
+
// console.debug("updateOptimalImageMeta", effectiveWidth, newVariant );
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
!newVariant ||
|
|
64
|
+
!this.#imageVariant ||
|
|
65
|
+
newVariant.width > this.#imageVariant.width
|
|
66
|
+
) {
|
|
67
|
+
this.#imageVariant = newVariant;
|
|
68
|
+
|
|
69
|
+
// Create and start loader here directly when variant changes
|
|
70
|
+
if (this.#imageLoader?.initial) {
|
|
71
|
+
this.#imageLoader.unload();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this.#imageLoader = new ImageLoader(newVariant);
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
this.#imageLoader.load();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get loaded() {
|
|
82
|
+
return this.#loaded;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get variant() {
|
|
86
|
+
return this.#imageVariant;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Get object URL that can be used as src parameter of an HTML image
|
|
91
|
+
*
|
|
92
|
+
* @note the objectURL should be revoked when no longer used
|
|
93
|
+
*
|
|
94
|
+
* @returns {string|null}
|
|
95
|
+
*/
|
|
96
|
+
getObjectURL() {
|
|
97
|
+
// Example usage:
|
|
98
|
+
//
|
|
99
|
+
// $effect(() => {
|
|
100
|
+
// if (variantsLoader.loaded) {
|
|
101
|
+
// // @ts-ignore
|
|
102
|
+
// imageUrl = variantsLoader.getObjectURL();
|
|
103
|
+
// }
|
|
104
|
+
|
|
105
|
+
// return () => {
|
|
106
|
+
// if (imageUrl) {
|
|
107
|
+
// URL.revokeObjectURL(imageUrl);
|
|
108
|
+
// imageUrl = null;
|
|
109
|
+
// }
|
|
110
|
+
// };
|
|
111
|
+
// });
|
|
112
|
+
|
|
113
|
+
const blob = this.#imageLoader?.getBlob();
|
|
114
|
+
|
|
115
|
+
const url = blob ? URL.createObjectURL(blob) : null;
|
|
116
|
+
|
|
117
|
+
return url;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
get progress() {
|
|
121
|
+
return this.#progress;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Get optimal image variant
|
|
126
|
+
*
|
|
127
|
+
* @param {number} containerWidth
|
|
128
|
+
*
|
|
129
|
+
* @returns {ImageMeta|null}
|
|
130
|
+
*/
|
|
131
|
+
getOptimalImageMeta(containerWidth) {
|
|
132
|
+
if (!containerWidth) {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Calculate the required width (container * DPR)
|
|
137
|
+
const requiredWidth = containerWidth * this.#devicePixelRatio;
|
|
138
|
+
|
|
139
|
+
const imagesMeta = this.#imagesMeta;
|
|
140
|
+
|
|
141
|
+
// Find the smallest image that's larger than our required width
|
|
142
|
+
|
|
143
|
+
const optimal = imagesMeta.find(
|
|
144
|
+
(current) => current.width >= requiredWidth
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
// Fall back to the largest image if nothing is big enough
|
|
148
|
+
return optimal || imagesMeta[imagesMeta.length - 1];
|
|
149
|
+
}
|
|
150
|
+
} // end class
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as ImageLoader } from './ImageLoader.svelte.js';
|
|
2
|
-
export { default as ImageVariantsLoader } from './ImageVariantsLoader.svelte.js';
|
|
3
|
-
|
|
4
|
-
// export * from './constants.js';
|
|
1
|
+
export { default as ImageLoader } from './ImageLoader.svelte.js';
|
|
2
|
+
export { default as ImageVariantsLoader } from './ImageVariantsLoader.svelte.js';
|
|
3
|
+
|
|
4
|
+
// export * from './constants.js';
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
|
|
2
|
-
|
|
3
|
-
import { IMAGE_PNG } from '../../../constants/mime/image.js';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* A minimal 1x1 black PNG encoded as base64
|
|
7
|
-
* @constant {string}
|
|
8
|
-
*/
|
|
9
|
-
const BASE64_PNG =
|
|
10
|
-
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Create a response value that can be used by a mocked
|
|
14
|
-
* fetch function
|
|
15
|
-
*
|
|
16
|
-
* @returns {Response}
|
|
17
|
-
*/
|
|
18
|
-
export function createPngResponse(/* data , options */) {
|
|
19
|
-
// Convert base64 to binary
|
|
20
|
-
const binaryString = atob(BASE64_PNG);
|
|
21
|
-
const bytes = new Uint8Array(binaryString.length);
|
|
22
|
-
|
|
23
|
-
for (let i = 0; i < binaryString.length; i++) {
|
|
24
|
-
bytes[i] = binaryString.charCodeAt(i);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const response = new Response(bytes, {
|
|
28
|
-
headers: new Headers({
|
|
29
|
-
[CONTENT_TYPE]: IMAGE_PNG,
|
|
30
|
-
[CONTENT_LENGTH]: String(bytes.length)
|
|
31
|
-
})
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
return response;
|
|
35
|
-
}
|
|
1
|
+
import { CONTENT_TYPE, CONTENT_LENGTH } from '../../../constants/http/index.js';
|
|
2
|
+
|
|
3
|
+
import { IMAGE_PNG } from '../../../constants/mime/image.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A minimal 1x1 black PNG encoded as base64
|
|
7
|
+
* @constant {string}
|
|
8
|
+
*/
|
|
9
|
+
const BASE64_PNG =
|
|
10
|
+
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a response value that can be used by a mocked
|
|
14
|
+
* fetch function
|
|
15
|
+
*
|
|
16
|
+
* @returns {Response}
|
|
17
|
+
*/
|
|
18
|
+
export function createPngResponse(/* data , options */) {
|
|
19
|
+
// Convert base64 to binary
|
|
20
|
+
const binaryString = atob(BASE64_PNG);
|
|
21
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
24
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const response = new Response(bytes, {
|
|
28
|
+
headers: new Headers({
|
|
29
|
+
[CONTENT_TYPE]: IMAGE_PNG,
|
|
30
|
+
[CONTENT_LENGTH]: String(bytes.length)
|
|
31
|
+
})
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return response;
|
|
35
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {Object} ImageMeta
|
|
3
|
-
* @property {string} src - URL of the image
|
|
4
|
-
* @property {number} width - Width of the image
|
|
5
|
-
* @property {number} height - Height of the image
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
export default {};
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Object} ImageMeta
|
|
3
|
+
* @property {string} src - URL of the image
|
|
4
|
+
* @property {number} width - Width of the image
|
|
5
|
+
* @property {number} height - Height of the image
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export default {};
|
|
@@ -1,86 +1,86 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Returns the unchanged image meta object or the last item of
|
|
3
|
-
* an array of ImageMeta objects. This is assumed to be a list
|
|
4
|
-
* of sorted responsive image formats, so it should be the
|
|
5
|
-
* largest image.
|
|
6
|
-
*
|
|
7
|
-
* @param {import('../../typedef.js').ImageSource} imageSource
|
|
8
|
-
*/
|
|
9
|
-
export function toSingleImageMeta(imageSource) {
|
|
10
|
-
if (Array.isArray(imageSource)) {
|
|
11
|
-
if (!imageSource.length) {
|
|
12
|
-
throw new Error('List of ImageMeta objects is empty');
|
|
13
|
-
}
|
|
14
|
-
imageSource = imageSource[imageSource.length - 1];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (typeof imageSource === 'object') {
|
|
18
|
-
return imageSource;
|
|
19
|
-
} else if (!imageSource) {
|
|
20
|
-
throw new Error('Missing [imageSource]');
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
throw new Error('Invalid value for parameter [imageSource]');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Calculate effective width based on container dimensions and fit mode
|
|
28
|
-
*
|
|
29
|
-
* @param {object} params
|
|
30
|
-
* @param {number} [params.containerWidth] Container width in pixels
|
|
31
|
-
* @param {number} [params.containerHeight] Container height in pixels
|
|
32
|
-
* @param {number} params.imageAspectRatio Original image aspect ratio (width/height)
|
|
33
|
-
* @param {'cover'|'contain'|'fill'} [params.fit='contain'] Fit mode
|
|
34
|
-
* @returns {number} Effective width needed
|
|
35
|
-
*/
|
|
36
|
-
export function calculateEffectiveWidth({
|
|
37
|
-
containerWidth,
|
|
38
|
-
containerHeight,
|
|
39
|
-
imageAspectRatio,
|
|
40
|
-
fit = 'contain'
|
|
41
|
-
}) {
|
|
42
|
-
if (containerWidth && !containerHeight) {
|
|
43
|
-
// If only width is provided, use it
|
|
44
|
-
|
|
45
|
-
return containerWidth;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (!containerWidth && containerHeight) {
|
|
49
|
-
// If only height is provided, calculate width based on aspect ratio
|
|
50
|
-
|
|
51
|
-
return containerHeight * imageAspectRatio;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (containerWidth && containerHeight) {
|
|
55
|
-
// If both dimensions are provided, calculate based on fit mode
|
|
56
|
-
|
|
57
|
-
const containerAspectRatio = containerWidth / containerHeight;
|
|
58
|
-
|
|
59
|
-
switch (fit) {
|
|
60
|
-
case 'fill':
|
|
61
|
-
return containerWidth;
|
|
62
|
-
|
|
63
|
-
case 'contain':
|
|
64
|
-
if (containerAspectRatio > imageAspectRatio) {
|
|
65
|
-
// Height constrained, scale width accordingly
|
|
66
|
-
|
|
67
|
-
return containerHeight * imageAspectRatio;
|
|
68
|
-
}
|
|
69
|
-
return containerWidth;
|
|
70
|
-
|
|
71
|
-
case 'cover':
|
|
72
|
-
if (containerAspectRatio < imageAspectRatio) {
|
|
73
|
-
// Height constrained, scale width accordingly
|
|
74
|
-
|
|
75
|
-
return containerHeight * imageAspectRatio;
|
|
76
|
-
}
|
|
77
|
-
return containerWidth;
|
|
78
|
-
|
|
79
|
-
default:
|
|
80
|
-
return containerWidth;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Fallback if neither dimension is provided
|
|
85
|
-
throw new Error('Either containerWidth or containerHeight must be provided');
|
|
86
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Returns the unchanged image meta object or the last item of
|
|
3
|
+
* an array of ImageMeta objects. This is assumed to be a list
|
|
4
|
+
* of sorted responsive image formats, so it should be the
|
|
5
|
+
* largest image.
|
|
6
|
+
*
|
|
7
|
+
* @param {import('../../typedef.js').ImageSource} imageSource
|
|
8
|
+
*/
|
|
9
|
+
export function toSingleImageMeta(imageSource) {
|
|
10
|
+
if (Array.isArray(imageSource)) {
|
|
11
|
+
if (!imageSource.length) {
|
|
12
|
+
throw new Error('List of ImageMeta objects is empty');
|
|
13
|
+
}
|
|
14
|
+
imageSource = imageSource[imageSource.length - 1];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof imageSource === 'object') {
|
|
18
|
+
return imageSource;
|
|
19
|
+
} else if (!imageSource) {
|
|
20
|
+
throw new Error('Missing [imageSource]');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
throw new Error('Invalid value for parameter [imageSource]');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Calculate effective width based on container dimensions and fit mode
|
|
28
|
+
*
|
|
29
|
+
* @param {object} params
|
|
30
|
+
* @param {number} [params.containerWidth] Container width in pixels
|
|
31
|
+
* @param {number} [params.containerHeight] Container height in pixels
|
|
32
|
+
* @param {number} params.imageAspectRatio Original image aspect ratio (width/height)
|
|
33
|
+
* @param {'cover'|'contain'|'fill'} [params.fit='contain'] Fit mode
|
|
34
|
+
* @returns {number} Effective width needed
|
|
35
|
+
*/
|
|
36
|
+
export function calculateEffectiveWidth({
|
|
37
|
+
containerWidth,
|
|
38
|
+
containerHeight,
|
|
39
|
+
imageAspectRatio,
|
|
40
|
+
fit = 'contain'
|
|
41
|
+
}) {
|
|
42
|
+
if (containerWidth && !containerHeight) {
|
|
43
|
+
// If only width is provided, use it
|
|
44
|
+
|
|
45
|
+
return containerWidth;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!containerWidth && containerHeight) {
|
|
49
|
+
// If only height is provided, calculate width based on aspect ratio
|
|
50
|
+
|
|
51
|
+
return containerHeight * imageAspectRatio;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (containerWidth && containerHeight) {
|
|
55
|
+
// If both dimensions are provided, calculate based on fit mode
|
|
56
|
+
|
|
57
|
+
const containerAspectRatio = containerWidth / containerHeight;
|
|
58
|
+
|
|
59
|
+
switch (fit) {
|
|
60
|
+
case 'fill':
|
|
61
|
+
return containerWidth;
|
|
62
|
+
|
|
63
|
+
case 'contain':
|
|
64
|
+
if (containerAspectRatio > imageAspectRatio) {
|
|
65
|
+
// Height constrained, scale width accordingly
|
|
66
|
+
|
|
67
|
+
return containerHeight * imageAspectRatio;
|
|
68
|
+
}
|
|
69
|
+
return containerWidth;
|
|
70
|
+
|
|
71
|
+
case 'cover':
|
|
72
|
+
if (containerAspectRatio < imageAspectRatio) {
|
|
73
|
+
// Height constrained, scale width accordingly
|
|
74
|
+
|
|
75
|
+
return containerHeight * imageAspectRatio;
|
|
76
|
+
}
|
|
77
|
+
return containerWidth;
|
|
78
|
+
|
|
79
|
+
default:
|
|
80
|
+
return containerWidth;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Fallback if neither dimension is provided
|
|
85
|
+
throw new Error('Either containerWidth or containerHeight must be provided');
|
|
86
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { default as ImageLoader } from './image/ImageLoader.svelte.js';
|
|
2
|
-
export { default as ImageScene } from './image/ImageScene.svelte.js';
|
|
3
|
-
export { default as ImageVariantsLoader } from './image/ImageVariantsLoader.svelte.js';
|
|
4
|
-
|
|
5
|
-
export * from './image/utils/index.js';
|
|
6
|
-
export * from './image/typedef.js';
|
|
7
|
-
|
|
1
|
+
export { default as ImageLoader } from './image/ImageLoader.svelte.js';
|
|
2
|
+
export { default as ImageScene } from './image/ImageScene.svelte.js';
|
|
3
|
+
export { default as ImageVariantsLoader } from './image/ImageVariantsLoader.svelte.js';
|
|
4
|
+
|
|
5
|
+
export * from './image/utils/index.js';
|
|
6
|
+
export * from './image/typedef.js';
|
|
7
|
+
|
|
8
8
|
// export * from './image/constants.js';
|
|
@@ -1,38 +1,38 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef {object} ImageMeta
|
|
3
|
-
* @property {string} src
|
|
4
|
-
* @property {number} width
|
|
5
|
-
* @property {number} height
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @typedef {ImageMeta | ImageMeta[]} ImageSource
|
|
10
|
-
* Single ImageMeta object or array of ImageMeta objects
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @typedef {"center" | "top" | "bottom" | "left" | "right" |
|
|
15
|
-
* "left top" | "left center" | "left bottom" |
|
|
16
|
-
* "center top" | "center center" | "center bottom" |
|
|
17
|
-
* "right top" | "right center" | "right bottom" |
|
|
18
|
-
* string} ObjectPosition
|
|
19
|
-
*
|
|
20
|
-
* @description Accepts valid CSS object-position values including:
|
|
21
|
-
* - Keywords: "center", "top", "bottom", "left", "right"
|
|
22
|
-
* - Length values: "10px", "2em", "50%", etc.
|
|
23
|
-
* - Percentage values: "25%", "100%", etc.
|
|
24
|
-
* - Two-value combinations: "left top", "center bottom", "25% 75%"
|
|
25
|
-
* - Mixed units: "left 20px", "10% center", "2em 50%"
|
|
26
|
-
*
|
|
27
|
-
* @example
|
|
28
|
-
* "center" // Single keyword (centers both axes)
|
|
29
|
-
* "top" // Single keyword
|
|
30
|
-
* "left center" // Two keywords
|
|
31
|
-
* "25% 75%" // Two percentages
|
|
32
|
-
* "10px 20px" // Two lengths
|
|
33
|
-
* "left 25%" // Keyword + percentage
|
|
34
|
-
* "50% top" // Percentage + keyword
|
|
35
|
-
* "2em center" // Length + keyword
|
|
36
|
-
*/
|
|
37
|
-
|
|
38
|
-
export default {};
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} ImageMeta
|
|
3
|
+
* @property {string} src
|
|
4
|
+
* @property {number} width
|
|
5
|
+
* @property {number} height
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {ImageMeta | ImageMeta[]} ImageSource
|
|
10
|
+
* Single ImageMeta object or array of ImageMeta objects
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {"center" | "top" | "bottom" | "left" | "right" |
|
|
15
|
+
* "left top" | "left center" | "left bottom" |
|
|
16
|
+
* "center top" | "center center" | "center bottom" |
|
|
17
|
+
* "right top" | "right center" | "right bottom" |
|
|
18
|
+
* string} ObjectPosition
|
|
19
|
+
*
|
|
20
|
+
* @description Accepts valid CSS object-position values including:
|
|
21
|
+
* - Keywords: "center", "top", "bottom", "left", "right"
|
|
22
|
+
* - Length values: "10px", "2em", "50%", etc.
|
|
23
|
+
* - Percentage values: "25%", "100%", etc.
|
|
24
|
+
* - Two-value combinations: "left top", "center bottom", "25% 75%"
|
|
25
|
+
* - Mixed units: "left 20px", "10% center", "2em 50%"
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* "center" // Single keyword (centers both axes)
|
|
29
|
+
* "top" // Single keyword
|
|
30
|
+
* "left center" // Two keywords
|
|
31
|
+
* "25% 75%" // Two percentages
|
|
32
|
+
* "10px 20px" // Two lengths
|
|
33
|
+
* "left 25%" // Keyword + percentage
|
|
34
|
+
* "50% top" // Percentage + keyword
|
|
35
|
+
* "2em center" // Length + keyword
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
export default {};
|
package/dist/network/loaders.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './loaders/audio.js';
|
|
2
|
-
export * from './loaders/image.js';
|
|
1
|
+
export * from './loaders/audio.js';
|
|
2
|
+
export * from './loaders/image.js';
|