@leafer-in/export 1.7.0 → 1.9.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/src/export.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { IExportModule, IExportOptions, IExportResult, IExportResultFunction, IUI, IExportFileType, IFunction, IRenderOptions, IBoundsData, IBounds, ILocationType, ILeaf } from '@leafer-ui/interface'
2
- import { Creator, Matrix, TaskProcessor, FileHelper, Bounds, Platform, MathHelper, Resource } from '@leafer-ui/draw'
2
+ import { Creator, Matrix, TaskProcessor, FileHelper, Bounds, Platform, MathHelper, Resource, Export, isUndefined } from '@leafer-ui/draw'
3
3
 
4
4
  import { getTrimBounds } from './trim'
5
5
 
@@ -8,146 +8,155 @@ export const ExportModule: IExportModule = {
8
8
 
9
9
  syncExport(leaf: IUI, filename: string, options?: IExportOptions | number | boolean): IExportResult {
10
10
 
11
- this.running = true
11
+ Export.running = true
12
12
 
13
13
  let result: IExportResult
14
- const fileType = FileHelper.fileType(filename)
15
- const isDownload = filename.includes('.')
16
- options = FileHelper.getExportOptions(options)
17
14
 
18
- const { toURL } = Platform
19
- const { download } = Platform.origin
15
+ try {
20
16
 
17
+ const fileType = FileHelper.fileType(filename)
18
+ const isDownload = filename.includes('.')
19
+ options = FileHelper.getExportOptions(options)
21
20
 
22
- if (fileType === 'json') {
21
+ const { toURL } = Platform
22
+ const { download } = Platform.origin
23
23
 
24
- isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename)
25
- result = { data: isDownload ? true : leaf.toJSON(options.json) }
26
24
 
27
- } else if (fileType === 'svg') {
25
+ if (fileType === 'json') {
28
26
 
29
- isDownload && download(toURL(leaf.toSVG(), 'svg'), filename)
30
- result = { data: isDownload ? true : leaf.toSVG() }
27
+ isDownload && download(toURL(JSON.stringify(leaf.toJSON(options.json)), 'text'), filename)
28
+ result = { data: isDownload ? true : leaf.toJSON(options.json) }
31
29
 
32
- } else {
30
+ } else if (fileType === 'svg') {
33
31
 
34
- let renderBounds: IBoundsData, trimBounds: IBounds, scaleX = 1, scaleY = 1
35
- const { worldTransform, isLeafer, leafer, isFrame } = leaf
36
- const { slice, clip, trim, screenshot, padding, onCanvas } = options
37
- const smooth = options.smooth === undefined ? (leafer ? leafer.config.smooth : true) : options.smooth
38
- const contextSettings = options.contextSettings || (leafer ? leafer.config.contextSettings : undefined)
32
+ isDownload && download(toURL(leaf.toSVG(), 'svg'), filename)
33
+ result = { data: isDownload ? true : leaf.toSVG() }
39
34
 
40
- const fill = (isLeafer && screenshot) ? (options.fill === undefined ? leaf.fill : options.fill) : options.fill // leafer use
41
- const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix()
42
-
43
- // 获取元素大小
44
- if (screenshot) {
45
- renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot
46
35
  } else {
47
- let relative: ILocationType | ILeaf = options.relative || (isLeafer ? 'inner' : 'local')
48
-
49
- scaleX = worldTransform.scaleX
50
- scaleY = worldTransform.scaleY
51
-
52
- switch (relative) {
53
- case 'inner':
54
- matrix.set(worldTransform)
55
- break
56
- case 'local':
57
- matrix.set(worldTransform).divide(leaf.localTransform)
58
- scaleX /= leaf.scaleX
59
- scaleY /= leaf.scaleY
60
- break
61
- case 'world':
62
- scaleX = 1
63
- scaleY = 1
64
- break
65
- case 'page':
66
- relative = leafer || leaf
67
- default:
68
- matrix.set(worldTransform).divide(leaf.getTransform(relative))
69
- const l = relative.worldTransform
70
- scaleX /= scaleX / l.scaleX
71
- scaleY /= scaleY / l.scaleY
36
+
37
+ let renderBounds: IBoundsData, trimBounds: IBounds, scaleX = 1, scaleY = 1
38
+ const { worldTransform, isLeafer, leafer, isFrame } = leaf
39
+ const { slice, clip, trim, screenshot, padding, onCanvas } = options
40
+ const smooth = isUndefined(options.smooth) ? (leafer ? leafer.config.smooth : true) : options.smooth
41
+ const contextSettings = options.contextSettings || (leafer ? leafer.config.contextSettings : undefined)
42
+
43
+ const fill = (isLeafer && screenshot) ? (isUndefined(options.fill) ? leaf.fill : options.fill) : options.fill // leafer use
44
+ const needFill = FileHelper.isOpaqueImage(filename) || fill, matrix = new Matrix()
45
+
46
+ // 获取元素大小
47
+ if (screenshot) {
48
+ renderBounds = screenshot === true ? (isLeafer ? leafer.canvas.bounds : leaf.worldRenderBounds) : screenshot
49
+ } else {
50
+ let relative: ILocationType | ILeaf = options.relative || (isLeafer ? 'inner' : 'local')
51
+
52
+ scaleX = worldTransform.scaleX
53
+ scaleY = worldTransform.scaleY
54
+
55
+ switch (relative) {
56
+ case 'inner':
57
+ matrix.set(worldTransform)
58
+ break
59
+ case 'local':
60
+ matrix.set(worldTransform).divide(leaf.localTransform)
61
+ scaleX /= leaf.scaleX
62
+ scaleY /= leaf.scaleY
63
+ break
64
+ case 'world':
65
+ scaleX = 1
66
+ scaleY = 1
67
+ break
68
+ case 'page':
69
+ relative = leafer || leaf
70
+ default:
71
+ matrix.set(worldTransform).divide(leaf.getTransform(relative))
72
+ const l = relative.worldTransform
73
+ scaleX /= scaleX / l.scaleX
74
+ scaleY /= scaleY / l.scaleY
75
+ }
76
+
77
+ renderBounds = leaf.getBounds('render', relative)
72
78
  }
73
79
 
74
- renderBounds = leaf.getBounds('render', relative)
75
- }
76
80
 
81
+ // 缩放元素
82
+ const scaleData = { scaleX: 1, scaleY: 1 }
83
+ MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData)
77
84
 
78
- // 缩放元素
79
- const scaleData = { scaleX: 1, scaleY: 1 }
80
- MathHelper.getScaleData(options.scale, options.size, renderBounds, scaleData)
85
+ let pixelRatio = options.pixelRatio || 1
81
86
 
82
- let pixelRatio = options.pixelRatio || 1
83
87
 
88
+ // 导出元素
89
+ let { x, y, width, height } = new Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY)
90
+ if (clip) x += clip.x, y += clip.y, width = clip.width, height = clip.height
84
91
 
85
- // 导出元素
86
- let { x, y, width, height } = new Bounds(renderBounds).scale(scaleData.scaleX, scaleData.scaleY)
87
- if (clip) x += clip.x, y += clip.y, width = clip.width, height = clip.height
92
+ const renderOptions: IRenderOptions = { exporting: true, matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) }
93
+ let canvas = Creator.canvas({ width: Math.floor(width), height: Math.floor(height), pixelRatio, smooth, contextSettings })
88
94
 
89
- const renderOptions: IRenderOptions = { exporting: true, matrix: matrix.scale(1 / scaleData.scaleX, 1 / scaleData.scaleY).invert().translate(-x, -y).withScale(1 / scaleX * scaleData.scaleX, 1 / scaleY * scaleData.scaleY) }
90
- let canvas = Creator.canvas({ width: Math.floor(width), height: Math.floor(height), pixelRatio, smooth, contextSettings })
95
+ let sliceLeaf: IUI
96
+ if (slice) {
97
+ sliceLeaf = leaf
98
+ sliceLeaf.__worldOpacity = 0 // hide slice
91
99
 
92
- let sliceLeaf: IUI
93
- if (slice) {
94
- sliceLeaf = leaf
95
- sliceLeaf.__worldOpacity = 0 // hide slice
100
+ leaf = leafer || leaf // render all in bounds
101
+ renderOptions.bounds = canvas.bounds
102
+ }
96
103
 
97
- leaf = leafer || leaf // render all in bounds
98
- renderOptions.bounds = canvas.bounds
99
- }
100
104
 
105
+ canvas.save()
101
106
 
102
- canvas.save()
107
+ if (isFrame && !isUndefined(fill)) {
108
+ const oldFill = leaf.get('fill')
109
+ leaf.fill = ''
110
+ leaf.__render(canvas, renderOptions)
111
+ leaf.fill = oldFill as string
112
+ } else {
113
+ leaf.__render(canvas, renderOptions)
114
+ }
103
115
 
104
- if (isFrame && fill !== undefined) {
105
- const oldFill = leaf.get('fill')
106
- leaf.fill = ''
107
- leaf.__render(canvas, renderOptions)
108
- leaf.fill = oldFill as string
109
- } else {
110
- leaf.__render(canvas, renderOptions)
111
- }
116
+ canvas.restore()
112
117
 
113
- canvas.restore()
118
+ if (sliceLeaf) sliceLeaf.__updateWorldOpacity() // show slice
114
119
 
120
+ if (trim) {
121
+ trimBounds = getTrimBounds(canvas)
122
+ const old = canvas, { width, height } = trimBounds
123
+ const config = { x: 0, y: 0, width, height, pixelRatio }
115
124
 
116
- if (sliceLeaf) sliceLeaf.__updateWorldOpacity() // show slice
125
+ canvas = Creator.canvas(config)
126
+ canvas.copyWorld(old, trimBounds, config)
127
+ old.destroy()
128
+ }
117
129
 
118
- if (trim) {
119
- trimBounds = getTrimBounds(canvas)
120
- const old = canvas, { width, height } = trimBounds
121
- const config = { x: 0, y: 0, width, height, pixelRatio }
130
+ if (padding) {
131
+ const [top, right, bottom, left] = MathHelper.fourNumber(padding)
132
+ const old = canvas, { width, height } = old
122
133
 
123
- canvas = Creator.canvas(config)
124
- canvas.copyWorld(old, trimBounds, config)
125
- }
134
+ canvas = Creator.canvas({ width: width + left + right, height: height + top + bottom, pixelRatio })
135
+ canvas.copyWorld(old, old.bounds, { x: left, y: top, width, height })
136
+ old.destroy()
137
+ }
126
138
 
127
- if (padding) {
128
- const [top, right, bottom, left] = MathHelper.fourNumber(padding)
129
- const old = canvas, { width, height } = old
139
+ if (needFill) canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over')
140
+ if (onCanvas) onCanvas(canvas)
130
141
 
131
- canvas = Creator.canvas({ width: width + left + right, height: height + top + bottom, pixelRatio })
132
- canvas.copyWorld(old, old.bounds, { x: left, y: top, width, height })
133
- }
142
+ const data = filename === 'canvas' ? canvas : canvas.export(filename, options)
143
+ result = { data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds }
134
144
 
135
- if (needFill) canvas.fillWorld(canvas.bounds, fill || '#FFFFFF', 'destination-over')
136
- if (onCanvas) onCanvas(canvas)
145
+ }
137
146
 
138
- const data = filename === 'canvas' ? canvas : canvas.export(filename, options)
139
- result = { data, width: canvas.pixelWidth, height: canvas.pixelHeight, renderBounds, trimBounds }
147
+ } catch (error) {
140
148
 
149
+ result = { data: '', error }
141
150
  }
