@leafer-draw/miniapp 1.0.1 → 1.0.3

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.
@@ -1,4 +1,4 @@
1
- import { LeaferCanvasBase, Platform, canvasPatch, DataHelper, canvasSizeAttrs, ResizeEvent, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, AnimateEvent, BoundsHelper, MatrixHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
1
+ import { LeaferCanvasBase, Platform, canvasPatch, DataHelper, canvasSizeAttrs, ResizeEvent, Creator, LeaferImage, defineKey, FileHelper, LeafList, RenderEvent, ChildEvent, WatchEvent, PropertyEvent, LeafHelper, BranchHelper, Bounds, LeafBoundsHelper, Debug, LeafLevelList, LayoutEvent, Run, ImageManager, BoundsHelper, MatrixHelper, MathHelper, AlignHelper, ImageEvent, AroundHelper, PointHelper, Direction4, TwoPointBoundsHelper, TaskProcessor, Matrix } from '@leafer/core';
2
2
  export * from '@leafer/core';
3
3
  export { LeaferImage } from '@leafer/core';
4
4
  import { PaintImage, ColorConvert, PaintGradient, Export, Group, TextConvert, Paint, Effect } from '@leafer-ui/draw';
@@ -43,6 +43,8 @@ class LeaferCanvas extends LeaferCanvasBase {
43
43
  const size = { width: width || view.width, height: height || view.height, pixelRatio };
44
44
  this.resize(size);
45
45
  if (this.context) {
46
+ if (this.viewSelect)
47
+ Platform.renderCanvas = this;
46
48
  if (this.context.roundRect) {
47
49
  this.roundRect = function (x, y, width, height, radius) {
48
50
  this.context.roundRect(x, y, width, height, typeof radius === 'number' ? [radius] : radius);
@@ -110,119 +112,120 @@ Object.assign(Creator, {
110
112
  image: (options) => new LeaferImage(options)
111
113
  });
112
114
  function useCanvas(_canvasType, app) {
113
- if (!Platform.origin) {
114
- Platform.origin = {
115
- createCanvas: (width, height, _format) => app.createOffscreenCanvas({ type: '2d', width, height }),
116
- canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
117
- canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
118
- canvasSaveAs: (canvas, filePath, quality) => {
119
- let data = canvas.toDataURL(mineType(fileType(filePath)), quality);
120
- data = data.substring(data.indexOf('64,') + 3);
121
- return Platform.origin.download(data, filePath);
122
- },
123
- download(data, filePath) {
124
- return new Promise((resolve, reject) => {
125
- let toAlbum;
126
- if (!filePath.includes('/')) {
127
- filePath = `${app.env.USER_DATA_PATH}/` + filePath;
128
- toAlbum = true;
129
- }
130
- const fs = app.getFileSystemManager();
131
- fs.writeFile({
132
- filePath,
133
- data,
134
- encoding: 'base64',
135
- success() {
136
- if (toAlbum) {
137
- Platform.miniapp.saveToAlbum(filePath).then(() => {
138
- fs.unlink({ filePath });
139
- resolve();
140
- });
141
- }
142
- else {
115
+ Platform.origin = {
116
+ createCanvas: (width, height, _format) => app.createOffscreenCanvas({ type: '2d', width, height }),
117
+ canvasToDataURL: (canvas, type, quality) => canvas.toDataURL(mineType(type), quality),
118
+ canvasToBolb: (canvas, type, quality) => canvas.toBuffer(type, { quality }),
119
+ canvasSaveAs: (canvas, filePath, quality) => {
120
+ let data = canvas.toDataURL(mineType(fileType(filePath)), quality);
121
+ data = data.substring(data.indexOf('64,') + 3);
122
+ return Platform.origin.download(data, filePath);
123
+ },
124
+ download(data, filePath) {
125
+ return new Promise((resolve, reject) => {
126
+ let toAlbum;
127
+ if (!filePath.includes('/')) {
128
+ filePath = `${app.env.USER_DATA_PATH}/` + filePath;
129
+ toAlbum = true;
130
+ }
131
+ const fs = app.getFileSystemManager();
132
+ fs.writeFile({
133
+ filePath,
134
+ data,
135
+ encoding: 'base64',
136
+ success() {
137
+ if (toAlbum) {
138
+ Platform.miniapp.saveToAlbum(filePath).then(() => {
139
+ fs.unlink({ filePath });
143
140
  resolve();
144
- }
145
- },
146
- fail(error) {
147
- reject(error);
141
+ });
148
142
  }
149
- });
150
- });
151
- },
152
- loadImage(src) {
153
- return new Promise((resolve, reject) => {
154
- const img = Platform.canvas.view.createImage();
155
- img.onload = () => { resolve(img); };
156
- img.onerror = (error) => { reject(error); };
157
- img.src = Platform.image.getRealURL(src);
143
+ else {
144
+ resolve();
145
+ }
146
+ },
147
+ fail(error) {
148
+ reject(error);
149
+ }
158
150
  });
159
- },
160
- noRepeat: 'repeat-x'
161
- };
162
- Platform.miniapp = {
163
- select(name) {
164
- return app.createSelectorQuery().select(name);
165
- },
166
- getBounds(select) {
167
- return new Promise((resolve) => {
168
- select.boundingClientRect().exec((res) => {
169
- const rect = res[1];
170
- resolve({ x: rect.top, y: rect.left, width: rect.width, height: rect.height });
171
- });
151
+ });
152
+ },
153
+ loadImage(src) {
154
+ return new Promise((resolve, reject) => {
155
+ const img = Platform.canvas.view.createImage();
156
+ img.onload = () => { resolve(img); };
157
+ img.onerror = (error) => { reject(error); };
158
+ img.src = Platform.image.getRealURL(src);
159
+ });
160
+ },
161
+ noRepeat: 'repeat-x'
162
+ };
163
+ Platform.miniapp = {
164
+ select(name) {
165
+ return app.createSelectorQuery().select(name);
166
+ },
167
+ getBounds(select) {
168
+ return new Promise((resolve) => {
169
+ select.boundingClientRect().exec((res) => {
170
+ const rect = res[1];
171
+ resolve({ x: rect.top, y: rect.left, width: rect.width, height: rect.height });
172
172
  });
173
- },
174
- getSizeView(select) {
175
- return new Promise((resolve) => {
176
- select.fields({ node: true, size: true }).exec((res) => {
177
- const data = res[0];
178
- resolve({ view: data.node, width: data.width, height: data.height });
179
- });
173
+ });
174
+ },
175
+ getSizeView(select) {
176
+ return new Promise((resolve) => {
177
+ select.fields({ node: true, size: true }).exec((res) => {
178
+ const data = res[0];
179
+ resolve({ view: data.node, width: data.width, height: data.height });
180
180
  });
181
- },
182
- saveToAlbum(path) {
183
- return new Promise((resolve) => {
184
- app.getSetting({
185
- success: (res) => {
186
- if (res.authSetting['scope.writePhotosAlbum']) {
187
- app.saveImageToPhotosAlbum({
188
- filePath: path,
189
- success() { resolve(true); }
190
- });
191
- }
192
- else {
193
- app.authorize({
194
- scope: 'scope.writePhotosAlbum',
195
- success: () => {
196
- app.saveImageToPhotosAlbum({
197
- filePath: path,
198
- success() { resolve(true); }
199
- });
200
- },
201
- fail: () => { }
202
- });
203
- }
181
+ });
182
+ },
183
+ saveToAlbum(path) {
184
+ return new Promise((resolve) => {
185
+ app.getSetting({
186
+ success: (res) => {
187
+ if (res.authSetting['scope.writePhotosAlbum']) {
188
+ app.saveImageToPhotosAlbum({
189
+ filePath: path,
190
+ success() { resolve(true); }
191
+ });
204
192
  }
205
- });
193
+ else {
194
+ app.authorize({
195
+ scope: 'scope.writePhotosAlbum',
196
+ success: () => {
197
+ app.saveImageToPhotosAlbum({
198
+ filePath: path,
199
+ success() { resolve(true); }
200
+ });
201
+ },
202
+ fail: () => { }
203
+ });
204
+ }
205
+ }
206
206
  });
207
- },
208
- onWindowResize(fun) {
209
- app.onWindowResize(fun);
210
- },
211
- offWindowResize(fun) {
212
- app.offWindowResize(fun);
213
- }
214
- };
215
- Platform.event = {
216
- stopDefault(_origin) { },
217
- stopNow(_origin) { },
218
- stop(_origin) { }
219
- };
220
- Platform.canvas = Creator.canvas();
221
- Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
222
- }
207
+ });
208
+ },
209
+ onWindowResize(fun) {
210
+ app.onWindowResize(fun);
211
+ },
212
+ offWindowResize(fun) {
213
+ app.offWindowResize(fun);
214
+ }
215
+ };
216
+ Platform.event = {
217
+ stopDefault(_origin) { },
218
+ stopNow(_origin) { },
219
+ stop(_origin) { }
220
+ };
221
+ Platform.canvas = Creator.canvas();
222
+ Platform.conicGradientSupport = !!Platform.canvas.context.createConicGradient;
223
223
  }
224
224
  Platform.name = 'miniapp';
225
- Platform.requestRender = function (render) { Platform.canvas.view.requestAnimationFrame(render); };
225
+ Platform.requestRender = function (render) {
226
+ const { view } = (Platform.renderCanvas || Platform.canvas);
227
+ view.requestAnimationFrame ? view.requestAnimationFrame(render) : setTimeout(render, 16);
228
+ };
226
229
  defineKey(Platform, 'devicePixelRatio', { get() { return Math.max(1, wx.getSystemInfoSync().pixelRatio); } });
227
230
 
228
231
  class Watcher {
@@ -363,9 +366,13 @@ function updateBounds(boundsList) {
363
366
  });
364
367
  }
365
368
  function updateChange(updateList) {
369
+ let layout;
366
370
  updateList.list.forEach(leaf => {
367
- if (leaf.__layout.opacityChanged)
371
+ layout = leaf.__layout;
372
+ if (layout.opacityChanged)
368
373
  updateAllWorldOpacity(leaf);
374
+ if (layout.stateStyleChanged)
375
+ setTimeout(() => layout.stateStyleChanged && leaf.updateState());
369
376
  leaf.__updateChange();
370
377
  });
371
378
  }
@@ -731,7 +738,6 @@ class Renderer {
731
738
  Platform.requestRender(() => {
732
739
  this.FPS = Math.min(60, Math.ceil(1000 / (Date.now() - startTime)));
733
740
  if (this.running) {
734
- this.target.emit(AnimateEvent.FRAME);
735
741
  if (this.changed && this.canvas.view)
736
742
  this.render();
737
743
  this.target.emit(RenderEvent.NEXT);
@@ -1156,16 +1162,21 @@ function repeatMode(data, box, width, height, x, y, scaleX, scaleY, rotation, al
1156
1162
  const { get: get$2, translate } = MatrixHelper;
1157
1163
  const tempBox = new Bounds();
1158
1164
  const tempPoint = {};
1165
+ const tempScaleData = {};
1159
1166
  function createData(leafPaint, image, paint, box) {
1160
- const { blendMode } = paint;
1167
+ const { blendMode, sync } = paint;
1161
1168
  if (blendMode)
1162
1169
  leafPaint.blendMode = blendMode;
1170
+ if (sync)
1171
+ leafPaint.sync = sync;
1163
1172
  leafPaint.data = getPatternData(paint, box, image);
1164
1173
  }
1165
1174
  function getPatternData(paint, box, image) {
1166
1175
  let { width, height } = image;
1167
1176
  if (paint.padding)
1168
1177
  box = tempBox.set(box).shrink(paint.padding);
1178
+ if (paint.mode === 'strench')
1179
+ paint.mode = 'stretch';
1169
1180
  const { opacity, mode, align, offset, scale, size, rotation, repeat } = paint;
1170
1181
  const sameBox = box.width === width && box.height === height;
1171
1182
  const data = { mode };
@@ -1179,13 +1190,10 @@ function getPatternData(paint, box, image) {
1179
1190
  x += (box.width - width * scaleX) / 2, y += (box.height - height * scaleY) / 2;
1180
1191
  }
1181
1192
  }
1182
- else if (size) {
1183
- scaleX = (typeof size === 'number' ? size : size.width) / width;
1184
- scaleY = (typeof size === 'number' ? size : size.height) / height;
1185
- }
1186
- else if (scale) {
1187
- scaleX = typeof scale === 'number' ? scale : scale.x;
1188
- scaleY = typeof scale === 'number' ? scale : scale.y;
1193
+ else if (scale || size) {
1194
+ MathHelper.getScaleData(scale, size, image, tempScaleData);
1195
+ scaleX = tempScaleData.scaleX;
1196
+ scaleY = tempScaleData.scaleY;
1189
1197
  }
1190
1198
  if (align) {
1191
1199
  const imageBounds = { x, y, width: swapWidth, height: swapHeight };
@@ -1197,7 +1205,7 @@ function getPatternData(paint, box, image) {
1197
1205
  if (offset)
1198
1206
  x += offset.x, y += offset.y;
1199
1207
  switch (mode) {
1200
- case 'strench':
1208
+ case 'stretch':
1201
1209
  if (!sameBox)
1202
1210
  width = box.width, height = box.height;
1203
1211
  break;
@@ -1224,7 +1232,7 @@ function getPatternData(paint, box, image) {
1224
1232
  translate(data.transform, box.x, box.y);
1225
1233
  }
1226
1234
  }
1227
- if (scaleX && mode !== 'strench') {
1235
+ if (scaleX && mode !== 'stretch') {
1228
1236
  data.scaleX = scaleX;
1229
1237
  data.scaleY = scaleY;
1230
1238
  }
@@ -1328,7 +1336,7 @@ const { get: get$1, scale, copy: copy$1 } = MatrixHelper;
1328
1336
  const { ceil, abs: abs$1 } = Math;
1329
1337
  function createPattern(ui, paint, pixelRatio) {
1330
1338
  let { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1331
- const id = scaleX + '-' + scaleY;
1339
+ const id = scaleX + '-' + scaleY + '-' + pixelRatio;
1332
1340
  if (paint.patternId !== id && !ui.destroyed) {
1333
1341
  scaleX = abs$1(scaleX);
1334
1342
  scaleY = abs$1(scaleY);
@@ -1422,7 +1430,8 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
1422
1430
  const { abs } = Math;
1423
1431
  function checkImage(ui, canvas, paint, allowPaint) {
1424
1432
  const { scaleX, scaleY } = ImageManager.patternLocked ? ui.__world : ui.__nowWorld;
1425
- if (!paint.data || (paint.patternId === scaleX + '-' + scaleY && !Export.running)) {
1433
+ const { pixelRatio } = canvas;
1434
+ if (!paint.data || (paint.patternId === scaleX + '-' + scaleY + '-' + pixelRatio && !Export.running)) {
1426
1435
  return false;
1427
1436
  }
1428
1437
  else {
@@ -1430,8 +1439,8 @@ function checkImage(ui, canvas, paint, allowPaint) {
1430
1439
  if (allowPaint) {
1431
1440
  if (!data.repeat) {
1432
1441
  let { width, height } = data;
1433
- width *= abs(scaleX) * canvas.pixelRatio;
1434
- height *= abs(scaleY) * canvas.pixelRatio;
1442
+ width *= abs(scaleX) * pixelRatio;
1443
+ height *= abs(scaleY) * pixelRatio;
1435
1444
  if (data.scaleX) {
1436
1445
  width *= data.scaleX;
1437
1446
  height *= data.scaleY;
@@ -1456,15 +1465,15 @@ function checkImage(ui, canvas, paint, allowPaint) {
1456
1465
  return true;
1457
1466
  }
1458
1467
  else {
1459
- if (!paint.style || Export.running) {
1460
- createPattern(ui, paint, canvas.pixelRatio);
1468
+ if (!paint.style || paint.sync || Export.running) {
1469
+ createPattern(ui, paint, pixelRatio);
1461
1470
  }
1462
1471
  else {
1463
1472
  if (!paint.patternTask) {
1464
1473
  paint.patternTask = ImageManager.patternTasker.add(() => __awaiter(this, void 0, void 0, function* () {
1465
1474
  paint.patternTask = null;
1466
1475
  if (canvas.bounds.hit(ui.__nowWorld))
1467
- createPattern(ui, paint, canvas.pixelRatio);
1476
+ createPattern(ui, paint, pixelRatio);
1468
1477
  ui.forceUpdate('surface');
1469
1478
  }), 300);
1470
1479
  }
@@ -1528,14 +1537,16 @@ function linearGradient(paint, box) {
1528
1537
  return data;
1529
1538
  }
1530
1539
  function applyStops(gradient, stops, opacity) {
1531
- let stop;
1532
- for (let i = 0, len = stops.length; i < len; i++) {
1533
- stop = stops[i];
1534
- if (typeof stop === 'string') {
1535
- gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
1536
- }
1537
- else {
1538
- gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1540
+ if (stops) {
1541
+ let stop;
1542
+ for (let i = 0, len = stops.length; i < len; i++) {
1543
+ stop = stops[i];
1544
+ if (typeof stop === 'string') {
1545
+ gradient.addColorStop(i / (len - 1), ColorConvert.string(stop, opacity));
1546
+ }
1547
+ else {
1548
+ gradient.addColorStop(stop.offset, ColorConvert.string(stop.color, opacity));
1549
+ }
1539
1550
  }
1540
1551
  }
1541
1552
  }
@@ -2291,10 +2302,15 @@ const TextConvertModule = {
2291
2302
  };
2292
2303
 
2293
2304
  function string(color, opacity) {
2294
- if (typeof color === 'string')
2295
- return color;
2305
+ const doOpacity = typeof opacity === 'number' && opacity !== 1;
2306
+ if (typeof color === 'string') {
2307
+ if (doOpacity && ColorConvert.object)
2308
+ color = ColorConvert.object(color);
2309
+ else
2310
+ return color;
2311
+ }
2296
2312
  let a = color.a === undefined ? 1 : color.a;
2297
- if (opacity)
2313
+ if (doOpacity)
2298
2314
  a *= opacity;
2299
2315
  const rgb = color.r + ',' + color.g + ',' + color.b;
2300
2316
  return a === 1 ? 'rgb(' + rgb + ')' : 'rgba(' + rgb + ',' + a + ')';
@@ -2326,6 +2342,7 @@ const ExportModule = {
2326
2342
  export(leaf, filename, options) {
2327
2343
  this.running = true;
2328
2344
  const fileType = FileHelper.fileType(filename);
2345
+ const isDownload = filename.includes('.');
2329
2346
  options = FileHelper.getExportOptions(options);
2330
2347
  return addTask((success) => new Promise((resolve) => {
2331
2348
  const over = (result) => {
@@ -2335,19 +2352,13 @@ const ExportModule = {
2335
2352
  };
2336
2353
  const { toURL } = Platform;
2337
2354
  const { download } = Platform.origin;
2338
- if (filename === 'json') {
2339
- return over({ data: leaf.toJSON(options.json) });
2340
- }
2341
- else if (fileType === 'json') {
2342
- download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2343
- return over({ data: true });
2355
+ if (fileType === 'json') {
2356
+ isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename);
2357
+ return over({ data: isDownload ? true : leaf.toJSON(options.json) });
2344
2358
  }
2345
- if (filename === 'svg') {
2346
- return over({ data: leaf.toSVG() });
2347
- }
2348
- else if (fileType === 'svg') {
2349
- download(toURL(leaf.toSVG(), 'svg'), filename);
2350
- return over({ data: true });
2359
+ if (fileType === 'svg') {
2360
+ isDownload && download(toURL(leaf.toSVG(), 'svg'), filename);
2361
+ return over({ data: isDownload ? true : leaf.toSVG() });
2351
2362
  }
2352
2363
  const { leafer } = leaf;
2353
2364
  if (leafer) {
@@ -2356,14 +2367,8 @@ const ExportModule = {
2356
2367
  let renderBounds, trimBounds, scaleX = 1, scaleY = 1;
2357
2368
  const { worldTransform, isLeafer, isFrame } = leaf;
2358
2369
  const { slice, trim, onCanvas } = options;
2359
- let scale = options.scale || 1;
2360
- let pixelRatio = options.pixelRatio || 1;
2361
2370
  const smooth = options.smooth === undefined ? leafer.config.smooth : options.smooth;
2362
2371
  const contextSettings = options.contextSettings || leafer.config.contextSettings;
2363
- if (leaf.isApp) {
2364
- scale *= pixelRatio;
2365
- pixelRatio = leaf.app.pixelRatio;
2366
- }
2367
2372
  const screenshot = options.screenshot || leaf.isApp;
2368
2373
  const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill;
2369
2374
  const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix();
@@ -2397,9 +2402,17 @@ const ExportModule = {
2397
2402
  }
2398
2403
  renderBounds = leaf.getBounds('render', relative);
2399
2404
  }
2400
- const { x, y, width, height } = new Bounds(renderBounds).scale(scale);
2405
+ const scaleData = { scaleX: 1, scaleY: 1 };
2406
+ MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData);
2407
+ let pixelRatio = options.pixelRatio || 1;
2408
+ if (leaf.isApp) {
2409
+ scaleData.scaleX *= pixelRatio;
2410
+ scaleData.scaleY *= pixelRatio;
2411
+ pixelRatio = leaf.app.pixelRatio;
2412
+ }
2413
+ const { x, y, width, height } = new Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY);
2414
+ const renderOptions = { matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) };
2401
2415
  let canvas = Creator.canvas({ width: Math.round(width), height: Math.round(height), pixelRatio, smooth, contextSettings });
2402
- const renderOptions = { matrix: matrix.scale(1 / scale).invert().translate(-x, -y).withScale(1 / scaleX * scale, 1 / scaleY * scale) };
2403
2416
  let sliceLeaf;
2404
2417
  if (slice) {
2405
2418
  sliceLeaf = leaf;
@@ -2503,7 +2516,8 @@ Object.assign(Effect, EffectModule);
2503
2516
  Object.assign(Export, ExportModule);
2504
2517
 
2505
2518
  try {
2506
- useCanvas('wx', wx);
2519
+ if (wx)
2520
+ useCanvas('miniapp', wx);
2507
2521
  }
2508
2522
  catch (_a) { }
2509
2523