@flighthq/displayobject-dom 0.1.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/dist/domBackground.d.ts +3 -0
- package/dist/domBackground.d.ts.map +1 -0
- package/dist/domBackground.js +9 -0
- package/dist/domBackground.js.map +1 -0
- package/dist/domBitmap.d.ts +4 -0
- package/dist/domBitmap.d.ts.map +1 -0
- package/dist/domBitmap.js +77 -0
- package/dist/domBitmap.js.map +1 -0
- package/dist/domCSSFilterBinding.d.ts +28 -0
- package/dist/domCSSFilterBinding.d.ts.map +1 -0
- package/dist/domCSSFilterBinding.js +56 -0
- package/dist/domCSSFilterBinding.js.map +1 -0
- package/dist/domCache.d.ts +14 -0
- package/dist/domCache.d.ts.map +1 -0
- package/dist/domCache.js +64 -0
- package/dist/domCache.js.map +1 -0
- package/dist/domClip.d.ts +3 -0
- package/dist/domClip.d.ts.map +1 -0
- package/dist/domClip.js +38 -0
- package/dist/domClip.js.map +1 -0
- package/dist/domClipContours.d.ts +6 -0
- package/dist/domClipContours.d.ts.map +1 -0
- package/dist/domClipContours.js +48 -0
- package/dist/domClipContours.js.map +1 -0
- package/dist/domClipRectangle.d.ts +6 -0
- package/dist/domClipRectangle.d.ts.map +1 -0
- package/dist/domClipRectangle.js +148 -0
- package/dist/domClipRectangle.js.map +1 -0
- package/dist/domDisplayObject.d.ts +5 -0
- package/dist/domDisplayObject.d.ts.map +1 -0
- package/dist/domDisplayObject.js +60 -0
- package/dist/domDisplayObject.js.map +1 -0
- package/dist/domFontSource.d.ts +5 -0
- package/dist/domFontSource.d.ts.map +1 -0
- package/dist/domFontSource.js +18 -0
- package/dist/domFontSource.js.map +1 -0
- package/dist/domMaterials.d.ts +15 -0
- package/dist/domMaterials.d.ts.map +1 -0
- package/dist/domMaterials.js +62 -0
- package/dist/domMaterials.js.map +1 -0
- package/dist/domNativeText.d.ts +5 -0
- package/dist/domNativeText.d.ts.map +1 -0
- package/dist/domNativeText.js +65 -0
- package/dist/domNativeText.js.map +1 -0
- package/dist/domReconcile.d.ts +9 -0
- package/dist/domReconcile.d.ts.map +1 -0
- package/dist/domReconcile.js +69 -0
- package/dist/domReconcile.js.map +1 -0
- package/dist/domRenderState.d.ts +5 -0
- package/dist/domRenderState.d.ts.map +1 -0
- package/dist/domRenderState.js +43 -0
- package/dist/domRenderState.js.map +1 -0
- package/dist/domRenderView.d.ts +4 -0
- package/dist/domRenderView.d.ts.map +1 -0
- package/dist/domRenderView.js +24 -0
- package/dist/domRenderView.js.map +1 -0
- package/dist/domRichText.d.ts +7 -0
- package/dist/domRichText.d.ts.map +1 -0
- package/dist/domRichText.js +183 -0
- package/dist/domRichText.js.map +1 -0
- package/dist/domScale9Mapper.d.ts +3 -0
- package/dist/domScale9Mapper.d.ts.map +1 -0
- package/dist/domScale9Mapper.js +37 -0
- package/dist/domScale9Mapper.js.map +1 -0
- package/dist/domScale9Shape.d.ts +10 -0
- package/dist/domScale9Shape.d.ts.map +1 -0
- package/dist/domScale9Shape.js +59 -0
- package/dist/domScale9Shape.js.map +1 -0
- package/dist/domShape.d.ts +4 -0
- package/dist/domShape.d.ts.map +1 -0
- package/dist/domShape.js +45 -0
- package/dist/domShape.js.map +1 -0
- package/dist/domStyle.d.ts +9 -0
- package/dist/domStyle.d.ts.map +1 -0
- package/dist/domStyle.js +25 -0
- package/dist/domStyle.js.map +1 -0
- package/dist/domSvgFilter.d.ts +27 -0
- package/dist/domSvgFilter.d.ts.map +1 -0
- package/dist/domSvgFilter.js +88 -0
- package/dist/domSvgFilter.js.map +1 -0
- package/dist/domTextHelpers.d.ts +6 -0
- package/dist/domTextHelpers.d.ts.map +1 -0
- package/dist/domTextHelpers.js +8 -0
- package/dist/domTextHelpers.js.map +1 -0
- package/dist/domTextInput.d.ts +4 -0
- package/dist/domTextInput.d.ts.map +1 -0
- package/dist/domTextInput.js +60 -0
- package/dist/domTextInput.js.map +1 -0
- package/dist/domTextLabel.d.ts +4 -0
- package/dist/domTextLabel.d.ts.map +1 -0
- package/dist/domTextLabel.js +74 -0
- package/dist/domTextLabel.js.map +1 -0
- package/dist/domTransform.d.ts +4 -0
- package/dist/domTransform.d.ts.map +1 -0
- package/dist/domTransform.js +16 -0
- package/dist/domTransform.js.map +1 -0
- package/dist/domVideo.d.ts +4 -0
- package/dist/domVideo.d.ts.map +1 -0
- package/dist/domVideo.js +27 -0
- package/dist/domVideo.js.map +1 -0
- package/dist/htmlView.d.ts +4 -0
- package/dist/htmlView.d.ts.map +1 -0
- package/dist/htmlView.js +28 -0
- package/dist/htmlView.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
- package/src/domBackground.test.ts +35 -0
- package/src/domBitmap.test.ts +117 -0
- package/src/domCSSFilterBinding.test.ts +104 -0
- package/src/domCache.test.ts +93 -0
- package/src/domClip.test.ts +12 -0
- package/src/domClipContours.test.ts +62 -0
- package/src/domClipRectangle.test.ts +81 -0
- package/src/domDisplayObject.test.ts +236 -0
- package/src/domFontSource.test.ts +30 -0
- package/src/domMaterials.test.ts +111 -0
- package/src/domNativeText.test.ts +71 -0
- package/src/domReconcile.test.ts +158 -0
- package/src/domRenderState.test.ts +87 -0
- package/src/domRenderView.test.ts +69 -0
- package/src/domRichText.test.ts +165 -0
- package/src/domScale9Mapper.test.ts +20 -0
- package/src/domScale9Shape.test.ts +76 -0
- package/src/domShape.test.ts +85 -0
- package/src/domStyle.test.ts +130 -0
- package/src/domSvgFilter.test.ts +116 -0
- package/src/domTextHelpers.test.ts +27 -0
- package/src/domTextInput.test.ts +61 -0
- package/src/domTextLabel.test.ts +92 -0
- package/src/domTransform.test.ts +68 -0
- package/src/domVideo.test.ts +30 -0
- package/src/htmlView.test.ts +117 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { computeRgbHexString } from '@flighthq/materials';
|
|
2
|
+
import { getRichTextRuntime } from '@flighthq/text';
|
|
3
|
+
import { getTextInputCaretRectangle, getTextInputSelectionBeginIndex, getTextInputSelectionEndIndex, getTextInputSelectionRectangles, getTextInputState, } from '@flighthq/textinput';
|
|
4
|
+
import { getRichTextScrollYOffset } from '@flighthq/textlayout';
|
|
5
|
+
import { registerDomTextInputOverlay } from './domRichText';
|
|
6
|
+
let _keyframesInjected = false;
|
|
7
|
+
// Appends the editable-field overlay (selection highlight + blinking caret) into the field div of a
|
|
8
|
+
// RichText whose input slot is present. Invoked by the DOM RichText renderer after the field.
|
|
9
|
+
export function drawDomTextInputOverlay(_state, renderProxy) {
|
|
10
|
+
if (!_keyframesInjected) {
|
|
11
|
+
injectCaretBlinkKeyframes();
|
|
12
|
+
_keyframesInjected = true;
|
|
13
|
+
}
|
|
14
|
+
const source = renderProxy.source;
|
|
15
|
+
const input = getTextInputState(source);
|
|
16
|
+
if (input === null)
|
|
17
|
+
return;
|
|
18
|
+
const layout = getRichTextRuntime(source).textLayout;
|
|
19
|
+
const data = renderProxy.rendererData;
|
|
20
|
+
if ((!input.focused && !input.alwaysShowSelection) || layout === null || data?.div == null)
|
|
21
|
+
return;
|
|
22
|
+
const firstVisibleLine = source.data.scrollV - 1;
|
|
23
|
+
const scrollYOffset = firstVisibleLine > 0 ? getRichTextScrollYOffset(layout.lineHeights, firstVisibleLine) : 0;
|
|
24
|
+
const scrollXOffset = source.data.scrollH;
|
|
25
|
+
const selColor = computeRgbHexString(input.selectionColor);
|
|
26
|
+
const selAlpha = input.selectionAlpha;
|
|
27
|
+
let html = '';
|
|
28
|
+
getTextInputSelectionRectangles(selectionRectangles, source, layout);
|
|
29
|
+
for (const rect of selectionRectangles) {
|
|
30
|
+
html += `<div data-input-overlay style="position:absolute;left:${rect.x - scrollXOffset}px;top:${rect.y - scrollYOffset}px;width:${rect.width}px;height:${rect.height}px;background:${selColor};opacity:${selAlpha};pointer-events:none;"></div>`;
|
|
31
|
+
}
|
|
32
|
+
if (input.focused && getTextInputSelectionBeginIndex(source) === getTextInputSelectionEndIndex(source)) {
|
|
33
|
+
getTextInputCaretRectangle(caretRectangle, source, layout);
|
|
34
|
+
html += `<div data-input-overlay style="position:absolute;left:${caretRectangle.x - scrollXOffset}px;top:${caretRectangle.y - scrollYOffset}px;width:${input.caretWidth}px;height:${caretRectangle.height}px;background:${computeRgbHexString(input.caretColor)};animation:flight-caret-blink 1s step-end infinite;pointer-events:none;"></div>`;
|
|
35
|
+
}
|
|
36
|
+
for (const el of data.div.querySelectorAll('[data-input-overlay]'))
|
|
37
|
+
el.remove();
|
|
38
|
+
if (html.length > 0) {
|
|
39
|
+
data.div.insertAdjacentHTML('beforeend', html);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Installs the caret/selection overlay onto the DOM RichText renderer. Importing this opts an app into
|
|
43
|
+
// text-input rendering; a static RichText leaves the slot null and pulls none of this module.
|
|
44
|
+
export function enableDomTextInput() {
|
|
45
|
+
registerDomTextInputOverlay(drawDomTextInputOverlay);
|
|
46
|
+
}
|
|
47
|
+
function injectCaretBlinkKeyframes() {
|
|
48
|
+
if (typeof document === 'undefined')
|
|
49
|
+
return;
|
|
50
|
+
const id = 'flight-caret-blink-style';
|
|
51
|
+
if (document.getElementById(id))
|
|
52
|
+
return;
|
|
53
|
+
const style = document.createElement('style');
|
|
54
|
+
style.id = id;
|
|
55
|
+
style.textContent = '@keyframes flight-caret-blink{0%,100%{opacity:1}50%{opacity:0}}';
|
|
56
|
+
document.head.appendChild(style);
|
|
57
|
+
}
|
|
58
|
+
const caretRectangle = { height: 0, lineIndex: 0, width: 0, x: 0, y: 0 };
|
|
59
|
+
const selectionRectangles = [];
|
|
60
|
+
//# sourceMappingURL=domTextInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domTextInput.js","sourceRoot":"","sources":["../src/domTextInput.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DisplayObjectRenderer, DomRenderState, RenderProxy2D } from '@flighthq/types';
|
|
2
|
+
export declare function drawDomTextLabel(state: DomRenderState, renderProxy: RenderProxy2D): void;
|
|
3
|
+
export declare const defaultDomTextLabelRenderer: DisplayObjectRenderer;
|
|
4
|
+
//# sourceMappingURL=domTextLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domTextLabel.d.ts","sourceRoot":"","sources":["../src/domTextLabel.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,qBAAqB,EACrB,cAAc,EAGd,aAAa,EAKd,MAAM,iBAAiB,CAAC;AAsBzB,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAyDxF;AAED,eAAO,MAAM,2BAA2B,EAAE,qBAGzC,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { createEntity } from '@flighthq/entity';
|
|
2
|
+
import { computeRgbHexString } from '@flighthq/materials';
|
|
3
|
+
import { computeTextFormatFontString } from '@flighthq/text';
|
|
4
|
+
import { getTextLabelRuntime } from '@flighthq/text';
|
|
5
|
+
import { computeTextLayout, createTextFormatRange, getTextLayoutResult } from '@flighthq/textlayout';
|
|
6
|
+
import { applyDomStyle, prepareDomElement, setDomRendererElement } from './domStyle';
|
|
7
|
+
import { escapeDomHtmlString } from './domTextHelpers';
|
|
8
|
+
function createDomTextData(_state, _source) {
|
|
9
|
+
return createEntity({ div: null });
|
|
10
|
+
}
|
|
11
|
+
let _measureCtx = null;
|
|
12
|
+
function getMeasureCtx() {
|
|
13
|
+
if (_measureCtx === null) {
|
|
14
|
+
_measureCtx = document.createElement('canvas').getContext('2d');
|
|
15
|
+
}
|
|
16
|
+
return _measureCtx;
|
|
17
|
+
}
|
|
18
|
+
export function drawDomTextLabel(state, renderProxy) {
|
|
19
|
+
const data = renderProxy.rendererData;
|
|
20
|
+
if (data === null)
|
|
21
|
+
return;
|
|
22
|
+
const source = renderProxy.source;
|
|
23
|
+
const { text, textFormat } = source.data;
|
|
24
|
+
if (text.length === 0)
|
|
25
|
+
return;
|
|
26
|
+
const ctx = getMeasureCtx();
|
|
27
|
+
if (ctx === null)
|
|
28
|
+
return;
|
|
29
|
+
if (data.div === null) {
|
|
30
|
+
data.div = document.createElement('div');
|
|
31
|
+
prepareDomElement(data.div);
|
|
32
|
+
data.div.style.overflow = 'hidden';
|
|
33
|
+
}
|
|
34
|
+
const measure = (t, format) => {
|
|
35
|
+
ctx.font = computeTextFormatFontString(format);
|
|
36
|
+
return ctx.measureText(t).width;
|
|
37
|
+
};
|
|
38
|
+
const result = getTextLayoutResult(getTextLabelRuntime(source));
|
|
39
|
+
computeTextLayout(result, {
|
|
40
|
+
text,
|
|
41
|
+
formatRanges: [createTextFormatRange(textFormat, 0, text.length)],
|
|
42
|
+
width: source.data.width,
|
|
43
|
+
height: source.data.height,
|
|
44
|
+
measure,
|
|
45
|
+
});
|
|
46
|
+
let divWidth = 0;
|
|
47
|
+
for (const group of result.groups) {
|
|
48
|
+
const right = group.offsetX + group.width;
|
|
49
|
+
if (right > divWidth)
|
|
50
|
+
divWidth = right;
|
|
51
|
+
}
|
|
52
|
+
data.div.style.width = `${divWidth}px`;
|
|
53
|
+
data.div.style.height = `${result.textHeight}px`;
|
|
54
|
+
let html = '';
|
|
55
|
+
for (const group of result.groups) {
|
|
56
|
+
const fmt = group.format;
|
|
57
|
+
const slice = escapeDomHtmlString(text.substring(group.startIndex, group.endIndex));
|
|
58
|
+
const x = group.offsetX;
|
|
59
|
+
const y = group.offsetY;
|
|
60
|
+
let style = `position:absolute;left:${x}px;top:${y}px;font:${computeTextFormatFontString(fmt)};`;
|
|
61
|
+
style += `color:${computeRgbHexString(fmt.color ?? 0)};white-space:nowrap;`;
|
|
62
|
+
if (fmt.underline)
|
|
63
|
+
style += 'text-decoration:underline;';
|
|
64
|
+
html += `<div style="${style}">${slice}</div>`;
|
|
65
|
+
}
|
|
66
|
+
data.div.innerHTML = html;
|
|
67
|
+
applyDomStyle(state, data.div, renderProxy);
|
|
68
|
+
setDomRendererElement(state, data.div);
|
|
69
|
+
}
|
|
70
|
+
export const defaultDomTextLabelRenderer = {
|
|
71
|
+
createData: createDomTextData,
|
|
72
|
+
submit: drawDomTextLabel,
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=domTextLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domTextLabel.js","sourceRoot":"","sources":["../src/domTextLabel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Matrix } from '@flighthq/types';
|
|
2
|
+
export declare function setDomTransform(element: HTMLElement, transform: Readonly<Matrix>, roundPixels: boolean): void;
|
|
3
|
+
export declare function setDomTransformWithOffset(element: HTMLElement, transform: Readonly<Matrix>, offsetX: number, offsetY: number, roundPixels: boolean): void;
|
|
4
|
+
//# sourceMappingURL=domTransform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domTransform.d.ts","sourceRoot":"","sources":["../src/domTransform.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,wBAAgB,eAAe,CAAC,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI,CAI7G;AAED,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC3B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,OAAO,GACnB,IAAI,CASN"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function setDomTransform(element, transform, roundPixels) {
|
|
2
|
+
const tx = roundPixels ? Math.fround(transform.tx) : transform.tx;
|
|
3
|
+
const ty = roundPixels ? Math.fround(transform.ty) : transform.ty;
|
|
4
|
+
element.style.transform = `matrix(${transform.a},${transform.b},${transform.c},${transform.d},${tx},${ty})`;
|
|
5
|
+
}
|
|
6
|
+
export function setDomTransformWithOffset(element, transform, offsetX, offsetY, roundPixels) {
|
|
7
|
+
const { a, b, c, d } = transform;
|
|
8
|
+
let tx = a * offsetX + c * offsetY + transform.tx;
|
|
9
|
+
let ty = b * offsetX + d * offsetY + transform.ty;
|
|
10
|
+
if (roundPixels) {
|
|
11
|
+
tx = Math.fround(tx);
|
|
12
|
+
ty = Math.fround(ty);
|
|
13
|
+
}
|
|
14
|
+
element.style.transform = `matrix(${a},${b},${c},${d},${tx},${ty})`;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=domTransform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domTransform.js","sourceRoot":"","sources":["../src/domTransform.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,eAAe,CAAC,OAAoB,EAAE,SAA2B,EAAE,WAAoB;IACrG,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;IAClE,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC;IAClE,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,UAAU,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;AAC9G,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,OAAoB,EACpB,SAA2B,EAC3B,OAAe,EACf,OAAe,EACf,WAAoB;IAEpB,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC;IAClD,IAAI,EAAE,GAAG,CAAC,GAAG,OAAO,GAAG,CAAC,GAAG,OAAO,GAAG,SAAS,CAAC,EAAE,CAAC;IAClD,IAAI,WAAW,EAAE,CAAC;QAChB,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACrB,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACvB,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DisplayObjectRenderer, DomRenderState, RenderProxy2D } from '@flighthq/types';
|
|
2
|
+
export declare function drawDomVideo(state: DomRenderState, renderProxy: RenderProxy2D): void;
|
|
3
|
+
export declare const defaultDomVideoRenderer: DisplayObjectRenderer;
|
|
4
|
+
//# sourceMappingURL=domVideo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domVideo.d.ts","sourceRoot":"","sources":["../src/domVideo.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,cAAc,EAGd,aAAa,EAGd,MAAM,iBAAiB,CAAC;AAYzB,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAkBpF;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAGrC,CAAC"}
|
package/dist/domVideo.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createEntity } from '@flighthq/entity';
|
|
2
|
+
import { applyDomStyle, prepareDomElement, setDomRendererElement } from './domStyle';
|
|
3
|
+
function createDomVideoData(_state, _source) {
|
|
4
|
+
return createEntity({ element: null });
|
|
5
|
+
}
|
|
6
|
+
export function drawDomVideo(state, renderProxy) {
|
|
7
|
+
const data = renderProxy.rendererData;
|
|
8
|
+
if (data === null)
|
|
9
|
+
return;
|
|
10
|
+
const source = renderProxy.source;
|
|
11
|
+
const element = source.data.source?.element ?? null;
|
|
12
|
+
if (element === null || element.videoWidth === 0 || element.videoHeight === 0)
|
|
13
|
+
return;
|
|
14
|
+
if (data.element !== element) {
|
|
15
|
+
data.element = element;
|
|
16
|
+
prepareDomElement(element);
|
|
17
|
+
}
|
|
18
|
+
element.style.width = `${element.videoWidth}px`;
|
|
19
|
+
element.style.height = `${element.videoHeight}px`;
|
|
20
|
+
applyDomStyle(state, element, renderProxy);
|
|
21
|
+
setDomRendererElement(state, element);
|
|
22
|
+
}
|
|
23
|
+
export const defaultDomVideoRenderer = {
|
|
24
|
+
createData: createDomVideoData,
|
|
25
|
+
submit: drawDomVideo,
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=domVideo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domVideo.js","sourceRoot":"","sources":["../src/domVideo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAWhD,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAMrF,SAAS,kBAAkB,CAAC,MAAmB,EAAE,OAAmB;IAClE,OAAO,YAAY,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAqB,EAAE,WAA0B;IAC5E,MAAM,IAAI,GAAG,WAAW,CAAC,YAAmC,CAAC;IAC7D,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO;IAE1B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAe,CAAC;IAC3C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC;IACpD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,UAAU,KAAK,CAAC,IAAI,OAAO,CAAC,WAAW,KAAK,CAAC;QAAE,OAAO;IAEtF,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC;IAChD,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC;IAElD,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAC3C,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAA0B;IAC5D,UAAU,EAAE,kBAAkB;IAC9B,MAAM,EAAE,YAAY;CACrB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DisplayObjectRenderer, DomRenderState, RenderProxy2D } from '@flighthq/types';
|
|
2
|
+
export declare function drawDomHtmlView(state: DomRenderState, renderProxy: RenderProxy2D): void;
|
|
3
|
+
export declare const defaultHtmlViewRenderer: DisplayObjectRenderer;
|
|
4
|
+
//# sourceMappingURL=htmlView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"htmlView.d.ts","sourceRoot":"","sources":["../src/htmlView.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,cAAc,EAAY,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKtG,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,GAAG,IAAI,CAqBvF;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAGrC,CAAC"}
|
package/dist/htmlView.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { noopRendererData } from '@flighthq/render';
|
|
2
|
+
import { setDomRendererElement } from './domStyle';
|
|
3
|
+
import { setDomTransform } from './domTransform';
|
|
4
|
+
export function drawDomHtmlView(state, renderProxy) {
|
|
5
|
+
const source = renderProxy.source;
|
|
6
|
+
const data = source.data;
|
|
7
|
+
const element = data.element;
|
|
8
|
+
if (element === null)
|
|
9
|
+
return;
|
|
10
|
+
if (element.style.position !== 'absolute') {
|
|
11
|
+
element.style.left = '0';
|
|
12
|
+
element.style.overflow = 'hidden';
|
|
13
|
+
element.style.position = 'absolute';
|
|
14
|
+
element.style.top = '0';
|
|
15
|
+
element.style.transformOrigin = '0 0';
|
|
16
|
+
}
|
|
17
|
+
element.style.width = `${data.width}px`;
|
|
18
|
+
element.style.height = `${data.height}px`;
|
|
19
|
+
setDomTransform(element, renderProxy.transform2D, state.roundPixels);
|
|
20
|
+
element.style.opacity = renderProxy.alpha < 1 ? String(renderProxy.alpha) : '';
|
|
21
|
+
state.applyBlendMode?.(element, renderProxy.blendMode);
|
|
22
|
+
setDomRendererElement(state, element);
|
|
23
|
+
}
|
|
24
|
+
export const defaultHtmlViewRenderer = {
|
|
25
|
+
createData: noopRendererData,
|
|
26
|
+
submit: drawDomHtmlView,
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=htmlView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"htmlView.js","sourceRoot":"","sources":["../src/htmlView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,MAAM,UAAU,eAAe,CAAC,KAAqB,EAAE,WAA0B;IAC/E,MAAM,MAAM,GAAG,WAAW,CAAC,MAAkB,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO;IAE7B,IAAI,OAAO,CAAC,KAAK,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC1C,OAAO,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,QAAQ,GAAG,UAAU,CAAC;QACpC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC;QACxB,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC;IACxC,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC;IAC1C,eAAe,CAAC,OAAO,EAAE,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,CAAC;IACrE,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,WAAW,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/E,KAAK,CAAC,cAAc,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAEvD,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAA0B;IAC5D,UAAU,EAAE,gBAAgB;IAC5B,MAAM,EAAE,eAAe;CACxB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from './domBackground';
|
|
2
|
+
export * from './domBitmap';
|
|
3
|
+
export * from './domCache';
|
|
4
|
+
export * from './domClip';
|
|
5
|
+
export * from './domClipRectangle';
|
|
6
|
+
export * from './domCSSFilterBinding';
|
|
7
|
+
export * from './domDisplayObject';
|
|
8
|
+
export { invalidateDomFontResource } from './domFontSource';
|
|
9
|
+
export * from './domMaterials';
|
|
10
|
+
export * from './domNativeText';
|
|
11
|
+
export * from './domRenderState';
|
|
12
|
+
export * from './domRenderView';
|
|
13
|
+
export * from './domRichText';
|
|
14
|
+
export * from './domScale9Shape';
|
|
15
|
+
export * from './domShape';
|
|
16
|
+
export * from './domStyle';
|
|
17
|
+
export * from './domSvgFilter';
|
|
18
|
+
export { escapeDomHtmlString } from './domTextHelpers';
|
|
19
|
+
export * from './domTextInput';
|
|
20
|
+
export * from './domTextLabel';
|
|
21
|
+
export * from './domTransform';
|
|
22
|
+
export * from './domVideo';
|
|
23
|
+
export * from './htmlView';
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from './domBackground';
|
|
2
|
+
export * from './domBitmap';
|
|
3
|
+
export * from './domCache';
|
|
4
|
+
export * from './domClip';
|
|
5
|
+
export * from './domClipRectangle';
|
|
6
|
+
export * from './domCSSFilterBinding';
|
|
7
|
+
export * from './domDisplayObject';
|
|
8
|
+
export { invalidateDomFontResource } from './domFontSource';
|
|
9
|
+
export * from './domMaterials';
|
|
10
|
+
export * from './domNativeText';
|
|
11
|
+
export * from './domRenderState';
|
|
12
|
+
export * from './domRenderView';
|
|
13
|
+
export * from './domRichText';
|
|
14
|
+
export * from './domScale9Shape';
|
|
15
|
+
export * from './domShape';
|
|
16
|
+
export * from './domStyle';
|
|
17
|
+
export * from './domSvgFilter';
|
|
18
|
+
export { escapeDomHtmlString } from './domTextHelpers';
|
|
19
|
+
export * from './domTextInput';
|
|
20
|
+
export * from './domTextLabel';
|
|
21
|
+
export * from './domTransform';
|
|
22
|
+
export * from './domVideo';
|
|
23
|
+
export * from './htmlView';
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC;AAC3B,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@flighthq/displayobject-dom",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist",
|
|
15
|
+
"src/**/*.test.ts",
|
|
16
|
+
"!dist/**/*.test.js",
|
|
17
|
+
"!dist/**/*.test.d.ts",
|
|
18
|
+
"!dist/**/*.test.js.map",
|
|
19
|
+
"!dist/**/*.test.d.ts.map"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc -b",
|
|
23
|
+
"clean": "tsc -b --clean",
|
|
24
|
+
"test": "vitest run --config vitest.config.ts",
|
|
25
|
+
"test:watch": "vitest --watch --config vitest.config.ts",
|
|
26
|
+
"prepack": "npm run clean && npm run clean:dist && npm run build",
|
|
27
|
+
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@flighthq/displayobject": "0.1.0",
|
|
31
|
+
"@flighthq/entity": "0.1.0",
|
|
32
|
+
"@flighthq/geometry": "0.1.0",
|
|
33
|
+
"@flighthq/materials": "0.1.0",
|
|
34
|
+
"@flighthq/node": "0.1.0",
|
|
35
|
+
"@flighthq/render": "0.1.0",
|
|
36
|
+
"@flighthq/displayobject-canvas": "0.1.0",
|
|
37
|
+
"@flighthq/shape": "0.1.0",
|
|
38
|
+
"@flighthq/text": "0.1.0",
|
|
39
|
+
"@flighthq/textinput": "0.1.0",
|
|
40
|
+
"@flighthq/textlayout": "0.1.0",
|
|
41
|
+
"@flighthq/types": "0.1.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@flighthq/image": "*",
|
|
45
|
+
"typescript": "^5.3.0"
|
|
46
|
+
},
|
|
47
|
+
"description": "DOM renderer implementation",
|
|
48
|
+
"sideEffects": false
|
|
49
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { setRenderStateBackgroundColor } from '@flighthq/render';
|
|
2
|
+
|
|
3
|
+
import { renderDomBackground } from './domBackground';
|
|
4
|
+
import { createDomRenderState } from './domRenderState';
|
|
5
|
+
|
|
6
|
+
function makeState() {
|
|
7
|
+
const div = document.createElement('div');
|
|
8
|
+
return { div, state: createDomRenderState(div) };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
describe('renderDomBackground', () => {
|
|
12
|
+
it('sets element backgroundColor when background alpha is non-zero', () => {
|
|
13
|
+
const { div, state } = makeState();
|
|
14
|
+
setRenderStateBackgroundColor(state, 0xff0000ff); // opaque red
|
|
15
|
+
|
|
16
|
+
renderDomBackground(state);
|
|
17
|
+
|
|
18
|
+
expect(div.style.backgroundColor).not.toBe('');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('clears element backgroundColor when background alpha is 0', () => {
|
|
22
|
+
const { div, state } = makeState();
|
|
23
|
+
div.style.backgroundColor = 'red';
|
|
24
|
+
setRenderStateBackgroundColor(state, 0xff000000); // alpha = 0
|
|
25
|
+
|
|
26
|
+
renderDomBackground(state);
|
|
27
|
+
|
|
28
|
+
expect(div.style.backgroundColor).toBe('');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('does not throw when called with default (transparent) background', () => {
|
|
32
|
+
const { state } = makeState();
|
|
33
|
+
expect(() => renderDomBackground(state)).not.toThrow();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { createBitmap } from '@flighthq/displayobject';
|
|
2
|
+
import { createImageResource, createImageResourceFromCanvas } from '@flighthq/image';
|
|
3
|
+
import { registerRenderer } from '@flighthq/render';
|
|
4
|
+
import { getOrCreateRenderProxy2D } from '@flighthq/render';
|
|
5
|
+
import { BitmapKind } from '@flighthq/types';
|
|
6
|
+
|
|
7
|
+
import { defaultDomBitmapRenderer, drawDomBitmap } from './domBitmap';
|
|
8
|
+
import { createDomRenderState, getDomRenderStateRuntime } from './domRenderState';
|
|
9
|
+
|
|
10
|
+
function makeState(pixelRatio = 1) {
|
|
11
|
+
const container = document.createElement('div');
|
|
12
|
+
const state = createDomRenderState(container, { pixelRatio });
|
|
13
|
+
registerRenderer(state, BitmapKind, defaultDomBitmapRenderer);
|
|
14
|
+
return state;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function drawGetEl(state: ReturnType<typeof makeState>, drawFn: () => void): HTMLElement | null {
|
|
18
|
+
getDomRenderStateRuntime(state).domCurrentElement = null;
|
|
19
|
+
drawFn();
|
|
20
|
+
return getDomRenderStateRuntime(state).domCurrentElement;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function makeHtmlImageSource() {
|
|
24
|
+
const img = document.createElement('img') as HTMLImageElement;
|
|
25
|
+
img.src = 'test.png';
|
|
26
|
+
const source = createImageResource(img);
|
|
27
|
+
source.width = 64;
|
|
28
|
+
source.height = 64;
|
|
29
|
+
return source;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function makeCanvasImageSource() {
|
|
33
|
+
const canvas = document.createElement('canvas');
|
|
34
|
+
canvas.width = 64;
|
|
35
|
+
canvas.height = 64;
|
|
36
|
+
return createImageResourceFromCanvas(canvas);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('defaultDomBitmapRenderer', () => {
|
|
40
|
+
it('has submit, and createData', () => {
|
|
41
|
+
expect(typeof defaultDomBitmapRenderer.submit).toBe('function');
|
|
42
|
+
expect(typeof defaultDomBitmapRenderer.createData).toBe('function');
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
describe('drawDomBitmap', () => {
|
|
47
|
+
it('does nothing when imageSource is null', () => {
|
|
48
|
+
const state = makeState();
|
|
49
|
+
const bitmap = createBitmap();
|
|
50
|
+
bitmap.data.image = null;
|
|
51
|
+
const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
|
|
52
|
+
|
|
53
|
+
const el = drawGetEl(state, () => drawDomBitmap(state, renderProxy));
|
|
54
|
+
|
|
55
|
+
expect(el).toBeNull();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('produces an img element when source is HTMLImageElement', () => {
|
|
59
|
+
const state = makeState();
|
|
60
|
+
const bitmap = createBitmap();
|
|
61
|
+
bitmap.data.image = makeHtmlImageSource();
|
|
62
|
+
const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
|
|
63
|
+
|
|
64
|
+
const el = drawGetEl(state, () => drawDomBitmap(state, renderProxy));
|
|
65
|
+
|
|
66
|
+
expect(el).not.toBeNull();
|
|
67
|
+
expect(el!.tagName).toBe('IMG');
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('produces a canvas element when source is not HTMLImageElement', () => {
|
|
71
|
+
const state = makeState();
|
|
72
|
+
const bitmap = createBitmap();
|
|
73
|
+
bitmap.data.image = makeCanvasImageSource();
|
|
74
|
+
const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
|
|
75
|
+
|
|
76
|
+
const el = drawGetEl(state, () => drawDomBitmap(state, renderProxy));
|
|
77
|
+
|
|
78
|
+
expect(el).not.toBeNull();
|
|
79
|
+
expect(el!.tagName).toBe('CANVAS');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('reuses the same img element across multiple draws', () => {
|
|
83
|
+
const state = makeState();
|
|
84
|
+
const bitmap = createBitmap();
|
|
85
|
+
bitmap.data.image = makeHtmlImageSource();
|
|
86
|
+
const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
|
|
87
|
+
|
|
88
|
+
const firstImg = drawGetEl(state, () => drawDomBitmap(state, renderProxy));
|
|
89
|
+
const secondImg = drawGetEl(state, () => drawDomBitmap(state, renderProxy));
|
|
90
|
+
|
|
91
|
+
expect(firstImg).toBe(secondImg);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('sets canvas dimensions to match image source', () => {
|
|
95
|
+
const state = makeState();
|
|
96
|
+
const bitmap = createBitmap();
|
|
97
|
+
bitmap.data.image = makeCanvasImageSource();
|
|
98
|
+
const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
|
|
99
|
+
|
|
100
|
+
const canvas = drawGetEl(state, () => drawDomBitmap(state, renderProxy)) as HTMLCanvasElement;
|
|
101
|
+
expect(canvas.width).toBe(64);
|
|
102
|
+
expect(canvas.height).toBe(64);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('sizes the backing canvas at physical pixels and constrains layout to logical pixels on HiDPI', () => {
|
|
106
|
+
const state = makeState(2);
|
|
107
|
+
const bitmap = createBitmap();
|
|
108
|
+
bitmap.data.image = makeCanvasImageSource();
|
|
109
|
+
const renderProxy = getOrCreateRenderProxy2D(state, bitmap);
|
|
110
|
+
|
|
111
|
+
const canvas = drawGetEl(state, () => drawDomBitmap(state, renderProxy)) as HTMLCanvasElement;
|
|
112
|
+
expect(canvas.width).toBe(128);
|
|
113
|
+
expect(canvas.height).toBe(128);
|
|
114
|
+
expect(canvas.style.width).toBe('64px');
|
|
115
|
+
expect(canvas.style.height).toBe('64px');
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { getOrCreateRenderProxy2D } from '@flighthq/render';
|
|
2
|
+
import type { BitmapFilter, DisplayObject } from '@flighthq/types';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
enableDomCssFilterSupport,
|
|
6
|
+
getDomCssFilter,
|
|
7
|
+
hasDomCssFilterEquivalent,
|
|
8
|
+
setDomCssFilter,
|
|
9
|
+
} from './domCSSFilterBinding';
|
|
10
|
+
import { createDomRenderState } from './domRenderState';
|
|
11
|
+
|
|
12
|
+
function makeState() {
|
|
13
|
+
return createDomRenderState(document.createElement('div'));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe('enableDomCssFilterSupport', () => {
|
|
17
|
+
it('installs the CSS filter resolver', () => {
|
|
18
|
+
const state = makeState();
|
|
19
|
+
expect(state.domCssFilterResolver).toBeNull();
|
|
20
|
+
enableDomCssFilterSupport(state);
|
|
21
|
+
expect(state.domCssFilterResolver).toBe(getDomCssFilter);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('getDomCssFilter', () => {
|
|
26
|
+
it('returns the filter bound to a render node', () => {
|
|
27
|
+
const state = makeState();
|
|
28
|
+
const node = {} as DisplayObject;
|
|
29
|
+
setDomCssFilter(state, node, 'blur(4px)');
|
|
30
|
+
const renderProxy = getOrCreateRenderProxy2D(state, node);
|
|
31
|
+
expect(getDomCssFilter(renderProxy)).toBe('blur(4px)');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('returns undefined for a render node with no binding', () => {
|
|
35
|
+
const state = makeState();
|
|
36
|
+
const renderProxy = getOrCreateRenderProxy2D(state, {} as DisplayObject);
|
|
37
|
+
expect(getDomCssFilter(renderProxy)).toBeUndefined();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('hasDomCssFilterEquivalent', () => {
|
|
42
|
+
it('returns true for BlurFilter', () => {
|
|
43
|
+
const filter = { kind: 'BlurFilter' } as BitmapFilter;
|
|
44
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(true);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('returns true for DropShadowFilter', () => {
|
|
48
|
+
const filter = { kind: 'DropShadowFilter' } as BitmapFilter;
|
|
49
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it('returns true for OuterGlowFilter (approximated as drop-shadow with 0 offset)', () => {
|
|
53
|
+
const filter = { kind: 'OuterGlowFilter' } as BitmapFilter;
|
|
54
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('returns false for ConvolutionFilter', () => {
|
|
58
|
+
const filter = { kind: 'ConvolutionFilter' } as BitmapFilter;
|
|
59
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('returns false for DisplacementMapFilter', () => {
|
|
63
|
+
const filter = { kind: 'DisplacementMapFilter' } as BitmapFilter;
|
|
64
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('returns false for ColorMatrixFilter (use getDomSvgColorMatrixFilter for SVG-filter path)', () => {
|
|
68
|
+
const filter = { kind: 'ColorMatrixFilter' } as BitmapFilter;
|
|
69
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('returns false for an unknown filter kind', () => {
|
|
73
|
+
const filter = { kind: 'UnknownFilter' } as unknown as BitmapFilter;
|
|
74
|
+
expect(hasDomCssFilterEquivalent(filter)).toBe(false);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe('setDomCssFilter', () => {
|
|
79
|
+
it('stores a filter keyed by the per-state render node', () => {
|
|
80
|
+
const state = makeState();
|
|
81
|
+
const node = {} as DisplayObject;
|
|
82
|
+
setDomCssFilter(state, node, 'blur(2px)');
|
|
83
|
+
const renderProxy = getOrCreateRenderProxy2D(state, node);
|
|
84
|
+
expect(getDomCssFilter(renderProxy)).toBe('blur(2px)');
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('clears the binding when passed null', () => {
|
|
88
|
+
const state = makeState();
|
|
89
|
+
const node = {} as DisplayObject;
|
|
90
|
+
setDomCssFilter(state, node, 'blur(2px)');
|
|
91
|
+
setDomCssFilter(state, node, null);
|
|
92
|
+
const renderProxy = getOrCreateRenderProxy2D(state, node);
|
|
93
|
+
expect(getDomCssFilter(renderProxy)).toBeUndefined();
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('does not leak a binding across render states', () => {
|
|
97
|
+
const a = makeState();
|
|
98
|
+
const b = makeState();
|
|
99
|
+
const node = {} as DisplayObject;
|
|
100
|
+
setDomCssFilter(a, node, 'blur(2px)');
|
|
101
|
+
expect(getDomCssFilter(getOrCreateRenderProxy2D(b, node))).toBeUndefined();
|
|
102
|
+
expect(getDomCssFilter(getOrCreateRenderProxy2D(a, node))).toBe('blur(2px)');
|
|
103
|
+
});
|
|
104
|
+
});
|