142
151
 
143
- this.running = false
152
+ Export.running = false
144
153
 
145
154
  return result
146
155
  },
147
156
 
148
157
  export(leaf: IUI, filename: IExportFileType | string, options?: IExportOptions | number | boolean): Promise<IExportResult> {
149
158
 
150
- this.running = true
159
+ Export.running = true
151
160
 
152
161
  return addTask((success: IExportResultFunction) =>
153
162
 
@@ -155,7 +164,7 @@ export const ExportModule: IExportModule = {
155
164
 
156
165
  const getResult = async () => {
157
166
  if (!Resource.isComplete) return Platform.requestRender(getResult)
158
- const result: IExportResult = ExportModule.syncExport(leaf, filename, options)
167
+ const result: IExportResult = Export.syncExport(leaf, filename, options)
159
168
  if (result.data instanceof Promise) result.data = await result.data
160
169
  success(result)
161
170
  resolve()
package/src/trim.ts CHANGED
@@ -19,6 +19,9 @@ export function getTrimBounds(canvas: ILeaferCanvas): IBounds {
19
19
  }
20
20
 
21
21
  const bounds = new Bounds()
22
- toBounds(pointBounds, bounds)
23
- return bounds.scale(1 / canvas.pixelRatio).ceil()
22
+ if (pointBounds) {
23
+ toBounds(pointBounds, bounds)
24
+ bounds.scale(1 / canvas.pixelRatio).ceil()
25
+ }
26
+ return bounds
24
27
  }
package/types/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
 
2
- export { }
2
+ export { };