@leafer-ui/node 1.4.1 → 1.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/node.esm.js CHANGED
@@ -4,7 +4,7 @@ export { LeaferImage } from '@leafer/core';
4
4
  import { writeFileSync } from 'fs';
5
5
  import { HitCanvasManager, InteractionBase } from '@leafer-ui/core';
6
6
  export * from '@leafer-ui/core';
7
- import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect, TwoPointBoundsHelper, Bounds as Bounds$1, FileHelper as FileHelper$1, TaskProcessor, Platform as Platform$1, Matrix, MathHelper as MathHelper$1, Creator as Creator$1, LeaferCanvasBase as LeaferCanvasBase$1, Debug as Debug$1, Plugin as Plugin$1, UI } from '@leafer-ui/draw';
7
+ import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect, TwoPointBoundsHelper, Bounds as Bounds$1, FileHelper as FileHelper$1, Platform as Platform$1, Matrix, MathHelper as MathHelper$1, Creator as Creator$1, TaskProcessor, Resource, LeaferCanvasBase as LeaferCanvasBase$1, Debug as Debug$1, Plugin as Plugin$1, UI } from '@leafer-ui/draw';
8
8
 
9
9
  /******************************************************************************
10
10
  Copyright (c) Microsoft Corporation.
@@ -2125,13 +2125,14 @@ function toChar(data, charX, rowData, isOverflow) {
2125
2125
  }
2126
2126
 
2127
2127
  function layoutText(drawData, style) {
2128
- const { rows, bounds } = drawData;
2128
+ const { rows, bounds } = drawData, countRows = rows.length;
2129
2129
  const { __lineHeight, __baseLine, __letterSpacing, __clipText, textAlign, verticalAlign, paraSpacing, autoSizeAlign } = style;
2130
- let { x, y, width, height } = bounds, realHeight = __lineHeight * rows.length + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2130
+ let { x, y, width, height } = bounds, realHeight = __lineHeight * countRows + (paraSpacing ? paraSpacing * (drawData.paraNumber - 1) : 0);
2131
2131
  let starY = __baseLine;
2132
2132
  if (__clipText && realHeight > height) {
2133
2133
  realHeight = Math.max(height, __lineHeight);
2134
- drawData.overflow = rows.length;
2134
+ if (countRows > 1)
2135
+ drawData.overflow = countRows;
2135
2136
  }
2136
2137
  else if (height || autoSizeAlign) {
2137
2138
  switch (verticalAlign) {
@@ -2143,7 +2144,7 @@ function layoutText(drawData, style) {
2143
2144
  }
2144
2145
  starY += y;
2145
2146
  let row, rowX, rowWidth, layoutWidth = (width || autoSizeAlign) ? width : drawData.maxWidth;
2146
- for (let i = 0, len = rows.length; i < len; i++) {
2147
+ for (let i = 0, len = countRows; i < len; i++) {
2147
2148
  row = rows[i];
2148
2149
  row.x = x;
2149
2150
  if (row.width < width || (row.width > width && !__clipText)) {
@@ -2212,7 +2213,7 @@ function clipText(drawData, style, x, width) {
2212
2213
  if (i === end && charRight < right) {
2213
2214
  break;
2214
2215
  }
2215
- else if (charRight < right && char.char !== ' ') {
2216
+ else if ((charRight < right && char.char !== ' ') || !i) {
2216
2217
  row.data.splice(i + 1);
2217
2218
  row.width -= char.width;
2218
2219
  break;
@@ -2356,124 +2357,134 @@ function getTrimBounds(canvas) {
2356
2357
  }
2357
2358
 
2358
2359
  const ExportModule = {
2359
- export(leaf, filename, options) {
2360
+ syncExport(leaf, filename, options) {
2360
2361
  this.running = true;
2362
+ let result;
2361
2363
  const fileType = FileHelper$1.fileType(filename);
2362
2364
  const isDownload = filename.includes('.');
2363
2365
  options = FileHelper$1.getExportOptions(options);
2364
- return addTask((success) => new Promise((resolve) => {
2365
- const over = (result) => {
2366
- success(result);
2367
- resolve();
2368
- this.running = false;
2369
- };
2370
- const { toURL } = Platform$1;
2371
- const { download } = Platform$1.origin;
2372
- if (fileType === 'json') {
2373
- isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2374
- return over({ data: isDownload ? true : leaf.toJSON(options.json) });
2366
+ const { toURL } = Platform$1;
2367
+ const { download } = Platform$1.origin;
2368
+ if (fileType === 'json') {
2369
+ isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2370
+ result = { data: isDownload ? true : leaf.toJSON(options.json) };
2371
+ }
2372
+ else if (fileType === 'svg') {
2373
+ isDownload && download(toURL(leaf.toSVG(), 'svg'), filename);
2374
+ result = { data: isDownload ? true : leaf.toSVG() };
2375
+ }
2376
+ else {
2377
+ let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2378
+ const { worldTransform, isLeafer, leafer, isFrame } = leaf;
2379
+ const { slice, trim, padding, onCanvas } = options;
2380
+ const smooth = options.smooth === undefined ? (leafer ? leafer.config.smooth : true) : options.smooth;
2381
+ const contextSettings = options.contextSettings || (leafer ? leafer.config.contextSettings : undefined);
2382
+ const screenshot = options.screenshot || leaf.isApp;
2383
+ const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2384
+ const needFill = FileHelper$1.isOpaqueImage(filename) || fill, matrix = new Matrix();
2385
+ if (screenshot) {
2386
+ renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2375
2387
  }
2376
- if (fileType === 'svg') {
2377
- isDownload && download(toURL(leaf.toSVG(), 'svg'), filename);
2378
- return over({ data: isDownload ? true : leaf.toSVG() });
2388
+ else {
2389
+ let relative = options.relative || (isLeafer ? 'inner' : 'local');
2390
+ scaleX = worldTransform.scaleX;
2391
+ scaleY = worldTransform.scaleY;
2392
+ switch (relative) {
2393
+ case 'inner':
2394
+ matrix.set(worldTransform);
2395
+ break;
2396
+ case 'local':
2397
+ matrix.set(worldTransform).divide(leaf.localTransform);
2398
+ scaleX /= leaf.scaleX;
2399
+ scaleY /= leaf.scaleY;
2400
+ break;
2401
+ case 'world':
2402
+ scaleX = 1;
2403
+ scaleY = 1;
2404
+ break;
2405
+ case 'page':
2406
+ relative = leafer || leaf;
2407
+ default:
2408
+ matrix.set(worldTransform).divide(leaf.getTransform(relative));
2409
+ const l = relative.worldTransform;
2410
+ scaleX /= scaleX / l.scaleX;
2411
+ scaleY /= scaleY / l.scaleY;
2412
+ }
2413
+ renderBounds = leaf.getBounds('render', relative);
2379
2414
  }
2380
- const { leafer } = leaf;
2381
- if (leafer) {
2382
- checkLazy(leaf);
2383
- leafer.waitViewCompleted(() => __awaiter(this, void 0, void 0, function* () {
2384
- let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2385
- const { worldTransform, isLeafer, isFrame } = leaf;
2386
- const { slice, trim, padding, onCanvas } = options;
2387
- const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
2388
- const contextSettings = options.contextSettings || leafer.config.contextSettings;
2389
- const screenshot = options.screenshot || leaf.isApp;
2390
- const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2391
- const needFill = FileHelper$1.isOpaqueImage(filename) || fill, matrix = new Matrix();
2392
- if (screenshot) {
2393
- renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot;
2394
- }
2395
- else {
2396
- let relative = options.relative || (isLeafer ? 'inner' : 'local');
2397
- scaleX = worldTransform.scaleX;
2398
- scaleY = worldTransform.scaleY;
2399
- switch (relative) {
2400
- case 'inner':
2401
- matrix.set(worldTransform);
2402
- break;
2403
- case 'local':
2404
- matrix.set(worldTransform).divide(leaf.localTransform);
2405
- scaleX /= leaf.scaleX;
2406
- scaleY /= leaf.scaleY;
2407
- break;
2408
- case 'world':
2409
- scaleX = 1;
2410
- scaleY = 1;
2411
- break;
2412
- case 'page':
2413
- relative = leaf.leafer;
2414
- default:
2415
- matrix.set(worldTransform).divide(leaf.getTransform(relative));
2416
- const l = relative.worldTransform;
2417
- scaleX /= scaleX / l.scaleX;
2418
- scaleY /= scaleY / l.scaleY;
2419
- }
2420
- renderBounds = leaf.getBounds('render', relative);
2421
- }
2422
- const scaleData = { scaleX: 1, scaleY: 1 };
2423
- MathHelper$1.getScaleData(options.scale, options.size, renderBounds, scaleData);
2424
- let pixelRatio = options.pixelRatio || 1;
2425
- if (leaf.isApp) {
2426
- scaleData.scaleX *= pixelRatio;
2427
- scaleData.scaleY *= pixelRatio;
2428
- pixelRatio = leaf.app.pixelRatio;
2429
- }
2430
- const { x, y, width, height } = new Bounds$1(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2431
- const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
2432
- let canvas = Creator$1.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
2433
- let sliceLeaf;
2434
- if (slice) {
2435
- sliceLeaf = leaf;
2436
- sliceLeaf.__worldOpacity = 0;
2437
- leaf = leafer;
2438
- renderOptions.bounds = canvas.bounds;
2439
- }
2440
- canvas.save();
2441
- if (isFrame && fill !== undefined) {
2442
- const oldFill = leaf.get('fill');
2443
- leaf.fill = '';
2444
- leaf.__render(canvas, renderOptions);
2445
- leaf.fill = oldFill;
2446
- }
2447
- else {
2448
- leaf.__render(canvas, renderOptions);
2449
- }
2450
- canvas.restore();
2451
- if (sliceLeaf)
2452
- sliceLeaf.__updateWorldOpacity();
2453
- if (trim) {
2454
- trimBounds = getTrimBounds(canvas);
2455
- const old = canvas, { width, height } = trimBounds;
2456
- const config = { x: 0, y: 0, width, height, pixelRatio };
2457
- canvas = Creator$1.canvas(config);
2458
- canvas.copyWorld(old, trimBounds, config);
2459
- }
2460
- if (padding) {
2461
- const [top, right, bottom, left] = MathHelper$1.fourNumber(padding);
2462
- const old = canvas, { width, height } = old;
2463
- canvas = Creator$1.canvas({ width: width + left + right, height: height + top + bottom, pixelRatio });
2464
- canvas.copyWorld(old, old.bounds, { x: left, y: top, width, height });
2465
- }
2466
- if (needFill)
2467
- canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
2468
- if (onCanvas)
2469
- onCanvas(canvas);
2470
- const data = filename === 'canvas' ? canvas : yield canvas.export(filename, options);
2471
- over({ data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds });
2472
- }));
2415
+ const scaleData = { scaleX: 1, scaleY: 1 };
2416
+ MathHelper$1.getScaleData(options.scale, options.size, renderBounds, scaleData);
2417
+ let pixelRatio = options.pixelRatio || 1;
2418
+ if (leaf.isApp) {
2419
+ scaleData.scaleX *= pixelRatio;
2420
+ scaleData.scaleY *= pixelRatio;
2421
+ pixelRatio = leaf.app.pixelRatio;
2422
+ }
2423
+ const { x, y, width, height } = new Bounds$1(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2424
+ const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
2425
+ let canvas = Creator$1.canvas({ width: Math.floor(width), height: Math.floor(height), pixelRatio, smooth, contextSettings });
2426
+ let sliceLeaf;
2427
+ if (slice) {
2428
+ sliceLeaf = leaf;
2429
+ sliceLeaf.__worldOpacity = 0;
2430
+ leaf = leafer || leaf;
2431
+ renderOptions.bounds = canvas.bounds;
2432
+ }
2433
+ canvas.save();
2434
+ if (isFrame && fill !== undefined) {
2435
+ const oldFill = leaf.get('fill');
2436
+ leaf.fill = '';
2437
+ leaf.__render(canvas, renderOptions);
2438
+ leaf.fill = oldFill;
2473
2439
  }
2474
2440
  else {
2475
- over({ data: false });
2441
+ leaf.__render(canvas, renderOptions);
2442
+ }
2443
+ canvas.restore();
2444
+ if (sliceLeaf)
2445
+ sliceLeaf.__updateWorldOpacity();
2446
+ if (trim) {
2447
+ trimBounds = getTrimBounds(canvas);
2448
+ const old = canvas, { width, height } = trimBounds;
2449
+ const config = { x: 0, y: 0, width, height, pixelRatio };
2450
+ canvas = Creator$1.canvas(config);
2451
+ canvas.copyWorld(old, trimBounds, config);
2452
+ }
2453
+ if (padding) {
2454
+ const [top, right, bottom, left] = MathHelper$1.fourNumber(padding);
2455
+ const old = canvas, { width, height } = old;
2456
+ canvas = Creator$1.canvas({ width: width + left + right, height: height + top + bottom, pixelRatio });
2457
+ canvas.copyWorld(old, old.bounds, { x: left, y: top, width, height });
2476
2458
  }
2459
+ if (needFill)
2460
+ canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over');
2461
+ if (onCanvas)
2462
+ onCanvas(canvas);
2463
+ const data = filename === 'canvas' ? canvas : canvas.export(filename, options);
2464
+ result = { data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds };
2465
+ }
2466
+ this.running = false;
2467
+ return result;
2468
+ },
2469
+ export(leaf, filename, options) {
2470
+ this.running = true;
2471
+ return addTask((success) => new Promise((resolve) => {
2472
+ const getResult = () => __awaiter(this, void 0, void 0, function* () {
2473
+ if (!Resource.isComplete)
2474
+ return Platform$1.requestRender(getResult);
2475
+ const result = ExportModule.syncExport(leaf, filename, options);
2476
+ if (result.data instanceof Promise)
2477
+ result.data = yield result.data;
2478
+ success(result);
2479
+ resolve();
2480
+ });
2481
+ leaf.updateLayout();
2482
+ checkLazy(leaf);
2483
+ const { leafer } = leaf;
2484
+ if (leafer)
2485
+ leafer.waitViewCompleted(getResult);
2486
+ else
2487
+ getResult();
2477
2488
  }));
2478
2489
  }
2479
2490
  };
@@ -2532,6 +2543,9 @@ Object.assign(Export, ExportModule);
2532
2543
  UI.prototype.export = function (filename, options) {
2533
2544
  return Export.export(this, filename, options);
2534
2545
  };
2546
+ UI.prototype.syncExport = function (filename, options) {
2547
+ return Export.syncExport(this, filename, options);
2548
+ };
2535
2549
 
2536
2550
  Object.assign(Creator, {
2537
2551
  interaction: (target, canvas, selector, options) => { return new InteractionBase(target, canvas, selector, options); },