@realnation/builder-shared-sdk 2.4.2 → 2.5.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/souvenir/index.d.ts +2 -2
- package/dist/souvenir/index.d.ts.map +1 -1
- package/dist/souvenir/index.js +5 -5
- package/dist/souvenir/render.d.ts +15 -5
- package/dist/souvenir/render.d.ts.map +1 -1
- package/dist/souvenir/render.js +40 -12
- package/dist/souvenir/types.d.ts +22 -0
- package/dist/souvenir/types.d.ts.map +1 -1
- package/dist/souvenir/types.js +13 -0
- package/package.json +64 -64
package/dist/souvenir/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export * from './types.js';
|
|
12
12
|
export * from './imageFit.js';
|
|
13
13
|
export { wrapText, tokenize, layoutLines, type MeasureText, type TextAlign, type TextVAlign, type PlacedLine, } from './text.js';
|
|
14
|
-
export { renderSouvenir, drawOrder, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
14
|
+
export { renderSouvenir, drawOrder, outputSize, regionOf, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
15
15
|
import { type SouvenirOptions, type SouvenirPage, type SouvenirResult, type SouvenirValues } from './types.js';
|
|
16
16
|
export { parseSouvenirOutputId } from './outputId.js';
|
|
17
17
|
/**
|
|
@@ -37,5 +37,5 @@ export declare function composeSouvenir(page: SouvenirPage, values?: SouvenirVal
|
|
|
37
37
|
* Anything else uploaded in the same submission must use a different tag, or
|
|
38
38
|
* it will be handed back the first file.
|
|
39
39
|
*/
|
|
40
|
-
export declare function souvenirTag(page: SouvenirPage, values?: SouvenirValues): string;
|
|
40
|
+
export declare function souvenirTag(page: SouvenirPage, values?: SouvenirValues, options?: SouvenirOptions): string;
|
|
41
41
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/souvenir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,SAAS,EACT,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EACtD,MAAM,CAAC,EAAE,MAAM,GACd,cAAc,CAUhB;AAYD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,GAAE,cAAmB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/souvenir/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,cAAc,EACd,SAAS,EACT,UAAU,EACV,QAAQ,EACR,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,cAAc,EACpB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAEtD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,YAAY,EAClB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,EACtD,MAAM,CAAC,EAAE,MAAM,GACd,cAAc,CAUhB;AAYD;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CAqBzB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,GAAE,cAAmB,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAElH"}
|
package/dist/souvenir/index.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
export * from './types.js';
|
|
12
12
|
export * from './imageFit.js';
|
|
13
13
|
export { wrapText, tokenize, layoutLines, } from './text.js';
|
|
14
|
-
export { renderSouvenir, drawOrder, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
14
|
+
export { renderSouvenir, drawOrder, outputSize, regionOf, pageHasOpaqueBackground, souvenirSignature, loadSouvenirImage, } from './render.js';
|
|
15
15
|
import { pageHasOpaqueBackground, renderSouvenir, souvenirSignature } from './render.js';
|
|
16
16
|
import { SouvenirError, } from './types.js';
|
|
17
17
|
import { parseSouvenirOutputId } from './outputId.js';
|
|
@@ -52,7 +52,7 @@ export async function composeSouvenir(page, values = {}, options = {}) {
|
|
|
52
52
|
const canvas = await renderSouvenir(page, values, options);
|
|
53
53
|
const format = options.format && options.format !== 'auto'
|
|
54
54
|
? options.format
|
|
55
|
-
: pageHasOpaqueBackground(page)
|
|
55
|
+
: pageHasOpaqueBackground(page, options.region)
|
|
56
56
|
? 'jpeg'
|
|
57
57
|
: 'png';
|
|
58
58
|
const quality = typeof options.quality === 'number' ? options.quality : 0.9;
|
|
@@ -63,7 +63,7 @@ export async function composeSouvenir(page, values = {}, options = {}) {
|
|
|
63
63
|
return {
|
|
64
64
|
file,
|
|
65
65
|
canvas,
|
|
66
|
-
tag: souvenirTag(page, values),
|
|
66
|
+
tag: souvenirTag(page, values, options),
|
|
67
67
|
width: canvas.width,
|
|
68
68
|
height: canvas.height,
|
|
69
69
|
format,
|
|
@@ -77,6 +77,6 @@ export async function composeSouvenir(page, values = {}, options = {}) {
|
|
|
77
77
|
* Anything else uploaded in the same submission must use a different tag, or
|
|
78
78
|
* it will be handed back the first file.
|
|
79
79
|
*/
|
|
80
|
-
export function souvenirTag(page, values = {}) {
|
|
81
|
-
return `souvenir-${souvenirSignature(page, values)}`;
|
|
80
|
+
export function souvenirTag(page, values = {}, options = {}) {
|
|
81
|
+
return `souvenir-${souvenirSignature(page, values, options)}`;
|
|
82
82
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* mirrors the runner's `elementStyle`, which is what the operator sees in the
|
|
10
10
|
* editor and the preview.
|
|
11
11
|
*/
|
|
12
|
-
import { type SouvenirOptions, type SouvenirPage, type SouvenirProperty, type SouvenirValues } from './types.js';
|
|
12
|
+
import { type SouvenirOptions, type SouvenirPage, type SouvenirProperty, type SouvenirRegion, type SouvenirValues } from './types.js';
|
|
13
13
|
/**
|
|
14
14
|
* An element bound to a Data field whose field has no value is left out, the
|
|
15
15
|
* way the runner hides it on a live page. Falling back to what the Builder
|
|
@@ -30,15 +30,25 @@ export declare function loadSouvenirImage(url: string, crossOrigin: string | nul
|
|
|
30
30
|
width: number;
|
|
31
31
|
height: number;
|
|
32
32
|
}>;
|
|
33
|
+
/**
|
|
34
|
+
* 整页时用它,给了区域时按区域算。区域外的元件照常留在页面上,由 runner 画。
|
|
35
|
+
*/
|
|
36
|
+
export declare function regionOf(page: SouvenirPage, region?: SouvenirRegion): SouvenirRegion;
|
|
37
|
+
/** 出图尺寸:形状跟着区域,长边取 longEdge;不给 longEdge 就按区域原尺寸。 */
|
|
38
|
+
export declare function outputSize(region: SouvenirRegion, longEdge?: number): {
|
|
39
|
+
width: number;
|
|
40
|
+
height: number;
|
|
41
|
+
scale: number;
|
|
42
|
+
};
|
|
33
43
|
/** Element ids in draw order: z-index ascending, insertion order for ties. */
|
|
34
|
-
export declare function drawOrder(page: SouvenirPage): string[];
|
|
44
|
+
export declare function drawOrder(page: SouvenirPage, region?: SouvenirRegion): string[];
|
|
35
45
|
/**
|
|
36
46
|
* True when every pixel is guaranteed opaque, i.e. a `bg` element covers the
|
|
37
47
|
* page with a colour or an image. Decides JPEG versus PNG in `auto`.
|
|
38
48
|
*/
|
|
39
|
-
export declare function pageHasOpaqueBackground(page: SouvenirPage): boolean;
|
|
40
|
-
/** A stable signature for (page, values): same inputs, same tag, same upload. */
|
|
41
|
-
export declare function souvenirSignature(page: SouvenirPage, values: SouvenirValues): string;
|
|
49
|
+
export declare function pageHasOpaqueBackground(page: SouvenirPage, region?: SouvenirRegion): boolean;
|
|
50
|
+
/** A stable signature for (page, values, region, size): same inputs, same tag, same upload. */
|
|
51
|
+
export declare function souvenirSignature(page: SouvenirPage, values: SouvenirValues, options?: SouvenirOptions): string;
|
|
42
52
|
/**
|
|
43
53
|
* Draws the page and returns the canvas.
|
|
44
54
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/souvenir/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/souvenir/render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AA6CpB;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,CAI7E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO5F;AAyPD,gFAAgF;AAChF,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAAC,iBAAiB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAoBhE;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,cAAc,CAEpF;AAED,oDAAoD;AACpD,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAStH;AAED,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,MAAM,EAAE,CAY/E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAc5F;AAED,+FAA+F;AAC/F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CAQnH;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,YAAY,EAClB,MAAM,GAAE,cAAmB,EAC3B,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,iBAAiB,CAAC,CA2E5B"}
|
package/dist/souvenir/render.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import { computeImageFitDrawRect, hashSignature, normalizeImageFit } from './imageFit.js';
|
|
13
13
|
import { parseSouvenirOutputId } from './outputId.js';
|
|
14
14
|
import { layoutLines, wrapText } from './text.js';
|
|
15
|
-
import { isSouvenirInteractive, isSouvenirSizeAllowed, SouvenirError, SOUVENIR_ELEMENT_TYPES, } from './types.js';
|
|
15
|
+
import { isInsideRegion, isSouvenirInteractive, isSouvenirSizeAllowed, SouvenirError, SOUVENIR_ELEMENT_TYPES, } from './types.js';
|
|
16
16
|
const DEFAULT_LINE_HEIGHT = 1.2;
|
|
17
17
|
const TRANSPARENT = 'TRANSPARENT';
|
|
18
18
|
const num = (value, fallback = 0) => {
|
|
@@ -281,13 +281,33 @@ export async function loadSouvenirImage(url, crossOrigin) {
|
|
|
281
281
|
image.src = url;
|
|
282
282
|
});
|
|
283
283
|
}
|
|
284
|
+
/**
|
|
285
|
+
* 整页时用它,给了区域时按区域算。区域外的元件照常留在页面上,由 runner 画。
|
|
286
|
+
*/
|
|
287
|
+
export function regionOf(page, region) {
|
|
288
|
+
return region ?? { x: 0, y: 0, width: num(page.width), height: num(page.height) };
|
|
289
|
+
}
|
|
290
|
+
/** 出图尺寸:形状跟着区域,长边取 longEdge;不给 longEdge 就按区域原尺寸。 */
|
|
291
|
+
export function outputSize(region, longEdge) {
|
|
292
|
+
const edge = Number.isFinite(longEdge) && longEdge > 0 ? longEdge : 0;
|
|
293
|
+
const longest = Math.max(region.width, region.height);
|
|
294
|
+
const scale = edge > 0 && longest > 0 ? edge / longest : 1;
|
|
295
|
+
return {
|
|
296
|
+
width: Math.max(1, Math.round(region.width * scale)),
|
|
297
|
+
height: Math.max(1, Math.round(region.height * scale)),
|
|
298
|
+
scale,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
284
301
|
/** Element ids in draw order: z-index ascending, insertion order for ties. */
|
|
285
|
-
export function drawOrder(page) {
|
|
302
|
+
export function drawOrder(page, region) {
|
|
303
|
+
const box = region;
|
|
286
304
|
return Object.keys(page.elements ?? {})
|
|
287
305
|
.filter((eid) => SOUVENIR_ELEMENT_TYPES.includes(page.elements[eid]?.type))
|
|
288
306
|
.filter((eid) => !isHidden(page.properties?.[eid] ?? {}))
|
|
289
307
|
// Controls stay on screen over the picture, so they are not in it
|
|
290
308
|
.filter((eid) => !isSouvenirInteractive(page.elements[eid]?.type, page.properties?.[eid] ?? {}))
|
|
309
|
+
// 框外的元件是页面的一部分,不进图
|
|
310
|
+
.filter((eid) => !box || isInsideRegion(page.properties?.[eid] ?? {}, box))
|
|
291
311
|
.map((eid, index) => ({ eid, index, z: num((page.properties?.[eid] ?? {})['zIndex']) }))
|
|
292
312
|
.sort((a, b) => (a.z === b.z ? a.index - b.index : a.z - b.z))
|
|
293
313
|
.map((entry) => entry.eid);
|
|
@@ -296,7 +316,8 @@ export function drawOrder(page) {
|
|
|
296
316
|
* True when every pixel is guaranteed opaque, i.e. a `bg` element covers the
|
|
297
317
|
* page with a colour or an image. Decides JPEG versus PNG in `auto`.
|
|
298
318
|
*/
|
|
299
|
-
export function pageHasOpaqueBackground(page) {
|
|
319
|
+
export function pageHasOpaqueBackground(page, region) {
|
|
320
|
+
const box = regionOf(page, region);
|
|
300
321
|
for (const eid of Object.keys(page.elements ?? {})) {
|
|
301
322
|
if (page.elements[eid]?.type !== 'bg')
|
|
302
323
|
continue;
|
|
@@ -304,7 +325,7 @@ export function pageHasOpaqueBackground(page) {
|
|
|
304
325
|
if (isHidden(property))
|
|
305
326
|
continue;
|
|
306
327
|
const geo = geometryOf(property);
|
|
307
|
-
const covers = geo.x <=
|
|
328
|
+
const covers = geo.x <= box.x && geo.y <= box.y && geo.x + geo.width >= box.x + box.width && geo.y + geo.height >= box.y + box.height;
|
|
308
329
|
if (!covers)
|
|
309
330
|
continue;
|
|
310
331
|
if (geo.opacity < 100 || geo.radius > 0 || geo.rotation)
|
|
@@ -314,10 +335,12 @@ export function pageHasOpaqueBackground(page) {
|
|
|
314
335
|
}
|
|
315
336
|
return false;
|
|
316
337
|
}
|
|
317
|
-
/** A stable signature for (page, values): same inputs, same tag, same upload. */
|
|
318
|
-
export function souvenirSignature(page, values) {
|
|
319
|
-
const
|
|
320
|
-
|
|
338
|
+
/** A stable signature for (page, values, region, size): same inputs, same tag, same upload. */
|
|
339
|
+
export function souvenirSignature(page, values, options = {}) {
|
|
340
|
+
const box = regionOf(page, options.region);
|
|
341
|
+
const size = outputSize(box, options.longEdge);
|
|
342
|
+
const parts = [`${box.x},${box.y},${box.width}x${box.height}`, `${size.width}x${size.height}`];
|
|
343
|
+
for (const eid of drawOrder(page, options.region)) {
|
|
321
344
|
parts.push(eid, page.elements[eid]?.type ?? '', JSON.stringify(page.properties?.[eid] ?? {}), String(values[eid] ?? ''));
|
|
322
345
|
}
|
|
323
346
|
return hashSignature(parts.join('|'));
|
|
@@ -333,12 +356,14 @@ export async function renderSouvenir(page, values = {}, options = {}) {
|
|
|
333
356
|
if (typeof document === 'undefined') {
|
|
334
357
|
throw new SouvenirError('no_dom', 'The souvenir composer needs a browser document.');
|
|
335
358
|
}
|
|
336
|
-
const
|
|
337
|
-
const
|
|
359
|
+
const box = regionOf(page, options.region);
|
|
360
|
+
const size = outputSize(box, options.longEdge);
|
|
361
|
+
const width = size.width;
|
|
362
|
+
const height = size.height;
|
|
338
363
|
if (!isSouvenirSizeAllowed(width, height)) {
|
|
339
|
-
throw new SouvenirError(width < 1 || height < 1 ? 'bad_size' : 'too_large', `Souvenir
|
|
364
|
+
throw new SouvenirError(width < 1 || height < 1 ? 'bad_size' : 'too_large', `Souvenir image size ${width}x${height} is out of range.`);
|
|
340
365
|
}
|
|
341
|
-
const order = drawOrder(page);
|
|
366
|
+
const order = drawOrder(page, options.region);
|
|
342
367
|
// Webfonts first: measuring before they land silently lays the text out in
|
|
343
368
|
// the fallback font and the first souvenir of an event comes out wrong.
|
|
344
369
|
if (!options.skipFontWait && typeof document !== 'undefined' && document.fonts?.ready) {
|
|
@@ -368,6 +393,9 @@ export async function renderSouvenir(page, values = {}, options = {}) {
|
|
|
368
393
|
const ctx = canvas.getContext('2d');
|
|
369
394
|
if (!ctx)
|
|
370
395
|
throw new SouvenirError('canvas_unavailable', 'Could not get a 2d context.');
|
|
396
|
+
// 元件坐标是页面坐标:先按出图倍数放大,再把框的左上角移到画布原点。描边宽度与字号
|
|
397
|
+
// 跟着这一层变换等比放大,所以各元件照页面坐标画就行。
|
|
398
|
+
ctx.setTransform(size.scale, 0, 0, size.scale, -box.x * size.scale, -box.y * size.scale);
|
|
371
399
|
for (const eid of order) {
|
|
372
400
|
const type = page.elements[eid]?.type ?? '';
|
|
373
401
|
const property = page.properties?.[eid] ?? {};
|
package/dist/souvenir/types.d.ts
CHANGED
|
@@ -55,12 +55,34 @@ export interface SouvenirPage {
|
|
|
55
55
|
*/
|
|
56
56
|
export type SouvenirValues = Record<string, string | null | undefined>;
|
|
57
57
|
export type SouvenirFormat = 'auto' | 'jpeg' | 'png';
|
|
58
|
+
/**
|
|
59
|
+
* The part of the page that becomes the image, in the page's own coordinates.
|
|
60
|
+
*
|
|
61
|
+
* A module that lays the souvenir out on a page participants see marks a frame
|
|
62
|
+
* on it: what is inside becomes the picture, what is outside stays a normal
|
|
63
|
+
* page (PF 2026-09-18). Left out, the whole page is composed.
|
|
64
|
+
*/
|
|
65
|
+
export interface SouvenirRegion {
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
width: number;
|
|
69
|
+
height: number;
|
|
70
|
+
}
|
|
71
|
+
/** 一个元件算不算在框里:按中心点判定(PF 2026-09-18),画的时候再按框裁切。 */
|
|
72
|
+
export declare function isInsideRegion(property: SouvenirProperty, region: SouvenirRegion): boolean;
|
|
58
73
|
export interface SouvenirOptions {
|
|
59
74
|
/**
|
|
60
75
|
* `auto` (default) picks JPEG unless the page has no opaque background, in
|
|
61
76
|
* which case the transparency has to survive and PNG wins.
|
|
62
77
|
*/
|
|
63
78
|
format?: SouvenirFormat;
|
|
79
|
+
/** 只合成页面上的这一块。不给就是整页(Live Input 的离屏页走这一条)。 */
|
|
80
|
+
region?: SouvenirRegion;
|
|
81
|
+
/**
|
|
82
|
+
* 出图的长边像素。短边按区域比例算,所以运营改框的形状不必再改这个数。
|
|
83
|
+
* 不给就按区域的原始尺寸出图。
|
|
84
|
+
*/
|
|
85
|
+
longEdge?: number;
|
|
64
86
|
/** JPEG quality, 0 to 1. Default 0.9. */
|
|
65
87
|
quality?: number;
|
|
66
88
|
/** File name handed to the upload endpoint. Extension is set from the format. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/souvenir/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,8FAQzB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1E;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,8CAA+C,CAAC;AAKvF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,QAAQ,GAAE,gBAAqB,GAAG,OAAO,CAG/G;AAED,uFAAuF;AACvF,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvD,iEAAiE;AACjE,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,mFAAmF;IACnF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAEvE,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAErD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,wGAAwG;IACxG,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,iBAAiB,CAAC;IAC1B,oFAAoF;IACpF,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,0EAA0E;AAC1E,qBAAa,aAAc,SAAQ,KAAK;aAEpB,IAAI,EAChB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,eAAe;gBANH,IAAI,EAChB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,oBAAoB,GACpB,cAAc,GACd,eAAe,EACnB,OAAO,EAAE,MAAM;CAKlB;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,WAAa,CAAC;AAE5C,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAK5E;AAED,4DAA4D;AAC5D,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,EAAE,CAW5E"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/souvenir/types.ts"],"names":[],"mappings":"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"}
|
package/dist/souvenir/types.js
CHANGED
|
@@ -40,6 +40,19 @@ export function isSouvenirInteractive(type, property = {}) {
|
|
|
40
40
|
return true;
|
|
41
41
|
return INTERACTIVE_PROPERTIES.some((key) => String(property?.[key] ?? '').trim() !== '');
|
|
42
42
|
}
|
|
43
|
+
/** 一个元件算不算在框里:按中心点判定(PF 2026-09-18),画的时候再按框裁切。 */
|
|
44
|
+
export function isInsideRegion(property, region) {
|
|
45
|
+
const num = (value) => {
|
|
46
|
+
const parsed = typeof value === 'number' ? value : parseFloat(String(value ?? ''));
|
|
47
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
48
|
+
};
|
|
49
|
+
const centerX = num(property['x-position']) + num(property['width']) / 2;
|
|
50
|
+
const centerY = num(property['y-position']) + num(property['height']) / 2;
|
|
51
|
+
return (centerX >= region.x &&
|
|
52
|
+
centerX <= region.x + region.width &&
|
|
53
|
+
centerY >= region.y &&
|
|
54
|
+
centerY <= region.y + region.height);
|
|
55
|
+
}
|
|
43
56
|
/** Thrown for every refusal the caller is expected to handle and show. */
|
|
44
57
|
export class SouvenirError extends Error {
|
|
45
58
|
code;
|
package/package.json
CHANGED
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@realnation/builder-shared-sdk",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"private": false,
|
|
6
|
-
"exports": {
|
|
7
|
-
"./package.json": "./package.json",
|
|
8
|
-
".": {
|
|
9
|
-
"types": "./dist/index.d.ts",
|
|
10
|
-
"import": "./dist/index.js"
|
|
11
|
-
},
|
|
12
|
-
"./runtime": {
|
|
13
|
-
"types": "./dist/runtime/index.d.ts",
|
|
14
|
-
"import": "./dist/runtime/index.js"
|
|
15
|
-
},
|
|
16
|
-
"./runtime/vue": {
|
|
17
|
-
"types": "./dist/runtime/vue/index.d.ts",
|
|
18
|
-
"import": "./dist/runtime/vue/index.js"
|
|
19
|
-
},
|
|
20
|
-
"./interaction": {
|
|
21
|
-
"types": "./dist/interaction/index.d.ts",
|
|
22
|
-
"import": "./dist/interaction/index.js"
|
|
23
|
-
},
|
|
24
|
-
"./interaction/vue": {
|
|
25
|
-
"types": "./dist/interaction/vue.d.ts",
|
|
26
|
-
"import": "./dist/interaction/vue.js"
|
|
27
|
-
},
|
|
28
|
-
"./souvenir": {
|
|
29
|
-
"types": "./dist/souvenir/index.d.ts",
|
|
30
|
-
"import": "./dist/souvenir/index.js"
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
"files": [
|
|
34
|
-
"dist"
|
|
35
|
-
],
|
|
36
|
-
"scripts": {
|
|
37
|
-
"build": "tsc -p tsconfig.json",
|
|
38
|
-
"clean": "rimraf dist",
|
|
39
|
-
"test": "vitest run",
|
|
40
|
-
"test:watch": "vitest",
|
|
41
|
-
"prepublishOnly": "npm run clean && npm run test && npm run build",
|
|
42
|
-
"prepare": "npm run clean && npm run build"
|
|
43
|
-
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"ali-oss": "^6.23.0",
|
|
46
|
-
"axios": "^1.7.7"
|
|
47
|
-
},
|
|
48
|
-
"peerDependencies": {
|
|
49
|
-
"vue": "^3.4.0"
|
|
50
|
-
},
|
|
51
|
-
"peerDependenciesMeta": {
|
|
52
|
-
"vue": {
|
|
53
|
-
"optional": true
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
"devDependencies": {
|
|
57
|
-
"@types/ali-oss": "^6.16.11",
|
|
58
|
-
"@types/node": "^26.1.2",
|
|
59
|
-
"rimraf": "^5.0.5",
|
|
60
|
-
"typescript": "^5.4.5",
|
|
61
|
-
"vitest": "^2.1.0",
|
|
62
|
-
"vue": "^3.4.0"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@realnation/builder-shared-sdk",
|
|
3
|
+
"version": "2.5.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"private": false,
|
|
6
|
+
"exports": {
|
|
7
|
+
"./package.json": "./package.json",
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./runtime": {
|
|
13
|
+
"types": "./dist/runtime/index.d.ts",
|
|
14
|
+
"import": "./dist/runtime/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./runtime/vue": {
|
|
17
|
+
"types": "./dist/runtime/vue/index.d.ts",
|
|
18
|
+
"import": "./dist/runtime/vue/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./interaction": {
|
|
21
|
+
"types": "./dist/interaction/index.d.ts",
|
|
22
|
+
"import": "./dist/interaction/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./interaction/vue": {
|
|
25
|
+
"types": "./dist/interaction/vue.d.ts",
|
|
26
|
+
"import": "./dist/interaction/vue.js"
|
|
27
|
+
},
|
|
28
|
+
"./souvenir": {
|
|
29
|
+
"types": "./dist/souvenir/index.d.ts",
|
|
30
|
+
"import": "./dist/souvenir/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsc -p tsconfig.json",
|
|
38
|
+
"clean": "rimraf dist",
|
|
39
|
+
"test": "vitest run",
|
|
40
|
+
"test:watch": "vitest",
|
|
41
|
+
"prepublishOnly": "npm run clean && npm run test && npm run build",
|
|
42
|
+
"prepare": "npm run clean && npm run build"
|
|
43
|
+
},
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"ali-oss": "^6.23.0",
|
|
46
|
+
"axios": "^1.7.7"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"vue": "^3.4.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependenciesMeta": {
|
|
52
|
+
"vue": {
|
|
53
|
+
"optional": true
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/ali-oss": "^6.16.11",
|
|
58
|
+
"@types/node": "^26.1.2",
|
|
59
|
+
"rimraf": "^5.0.5",
|
|
60
|
+
"typescript": "^5.4.5",
|
|
61
|
+
"vitest": "^2.1.0",
|
|
62
|
+
"vue": "^3.4.0"
|
|
63
|
+
}
|
|
64
|
+
}
|