@leafer-ui/paint 1.0.0-beta.11 → 1.0.0-beta.15

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/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@leafer-ui/paint",
3
- "version": "1.0.0-beta.11",
3
+ "version": "1.0.0-beta.15",
4
4
  "description": "@leafer-ui/paint",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
7
7
  "main": "src/index.ts",
8
+ "types": "types/index.d.ts",
8
9
  "files": [
9
- "src"
10
+ "src",
11
+ "types",
12
+ "dist"
10
13
  ],
11
14
  "repository": {
12
15
  "type": "git",
@@ -19,11 +22,10 @@
19
22
  "leaferjs"
20
23
  ],
21
24
  "dependencies": {
22
- "@leafer/core": "1.0.0-beta.11",
23
- "@leafer-ui/color": "1.0.0-beta.11"
25
+ "@leafer/core": "1.0.0-beta.15"
24
26
  },
25
27
  "devDependencies": {
26
- "@leafer/interface": "1.0.0-beta.11",
27
- "@leafer-ui/interface": "1.0.0-beta.11"
28
+ "@leafer/interface": "1.0.0-beta.15",
29
+ "@leafer-ui/interface": "1.0.0-beta.15"
28
30
  }
29
31
  }
package/src/Compute.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { IUI, IPaint, ILeafPaint, IRGB, IBooleanMap } from '@leafer-ui/interface'
2
- import { ColorConvert } from '@leafer-ui/color'
2
+ import { ColorConvert } from '@leafer-ui/core'
3
3
 
4
4
  import { image } from "./paint/image/image"
5
5
  import { linearGradient } from './paint/linear'
6
6
  import { radialGradient } from "./paint/radial"
7
7
  import { conicGradient } from "./paint/conic"
8
+ import { recycleImage } from './paint/image'
8
9
 
9
10
 
10
11
  let recycleMap: IBooleanMap
