@lightningjs/renderer 1.0.1 → 2.0.0
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 +17 -0
- package/dist/exports/canvas.d.ts +18 -0
- package/dist/exports/canvas.js +37 -0
- package/dist/exports/canvas.js.map +1 -0
- package/dist/exports/index.d.ts +2 -4
- package/dist/exports/index.js +1 -3
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/inspector.d.ts +1 -0
- package/dist/exports/inspector.js +20 -0
- package/dist/exports/inspector.js.map +1 -0
- package/dist/exports/webgl.d.ts +19 -0
- package/dist/exports/webgl.js +38 -0
- package/dist/exports/webgl.js.map +1 -0
- package/dist/src/common/EventEmitter.d.ts +1 -1
- package/dist/src/common/IAnimationController.d.ts +1 -1
- package/dist/src/common/IEventEmitter.d.ts +8 -0
- package/dist/src/common/IEventEmitter.js +18 -0
- package/dist/src/common/IEventEmitter.js.map +1 -0
- package/dist/src/core/CoreNode.d.ts +58 -0
- package/dist/src/core/CoreNode.js +57 -1
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreTextNode.d.ts +2 -2
- package/dist/src/core/CoreTextNode.js +20 -30
- package/dist/src/core/CoreTextNode.js.map +1 -1
- package/dist/src/core/Stage.d.ts +11 -5
- package/dist/src/core/Stage.js +54 -26
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/TextureMemoryManager.js +4 -2
- package/dist/src/core/TextureMemoryManager.js.map +1 -1
- package/dist/src/core/animations/CoreAnimation.js +1 -1
- package/dist/src/core/animations/CoreAnimation.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.d.ts +1 -1
- package/dist/src/core/lib/ImageWorker.js +25 -3
- package/dist/src/core/lib/ImageWorker.js.map +1 -1
- package/dist/src/core/lib/textureSvg.d.ts +16 -0
- package/dist/src/core/lib/textureSvg.js +63 -0
- package/dist/src/core/lib/textureSvg.js.map +1 -0
- package/dist/src/core/text-rendering/TrFontManager.js +11 -4
- package/dist/src/core/text-rendering/TrFontManager.js.map +1 -1
- package/dist/src/core/text-rendering/font-face-types/WebTrFontFace.js +13 -5
- package/dist/src/core/text-rendering/font-face-types/WebTrFontFace.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +1 -0
- package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
- package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +1 -0
- package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
- package/dist/src/core/textures/ImageTexture.d.ts +52 -0
- package/dist/src/core/textures/ImageTexture.js +78 -31
- package/dist/src/core/textures/ImageTexture.js.map +1 -1
- package/dist/src/core/textures/Texture.d.ts +1 -0
- package/dist/src/core/textures/Texture.js +1 -0
- package/dist/src/core/textures/Texture.js.map +1 -1
- package/dist/src/main-api/Inspector.js +2 -2
- package/dist/src/main-api/Inspector.js.map +1 -1
- package/dist/src/main-api/Renderer.d.ts +50 -8
- package/dist/src/main-api/Renderer.js +8 -7
- package/dist/src/main-api/Renderer.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/exports/canvas.ts +37 -0
- package/exports/index.ts +3 -3
- package/exports/inspector.ts +20 -0
- package/exports/webgl.ts +38 -0
- package/package.json +5 -7
- package/src/common/EventEmitter.ts +1 -1
- package/src/common/IAnimationController.ts +1 -1
- package/src/common/IEventEmitter.ts +28 -0
- package/src/core/CoreNode.test.ts +1 -0
- package/src/core/CoreNode.ts +120 -1
- package/src/core/CoreTextNode.ts +58 -65
- package/src/core/Stage.ts +88 -36
- package/src/core/TextureMemoryManager.ts +4 -2
- package/src/core/animations/CoreAnimation.ts +2 -1
- package/src/core/lib/ImageWorker.ts +44 -7
- package/src/core/lib/textureSvg.ts +78 -0
- package/src/core/text-rendering/TrFontManager.ts +15 -4
- package/src/core/text-rendering/font-face-types/WebTrFontFace.ts +15 -8
- package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +2 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +2 -0
- package/src/core/text-rendering/renderers/TextRenderer.ts +1 -0
- package/src/core/textures/ImageTexture.ts +159 -35
- package/src/core/textures/Texture.ts +2 -0
- package/src/main-api/Inspector.ts +2 -2
- package/src/main-api/Renderer.ts +59 -15
|
@@ -25,6 +25,17 @@ interface getImageReturn {
|
|
|
25
25
|
premultiplyAlpha: boolean | null;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
+
interface ImageWorkerMessage {
|
|
29
|
+
id: number;
|
|
30
|
+
src: string;
|
|
31
|
+
data: getImageReturn;
|
|
32
|
+
error: string;
|
|
33
|
+
sx: number | null;
|
|
34
|
+
sy: number | null;
|
|
35
|
+
sw: number | null;
|
|
36
|
+
sh: number | null;
|
|
37
|
+
}
|
|
38
|
+
|
|
28
39
|
/**
|
|
29
40
|
* Note that, within the createImageWorker function, we must only use ES5 code to keep it ES5-valid after babelifying, as
|
|
30
41
|
* the converted code of this section is converted to a blob and used as the js of the web worker thread.
|
|
@@ -43,6 +54,10 @@ function createImageWorker() {
|
|
|
43
54
|
function getImage(
|
|
44
55
|
src: string,
|
|
45
56
|
premultiplyAlpha: boolean | null,
|
|
57
|
+
x: number | null,
|
|
58
|
+
y: number | null,
|
|
59
|
+
width: number | null,
|
|
60
|
+
height: number | null,
|
|
46
61
|
): Promise<getImageReturn> {
|
|
47
62
|
return new Promise(function (resolve, reject) {
|
|
48
63
|
var xhr = new XMLHttpRequest();
|
|
@@ -60,6 +75,21 @@ function createImageWorker() {
|
|
|
60
75
|
? premultiplyAlpha
|
|
61
76
|
: hasAlphaChannel(blob.type);
|
|
62
77
|
|
|
78
|
+
if (width !== null && height !== null) {
|
|
79
|
+
createImageBitmap(blob, x || 0, y || 0, width, height, {
|
|
80
|
+
premultiplyAlpha: withAlphaChannel ? 'premultiply' : 'none',
|
|
81
|
+
colorSpaceConversion: 'none',
|
|
82
|
+
imageOrientation: 'none',
|
|
83
|
+
})
|
|
84
|
+
.then(function (data) {
|
|
85
|
+
resolve({ data, premultiplyAlpha: premultiplyAlpha });
|
|
86
|
+
})
|
|
87
|
+
.catch(function (error) {
|
|
88
|
+
reject(error);
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
63
93
|
createImageBitmap(blob, {
|
|
64
94
|
premultiplyAlpha: withAlphaChannel ? 'premultiply' : 'none',
|
|
65
95
|
colorSpaceConversion: 'none',
|
|
@@ -87,8 +117,12 @@ function createImageWorker() {
|
|
|
87
117
|
var src = event.data.src;
|
|
88
118
|
var id = event.data.id;
|
|
89
119
|
var premultiplyAlpha = event.data.premultiplyAlpha;
|
|
120
|
+
var x = event.data.sx;
|
|
121
|
+
var y = event.data.sy;
|
|
122
|
+
var width = event.data.sw;
|
|
123
|
+
var height = event.data.sh;
|
|
90
124
|
|
|
91
|
-
getImage(src, premultiplyAlpha)
|
|
125
|
+
getImage(src, premultiplyAlpha, x, y, width, height)
|
|
92
126
|
.then(function (data) {
|
|
93
127
|
self.postMessage({ id: id, src: src, data: data });
|
|
94
128
|
})
|
|
@@ -114,12 +148,7 @@ export class ImageWorkerManager {
|
|
|
114
148
|
}
|
|
115
149
|
|
|
116
150
|
private handleMessage(event: MessageEvent) {
|
|
117
|
-
const { id, data, error } = event.data as
|
|
118
|
-
id: number;
|
|
119
|
-
src: string;
|
|
120
|
-
data?: any;
|
|
121
|
-
error?: string;
|
|
122
|
-
};
|
|
151
|
+
const { id, data, error } = event.data as ImageWorkerMessage;
|
|
123
152
|
const msg = this.messageManager[id];
|
|
124
153
|
if (msg) {
|
|
125
154
|
const [resolve, reject] = msg;
|
|
@@ -155,6 +184,10 @@ export class ImageWorkerManager {
|
|
|
155
184
|
getImage(
|
|
156
185
|
src: string,
|
|
157
186
|
premultiplyAlpha: boolean | null,
|
|
187
|
+
sx: number | null,
|
|
188
|
+
sy: number | null,
|
|
189
|
+
sw: number | null,
|
|
190
|
+
sh: number | null,
|
|
158
191
|
): Promise<TextureData> {
|
|
159
192
|
return new Promise((resolve, reject) => {
|
|
160
193
|
try {
|
|
@@ -167,6 +200,10 @@ export class ImageWorkerManager {
|
|
|
167
200
|
id,
|
|
168
201
|
src: src,
|
|
169
202
|
premultiplyAlpha,
|
|
203
|
+
sx,
|
|
204
|
+
sy,
|
|
205
|
+
sw,
|
|
206
|
+
sh,
|
|
170
207
|
});
|
|
171
208
|
}
|
|
172
209
|
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import { assertTruthy } from '../../utils.js';
|
|
21
|
+
import { type TextureData } from '../textures/Texture.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Tests if the given location is a SVG
|
|
25
|
+
* @param url
|
|
26
|
+
* @remarks
|
|
27
|
+
* This function is used to determine if the given image url is a SVG
|
|
28
|
+
* image
|
|
29
|
+
* @returns
|
|
30
|
+
*/
|
|
31
|
+
export function isSvgImage(url: string): boolean {
|
|
32
|
+
return /\.(svg)$/.test(url);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Loads a SVG image
|
|
37
|
+
* @param url
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
export const loadSvg = (
|
|
41
|
+
url: string,
|
|
42
|
+
width: number | null,
|
|
43
|
+
height: number | null,
|
|
44
|
+
sx: number | null,
|
|
45
|
+
sy: number | null,
|
|
46
|
+
sw: number | null,
|
|
47
|
+
sh: number | null,
|
|
48
|
+
): Promise<TextureData> => {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const canvas = document.createElement('canvas');
|
|
51
|
+
const ctx = canvas.getContext('2d');
|
|
52
|
+
assertTruthy(ctx);
|
|
53
|
+
|
|
54
|
+
ctx.imageSmoothingEnabled = true;
|
|
55
|
+
const img = new Image();
|
|
56
|
+
img.onload = () => {
|
|
57
|
+
const x = sx ?? 0;
|
|
58
|
+
const y = sy ?? 0;
|
|
59
|
+
const w = width || img.width;
|
|
60
|
+
const h = height || img.height;
|
|
61
|
+
|
|
62
|
+
canvas.width = w;
|
|
63
|
+
canvas.height = h;
|
|
64
|
+
ctx.drawImage(img, 0, 0, w, h);
|
|
65
|
+
|
|
66
|
+
resolve({
|
|
67
|
+
data: ctx.getImageData(x, y, sw ?? w, sh ?? h),
|
|
68
|
+
premultiplyAlpha: false,
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
img.onerror = (err) => {
|
|
73
|
+
reject(err);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
img.src = url;
|
|
77
|
+
});
|
|
78
|
+
};
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
import type { TrFontFace } from './font-face-types/TrFontFace.js';
|
|
21
21
|
import type { TextRendererMap, TrFontProps } from './renderers/TextRenderer.js';
|
|
22
|
-
|
|
22
|
+
|
|
23
|
+
const fontCache = new Map<string, TrFontFace>();
|
|
23
24
|
|
|
24
25
|
const weightConversions: { [key: string]: number } = {
|
|
25
26
|
normal: 400,
|
|
@@ -36,7 +37,7 @@ const fontWeightToNumber = (weight: string | number): number => {
|
|
|
36
37
|
return weightConversions[weight] || 400;
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
function
|
|
40
|
+
function resolveFontToUse(
|
|
40
41
|
familyMapsByPriority: FontFamilyMap[],
|
|
41
42
|
family: string,
|
|
42
43
|
weightIn: string | number,
|
|
@@ -119,7 +120,6 @@ function rawResolveFontToUse(
|
|
|
119
120
|
|
|
120
121
|
return;
|
|
121
122
|
}
|
|
122
|
-
const resolveFontToUse = memize(rawResolveFontToUse);
|
|
123
123
|
|
|
124
124
|
/**
|
|
125
125
|
* Structure mapping font family names to a set of font faces.
|
|
@@ -159,12 +159,23 @@ export class TrFontManager {
|
|
|
159
159
|
props: TrFontProps,
|
|
160
160
|
): TrFontFace | undefined {
|
|
161
161
|
const { fontFamily, fontWeight, fontStyle, fontStretch } = props;
|
|
162
|
-
|
|
162
|
+
const fontCacheString = `${fontFamily}${fontStyle}${fontWeight}${fontStretch}`;
|
|
163
|
+
|
|
164
|
+
if (fontCache.has(fontCacheString) === true) {
|
|
165
|
+
return fontCache.get(fontCacheString);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const resolvedFont = resolveFontToUse(
|
|
163
169
|
familyMapsByPriority,
|
|
164
170
|
fontFamily,
|
|
165
171
|
fontWeight,
|
|
166
172
|
fontStyle,
|
|
167
173
|
fontStretch,
|
|
168
174
|
);
|
|
175
|
+
if (resolvedFont !== undefined) {
|
|
176
|
+
fontCache.set(fontCacheString, resolvedFont);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return resolvedFont;
|
|
169
180
|
}
|
|
170
181
|
}
|
|
@@ -67,14 +67,21 @@ export class WebTrFontFace extends TrFontFace {
|
|
|
67
67
|
cssDescriptors,
|
|
68
68
|
);
|
|
69
69
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
if (fontUrlWithoutParentheses.length > 0) {
|
|
71
|
+
fontFace
|
|
72
|
+
.load()
|
|
73
|
+
.then(() => {
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
75
|
+
(this.loaded as boolean) = true;
|
|
76
|
+
this.emit('loaded');
|
|
77
|
+
})
|
|
78
|
+
.catch(console.error);
|
|
79
|
+
} else {
|
|
80
|
+
// Default font
|
|
81
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
82
|
+
(this.loaded as boolean) = true;
|
|
83
|
+
this.emit('loaded');
|
|
84
|
+
}
|
|
78
85
|
|
|
79
86
|
this.fontFace = fontFace;
|
|
80
87
|
this.fontUrl = fontUrl;
|
|
@@ -90,6 +90,8 @@ export class CanvasTextRenderer extends TextRenderer<CanvasTextRendererState> {
|
|
|
90
90
|
private fontFamilies: FontFamilyMap = {};
|
|
91
91
|
private fontFamilyArray: FontFamilyMap[] = [this.fontFamilies];
|
|
92
92
|
|
|
93
|
+
public type: 'canvas' | 'sdf' = 'canvas';
|
|
94
|
+
|
|
93
95
|
constructor(stage: Stage) {
|
|
94
96
|
super(stage);
|
|
95
97
|
if (typeof OffscreenCanvas !== 'undefined') {
|
|
@@ -142,6 +142,8 @@ export class SdfTextRenderer extends TextRenderer<SdfTextRendererState> {
|
|
|
142
142
|
private sdfShader: SdfShader;
|
|
143
143
|
private rendererBounds: Bound;
|
|
144
144
|
|
|
145
|
+
public type: 'canvas' | 'sdf' = 'sdf';
|
|
146
|
+
|
|
145
147
|
constructor(stage: Stage) {
|
|
146
148
|
super(stage);
|
|
147
149
|
this.sdfShader = this.stage.shManager.loadShader('SdfShader').shader;
|
|
@@ -422,6 +422,7 @@ export abstract class TextRenderer<
|
|
|
422
422
|
StateT extends TextRendererState = TextRendererState,
|
|
423
423
|
> {
|
|
424
424
|
readonly set: Readonly<TrPropSetters<StateT>>;
|
|
425
|
+
abstract type: 'canvas' | 'sdf';
|
|
425
426
|
|
|
426
427
|
constructor(protected stage: Stage) {
|
|
427
428
|
const propSetters = {
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
loadCompressedTexture,
|
|
25
25
|
} from '../lib/textureCompression.js';
|
|
26
26
|
import { convertUrlToAbsolute } from '../lib/utils.js';
|
|
27
|
+
import { isSvgImage, loadSvg } from '../lib/textureSvg.js';
|
|
27
28
|
|
|
28
29
|
/**
|
|
29
30
|
* Properties of the {@link ImageTexture}
|
|
@@ -55,6 +56,52 @@ export interface ImageTextureProps {
|
|
|
55
56
|
* `ImageData` textures are not cached unless a `key` is provided
|
|
56
57
|
*/
|
|
57
58
|
key?: string | null;
|
|
59
|
+
/**
|
|
60
|
+
* Width of the image to be used as a texture. If not provided, the image's
|
|
61
|
+
* natural width will be used.
|
|
62
|
+
*/
|
|
63
|
+
width?: number | null;
|
|
64
|
+
/**
|
|
65
|
+
* Height of the image to be used as a texture. If not provided, the image's
|
|
66
|
+
* natural height will be used.
|
|
67
|
+
*/
|
|
68
|
+
height?: number | null;
|
|
69
|
+
/**
|
|
70
|
+
* Type, indicate an image type for overriding type detection
|
|
71
|
+
*
|
|
72
|
+
* @default null
|
|
73
|
+
*/
|
|
74
|
+
type?: 'regular' | 'compressed' | 'svg' | null;
|
|
75
|
+
/**
|
|
76
|
+
* The width of the rectangle from which the ImageBitmap will be extracted. This value
|
|
77
|
+
* can be negative. Only works when createImageBitmap is supported on the browser.
|
|
78
|
+
*
|
|
79
|
+
* @default null
|
|
80
|
+
*/
|
|
81
|
+
sw?: number | null;
|
|
82
|
+
/**
|
|
83
|
+
* The height of the rectangle from which the ImageBitmap will be extracted. This value
|
|
84
|
+
* can be negative. Only works when createImageBitmap is supported on the browser.
|
|
85
|
+
*
|
|
86
|
+
* @default null
|
|
87
|
+
*/
|
|
88
|
+
sh?: number | null;
|
|
89
|
+
/**
|
|
90
|
+
* The y coordinate of the reference point of the rectangle from which the ImageBitmap
|
|
91
|
+
* will be extracted. Only used when `sw` and `sh` are provided. And only works when
|
|
92
|
+
* createImageBitmap is available.
|
|
93
|
+
*
|
|
94
|
+
* @default null
|
|
95
|
+
*/
|
|
96
|
+
sx?: number | null;
|
|
97
|
+
/**
|
|
98
|
+
* The x coordinate of the reference point of the rectangle from which the
|
|
99
|
+
* ImageBitmap will be extracted. Only used when source `sw` width and `sh` height
|
|
100
|
+
* are provided. Only works when createImageBitmap is supported on the browser.
|
|
101
|
+
*
|
|
102
|
+
* @default null
|
|
103
|
+
*/
|
|
104
|
+
sy?: number | null;
|
|
58
105
|
}
|
|
59
106
|
|
|
60
107
|
/**
|
|
@@ -83,45 +130,35 @@ export class ImageTexture extends Texture {
|
|
|
83
130
|
return mimeType.indexOf('image/png') !== -1;
|
|
84
131
|
}
|
|
85
132
|
|
|
86
|
-
|
|
87
|
-
const {
|
|
88
|
-
if (!src) {
|
|
89
|
-
return {
|
|
90
|
-
data: null,
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (typeof src !== 'string') {
|
|
95
|
-
if (src instanceof ImageData) {
|
|
96
|
-
return {
|
|
97
|
-
data: src,
|
|
98
|
-
premultiplyAlpha,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
return {
|
|
102
|
-
data: src(),
|
|
103
|
-
premultiplyAlpha,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Handle compressed textures
|
|
108
|
-
if (isCompressedTextureContainer(src)) {
|
|
109
|
-
return loadCompressedTexture(src);
|
|
110
|
-
}
|
|
133
|
+
async loadImage(src: string) {
|
|
134
|
+
const { premultiplyAlpha, sx, sy, sw, sh, width, height } = this.props;
|
|
111
135
|
|
|
112
|
-
|
|
113
|
-
const absoluteSrc = convertUrlToAbsolute(src);
|
|
114
|
-
|
|
115
|
-
if (this.txManager.imageWorkerManager) {
|
|
136
|
+
if (this.txManager.imageWorkerManager !== null) {
|
|
116
137
|
return await this.txManager.imageWorkerManager.getImage(
|
|
117
|
-
|
|
138
|
+
src,
|
|
118
139
|
premultiplyAlpha,
|
|
140
|
+
sx,
|
|
141
|
+
sy,
|
|
142
|
+
sw,
|
|
143
|
+
sh,
|
|
119
144
|
);
|
|
120
|
-
} else if (this.txManager.hasCreateImageBitmap) {
|
|
121
|
-
const response = await fetch(
|
|
145
|
+
} else if (this.txManager.hasCreateImageBitmap === true) {
|
|
146
|
+
const response = await fetch(src);
|
|
122
147
|
const blob = await response.blob();
|
|
123
148
|
const hasAlphaChannel =
|
|
124
149
|
premultiplyAlpha ?? this.hasAlphaChannel(blob.type);
|
|
150
|
+
|
|
151
|
+
if (sw !== null && sh !== null) {
|
|
152
|
+
return {
|
|
153
|
+
data: await createImageBitmap(blob, sx ?? 0, sy ?? 0, sw, sh, {
|
|
154
|
+
premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
|
|
155
|
+
colorSpaceConversion: 'none',
|
|
156
|
+
imageOrientation: 'none',
|
|
157
|
+
}),
|
|
158
|
+
premultiplyAlpha: hasAlphaChannel,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
125
162
|
return {
|
|
126
163
|
data: await createImageBitmap(blob, {
|
|
127
164
|
premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
|
|
@@ -131,11 +168,11 @@ export class ImageTexture extends Texture {
|
|
|
131
168
|
premultiplyAlpha: hasAlphaChannel,
|
|
132
169
|
};
|
|
133
170
|
} else {
|
|
134
|
-
const img = new Image();
|
|
171
|
+
const img = new Image(width || undefined, height || undefined);
|
|
135
172
|
if (!(src.substr(0, 5) === 'data:')) {
|
|
136
173
|
img.crossOrigin = 'Anonymous';
|
|
137
174
|
}
|
|
138
|
-
img.src =
|
|
175
|
+
img.src = src;
|
|
139
176
|
await new Promise<void>((resolve, reject) => {
|
|
140
177
|
img.onload = () => resolve();
|
|
141
178
|
img.onerror = () => reject(new Error(`Failed to load image`));
|
|
@@ -150,6 +187,73 @@ export class ImageTexture extends Texture {
|
|
|
150
187
|
}
|
|
151
188
|
}
|
|
152
189
|
|
|
190
|
+
override async getTextureData(): Promise<TextureData> {
|
|
191
|
+
const { src, premultiplyAlpha, type } = this.props;
|
|
192
|
+
if (src === null) {
|
|
193
|
+
return {
|
|
194
|
+
data: null,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (typeof src !== 'string') {
|
|
199
|
+
if (src instanceof ImageData) {
|
|
200
|
+
return {
|
|
201
|
+
data: src,
|
|
202
|
+
premultiplyAlpha,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
return {
|
|
206
|
+
data: src(),
|
|
207
|
+
premultiplyAlpha,
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const absoluteSrc = convertUrlToAbsolute(src);
|
|
212
|
+
if (type === 'regular') {
|
|
213
|
+
return this.loadImage(absoluteSrc);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (type === 'svg') {
|
|
217
|
+
return loadSvg(
|
|
218
|
+
absoluteSrc,
|
|
219
|
+
this.props.width,
|
|
220
|
+
this.props.height,
|
|
221
|
+
this.props.sx,
|
|
222
|
+
this.props.sy,
|
|
223
|
+
this.props.sw,
|
|
224
|
+
this.props.sh,
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (isSvgImage(src) === true) {
|
|
229
|
+
return loadSvg(
|
|
230
|
+
absoluteSrc,
|
|
231
|
+
this.props.width,
|
|
232
|
+
this.props.height,
|
|
233
|
+
this.props.sx,
|
|
234
|
+
this.props.sy,
|
|
235
|
+
this.props.sw,
|
|
236
|
+
this.props.sh,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (type === 'compressed') {
|
|
241
|
+
return loadCompressedTexture(absoluteSrc);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (isCompressedTextureContainer(src) === true) {
|
|
245
|
+
return loadCompressedTexture(absoluteSrc);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// default
|
|
249
|
+
return this.loadImage(absoluteSrc);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Generates a cache key for the ImageTexture based on the provided props.
|
|
254
|
+
* @param props - The props used to generate the cache key.
|
|
255
|
+
* @returns The cache key as a string, or `false` if the key cannot be generated.
|
|
256
|
+
*/
|
|
153
257
|
static override makeCacheKey(props: ImageTextureProps): string | false {
|
|
154
258
|
const resolvedProps = ImageTexture.resolveDefaults(props);
|
|
155
259
|
// Only cache key-able textures; prioritise key
|
|
@@ -157,7 +261,20 @@ export class ImageTexture extends Texture {
|
|
|
157
261
|
if (typeof key !== 'string') {
|
|
158
262
|
return false;
|
|
159
263
|
}
|
|
160
|
-
|
|
264
|
+
|
|
265
|
+
// if we have source dimensions, cache the texture separately
|
|
266
|
+
let dimensionProps = '';
|
|
267
|
+
if (resolvedProps.sh !== null && resolvedProps.sw !== null) {
|
|
268
|
+
dimensionProps += ',';
|
|
269
|
+
dimensionProps += resolvedProps.sx ?? '';
|
|
270
|
+
dimensionProps += resolvedProps.sy ?? '';
|
|
271
|
+
dimensionProps += resolvedProps.sw || '';
|
|
272
|
+
dimensionProps += resolvedProps.sh || '';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return `ImageTexture,${key},${
|
|
276
|
+
resolvedProps.premultiplyAlpha ?? 'true'
|
|
277
|
+
}${dimensionProps}`;
|
|
161
278
|
}
|
|
162
279
|
|
|
163
280
|
static override resolveDefaults(
|
|
@@ -167,6 +284,13 @@ export class ImageTexture extends Texture {
|
|
|
167
284
|
src: props.src ?? '',
|
|
168
285
|
premultiplyAlpha: props.premultiplyAlpha ?? true, // null,
|
|
169
286
|
key: props.key ?? null,
|
|
287
|
+
type: props.type ?? null,
|
|
288
|
+
width: props.width ?? null,
|
|
289
|
+
height: props.height ?? null,
|
|
290
|
+
sx: props.sx ?? null,
|
|
291
|
+
sy: props.sy ?? null,
|
|
292
|
+
sw: props.sw ?? null,
|
|
293
|
+
sh: props.sh ?? null,
|
|
170
294
|
};
|
|
171
295
|
}
|
|
172
296
|
|
|
@@ -128,7 +128,7 @@ const convertColorToRgba = (color: number) => {
|
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
const domPropertyMap: { [key: string]: string } = {
|
|
131
|
-
id: 'id',
|
|
131
|
+
id: 'test-id',
|
|
132
132
|
};
|
|
133
133
|
|
|
134
134
|
const gradientColorPropertyMap = [
|
|
@@ -163,7 +163,7 @@ export class Inspector {
|
|
|
163
163
|
);
|
|
164
164
|
|
|
165
165
|
this.width = Math.ceil(
|
|
166
|
-
settings.appWidth ??
|
|
166
|
+
settings.appWidth ?? 1920 / (settings.deviceLogicalPixelRatio ?? 1),
|
|
167
167
|
);
|
|
168
168
|
|
|
169
169
|
this.scaleX = settings.deviceLogicalPixelRatio ?? 1;
|