@@ -16,7 +17,7 @@ export function compute(ui: IUI, attrName: string): void {
16
17
 
17
18
  if (!(paints instanceof Array)) paints = [paints]
18
19
 
19
- recycleMap = ui.__.__recycleImage(attrName)
20
+ recycleMap = recycleImage(ui.__, attrName)
20
21
 
21
22
  for (let i = 0, len = paints.length; i < len; i++) {
22
23
  item = getLeafPaint(ui, paints[i], attrName)
package/src/Shape.ts CHANGED
@@ -13,12 +13,14 @@ export function shape(ui: IUI, current: ILeaferCanvas, options: IRenderOptions):
13
13
  let worldCanvas: ILeaferCanvas
14
14
 
15
15
  const { __world } = ui
16
- let { a: scaleX, d: scaleY } = __world
16
+ let { scaleX, scaleY } = __world
17
+ if (scaleX < 0) scaleX = -scaleX
18
+ if (scaleY < 0) scaleY = -scaleY
17
19
 
18
20
  if (!current.bounds.includes(__world, options.matrix)) {
19
21
 
20
22
  const { renderShapeSpread: spread } = ui.__layout
21
- const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX) : current.bounds, __world, options.matrix)
23
+ const worldClipBounds = getIntersectData(spread ? getSpread(current.bounds, spread * scaleX, spread * scaleY) : current.bounds, __world, options.matrix)
22
24
  matrix = current.bounds.getFitMatrix(worldClipBounds)
23
25
 
24
26
  if (matrix.a < 1) {
package/src/Stroke.ts CHANGED
@@ -29,7 +29,7 @@ export function stroke(ui: IUI, canvas: ILeaferCanvas, stroke: string): void {
29
29
  canvas.save()
30
30
  canvas.setStroke(stroke, strokeWidth * 2, options)
31
31
 
32
- canvas.clip(options.windingRule)
32
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip()
33
33
  canvas.stroke()
34
34
 
35
35
  canvas.restore()
@@ -44,7 +44,7 @@ export function stroke(ui: IUI, canvas: ILeaferCanvas, stroke: string): void {
44
44
 
45
45
  out.stroke()
46
46
 
47
- out.clip(options.windingRule)
47
+ options.windingRule ? out.clip(options.windingRule) : out.clip()
48
48
  out.clearWorld(ui.__layout.renderBounds)
49
49
 
50
50
  canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds)
@@ -78,7 +78,7 @@ export function strokes(ui: IUI, canvas: ILeaferCanvas, strokes: ILeafPaint[]):
78
78
  case 'inside':
79
79
  canvas.save()
80
80
  canvas.setStroke(undefined, strokeWidth * 2, options)
81
- canvas.clip(options.windingRule)
81
+ options.windingRule ? canvas.clip(options.windingRule) : canvas.clip()
82
82
 
83
83
  drawStrokesStyle(ui, strokes, canvas)
84
84
 
@@ -94,7 +94,7 @@ export function strokes(ui: IUI, canvas: ILeaferCanvas, strokes: ILeafPaint[]):
94
94
 
95
95
  drawStrokesStyle(ui, strokes, out)
96
96
 
97
- out.clip(options.windingRule)
97
+ options.windingRule ? out.clip(options.windingRule) : out.clip()
98
98
  out.clearWorld(renderBounds)
99
99
 
100
100
  canvas.copyWorldToInner(out, ui.__world, renderBounds)
package/src/index.ts CHANGED
@@ -3,4 +3,5 @@ export { fillText } from './FillText'
3
3
  export { stroke, strokes } from './Stroke'
4
4
  export { strokeText, drawTextStroke } from './StrokeText'
5
5
  export { shape } from './Shape'
6
- export { compute } from './Compute'
6
+ export { compute } from './Compute'
7
+ export { recycleImage } from './paint/image'
@@ -10,7 +10,7 @@ import { createPattern } from './pattern'
10
10
  export function checkImage(ui: IUI, canvas: ILeaferCanvas, paint: ILeafPaint, allowPaint?: boolean): boolean {
11
11
  const { scaleX, scaleY } = ui.__world
12
12
 
13
- if (!paint.data || paint.patternId === scaleX + scaleY) {
13
+ if (!paint.data || paint.patternId === scaleX + '-' + scaleY) {
14
14
  return false
15
15
  } else {
16
16
 
@@ -1,15 +1,14 @@
1
1
  import { IBoundsData, ILeaferImage } from '@leafer/interface'
2
2
  import { MatrixHelper } from '@leafer/core'
3
3
 
4
- import { IUI, IImagePaint, ILeafPaint, ILeafPaintPatternData } from '@leafer-ui/interface'
4
+ import { IImagePaint, ILeafPaint, ILeafPaintPatternData } from '@leafer-ui/interface'
5
5
 
6
6
  import { clipMode, fillOrFitMode, repeatMode } from './mode'
7
- import { createPattern } from './pattern'
8
7
 
9
8
 
10
9
  const { get, translate } = MatrixHelper
11
10
 
12
- export function createData(ui: IUI, leafPaint: ILeafPaint, image: ILeaferImage, paint: IImagePaint, box: IBoundsData): void {
11
+ export function createData(leafPaint: ILeafPaint, image: ILeaferImage, paint: IImagePaint, box: IBoundsData): void {
13
12
  let { width, height } = image
14
13
 
15
14
  const { opacity, mode, offset, scale, rotation, blendMode } = paint
@@ -41,7 +40,4 @@ export function createData(ui: IUI, leafPaint: ILeafPaint, image: ILeaferImage,
41
40
  data.width = width
42
41
  data.height = height
43
42
  if (opacity) data.opacity = opacity
44
-
45
- const canvas = ui.leafer && ui.leafer.canvas
46
- if (canvas && canvas.bounds.hit(ui.__world)) createPattern(ui, leafPaint, canvas.pixelRatio)
47
43
  }
@@ -6,51 +6,51 @@ import { IUI, IImagePaint, ILeafPaint } from '@leafer-ui/interface'
6
6
  import { createData } from './data'
7
7
 
8
8
 
9
- export function image(ui: IUI, attrName: string, attrValue: IImagePaint, box: IBoundsData, first: boolean): ILeafPaint {
9
+ export function image(ui: IUI, attrName: string, attrValue: IImagePaint, box: IBoundsData, firstUse: boolean): ILeafPaint {
10
10
  const leafPaint: ILeafPaint = { type: attrValue.type }
11
11
  const image = leafPaint.image = ImageManager.get(attrValue)
12
12
 
13
- if (image.ready && hasNaturalSize(ui, attrName, image)) createData(ui, leafPaint, image, attrValue, box)
13
+ const event: IImageEvent = (firstUse || image.loading) && { target: ui, image, attrName, attrValue }
14
14
 
15
- if (first) {
15
+ if (image.ready) {
16
16
 
17
- const event: IImageEvent = { target: ui, image, attrName, attrValue }
18
-
19
- if (image.ready) {
17
+ if (hasNaturalSize(ui, attrName, image)) createData(leafPaint, image, attrValue, box)
20
18
 
19
+ if (firstUse) {
21
20
  emit(ImageEvent.LOAD, event)
22
21
  emit(ImageEvent.LOADED, event)
22
+ }
23
23
 
24
- } else if (image.error) {
24
+ } else if (image.error) {
25
25
 
26
+ if (firstUse) {
26
27
  ui.forceUpdate('surface')
27
28
  event.error = image.error
28
29
  emit(ImageEvent.ERROR, event)
30
+ }
29
31
 
30
- } else {
31
-
32
- emit(ImageEvent.LOAD, event)
32
+ } else {
33
33
 
34
- leafPaint.loadId = image.load(
35
- () => {
36
- if (ui.__) {
34
+ if (firstUse) emit(ImageEvent.LOAD, event)
37
35
 
38
- if (hasNaturalSize(ui, attrName, image)) {
39
- createData(ui, leafPaint, image, attrValue, box)
40
- ui.forceUpdate('surface')
41
- }
36
+ leafPaint.loadId = image.load(
37
+ () => {
38
+ if (!ui.destroyed) {
42
39
 
43
- emit(ImageEvent.LOADED, event)
40
+ if (hasNaturalSize(ui, attrName, image)) {
41
+ createData(leafPaint, image, attrValue, box)
42
+ ui.forceUpdate('surface')
44
43
  }
45
- },
46
- (error) => {
47
- ui.forceUpdate('surface')
48
- event.error = error
49
- emit(ImageEvent.ERROR, event)
50
- }
51
- )
52
44
 
53
- }
45
+ emit(ImageEvent.LOADED, event)
46
+ }
47
+ },
48
+ (error) => {
49
+ ui.forceUpdate('surface')
50
+ event.error = error
51
+ emit(ImageEvent.ERROR, event)
52
+ }
53
+ )
54
54
 
55
55
  }
56
56
 
@@ -1,2 +1,4 @@
1
1
  export { image } from './image'
2
2
  export { checkImage } from './check'
3
+ export { recycleImage } from './recycle'
4
+
@@ -9,12 +9,15 @@ export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): b
9
9
 
10
10
  let { scaleX, scaleY } = ui.__world
11
11
 
12
- const id = scaleX + scaleY
12
+ const id = scaleX + '-' + scaleY
13
13
 
14
- if (paint.patternId !== id) {
14
+ if (paint.patternId !== id && !ui.destroyed) {
15
15
 
16
16
  paint.patternId = id
17
17
 
18
+ scaleX = Math.abs(scaleX) // maybe -1
19
+ scaleY = Math.abs(scaleY)
20
+
18
21
  const { image, data } = paint
19
22
  const maxWidth = image.isSVG ? 4096 : Math.min(image.width, 4096)
20
23
  const maxHeight = image.isSVG ? 4096 : Math.min(image.height, 4096)
@@ -35,8 +38,6 @@ export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): b
35
38
 
36
39
  if (width > maxWidth || height > maxHeight) {
37
40
  scale = Math.max(width / maxWidth, height / maxHeight)
38
- } else if (width < 32 || height < 32) {
39
- scale = Math.min(width / 32, height / 32)
40
41
  }
41
42
 
42
43
  if (scale) {
@@ -59,12 +60,12 @@ export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): b
59
60
  scaleHelper(matrix, 1 / scaleX, 1 / scaleY)
60
61
  }
61
62
 
62
- const style = Platform.canvas.createPattern(image.getCanvas(width, height, opacity) as any, mode === 'repeat' ? 'repeat' : (Platform.origin.noRepeat || 'no-repeat'))
63
+ const style = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity) as any, mode === 'repeat' ? 'repeat' : (Platform.origin.noRepeat || 'no-repeat'))
63
64
 
64
65
  try {
65
- paint.transform = null
66
+ if (paint.transform) paint.transform = null
66
67
  if (matrix) style.setTransform ? style.setTransform(matrix) : paint.transform = matrix
67
- } catch (e) {
68
+ } catch {
68
69
  paint.transform = matrix
69
70
  }
70
71
 
@@ -0,0 +1,41 @@
1
+ import { IBooleanMap, ILeaferImage } from '@leafer/interface'
2
+ import { ImageManager } from '@leafer/core'
3
+
4
+ import { IImagePaint, ILeafPaint, IUIData } from '@leafer-ui/interface'
5
+
6
+
7
+ export function recycleImage(data: IUIData, attrName: string): IBooleanMap {
8
+ const paints = (attrName === 'fill' ? data._fill : data._stroke) as ILeafPaint[]
9
+
10
+ if (paints instanceof Array) {
11
+
12
+ let image: ILeaferImage, recycleMap: IBooleanMap, input: IImagePaint[], url: string
13
+
14
+ for (let i = 0, len = paints.length; i < len; i++) {
15
+
16
+ image = paints[i].image
17
+ url = image && image.url
18
+
19
+ if (url) {
20
+ if (!recycleMap) recycleMap = {}
21
+ recycleMap[url] = true
22
+ ImageManager.recycle(image)
23
+
24
+ // stop load
25
+ if (image.loading) {
26
+ if (!input) {
27
+ input = (data.__input && data.__input[attrName]) || []
28
+ if (!(input instanceof Array)) input = [input]
29
+ }
30
+ image.unload(paints[i].loadId, !input.some((item: IImagePaint) => item.url === url))
31
+ }
32
+ }
33
+
34
+ }
35
+
36
+ return recycleMap
37
+
38
+ }
39
+
40
+ return null
41
+ }
@@ -2,7 +2,7 @@ import { IObject, IBoundsData } from '@leafer/interface'
2
2
  import { Platform } from '@leafer/core'
3
3
 
4
4
  import { IGradientPaint, ILeafPaint, IColorStop } from '@leafer-ui/interface'
5
- import { ColorConvert } from '@leafer-ui/color'
5
+ import { ColorConvert } from '@leafer-ui/core'
6
6
 
7
7
 
8
8
  const defaultFrom = { x: 0.5, y: 0 }
@@ -0,0 +1,21 @@
1
+ import { ILeaferCanvas, IRenderOptions, IBooleanMap } from '@leafer/interface';
2
+ import { IUI, ILeafPaint, ICachedShape, IUIData } from '@leafer-ui/interface';
3
+
4
+ declare function fill(ui: IUI, canvas: ILeaferCanvas, fill: string): void;
5
+ declare function fills(ui: IUI, canvas: ILeaferCanvas, fills: ILeafPaint[]): void;
6
+
7
+ declare function fillText(ui: IUI, canvas: ILeaferCanvas): void;
8
+
9
+ declare function stroke(ui: IUI, canvas: ILeaferCanvas, stroke: string): void;
10
+ declare function strokes(ui: IUI, canvas: ILeaferCanvas, strokes: ILeafPaint[]): void;
11
+
12
+ declare function strokeText(ui: IUI, canvas: ILeaferCanvas, stroke: string | ILeafPaint[]): void;
13
+ declare function drawTextStroke(ui: IUI, canvas: ILeaferCanvas): void;
14
+
15
+ declare function shape(ui: IUI, current: ILeaferCanvas, options: IRenderOptions): ICachedShape;
16
+
17
+ declare function compute(ui: IUI, attrName: string): void;
18
+
19
+ declare function recycleImage(data: IUIData, attrName: string): IBooleanMap;
20
+
21
+ export { compute, drawTextStroke, fill, fillText, fills, recycleImage, shape, stroke, strokeText, strokes };