@leafer-ui/paint 1.6.1 → 1.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leafer-ui/paint",
3
- "version": "1.6.1",
3
+ "version": "1.6.3",
4
4
  "description": "@leafer-ui/paint",
5
5
  "author": "Chao (Leafer) Wan",
6
6
  "license": "MIT",
@@ -22,11 +22,11 @@
22
22
  "leaferjs"
23
23
  ],
24
24
  "dependencies": {
25
- "@leafer/core": "1.6.1",
26
- "@leafer-ui/draw": "1.6.1"
25
+ "@leafer/core": "1.6.3",
26
+ "@leafer-ui/draw": "1.6.3"
27
27
  },
28
28
  "devDependencies": {
29
- "@leafer/interface": "1.6.1",
30
- "@leafer-ui/interface": "1.6.1"
29
+ "@leafer/interface": "1.6.3",
30
+ "@leafer-ui/interface": "1.6.3"
31
31
  }
32
32
  }
package/src/Compute.ts CHANGED
@@ -1,13 +1,16 @@
1
+ import { DataHelper } from '@leafer/core'
2
+
1
3
  import { IUI, IPaint, ILeafPaint, IRGB, IBooleanMap, IObject, IPaintAttr } from '@leafer-ui/interface'
2
4
  import { ColorConvert, PaintImage, PaintGradient } from '@leafer-ui/draw'
3
5
 
4
6
 
5
7
  let recycleMap: IBooleanMap
8
+ const { stintSet } = DataHelper, { hasTransparent } = ColorConvert
6
9
 
7
10
  export function compute(attrName: IPaintAttr, ui: IUI): void {
8
11
  const data = ui.__, leafPaints: ILeafPaint[] = []
9
12
 
10
- let paints: IPaint[] = data.__input[attrName], hasOpacityPixel: boolean
13
+ let paints: IPaint[] = data.__input[attrName], isAlphaPixel: boolean, isTransparent: boolean
11
14
  if (!(paints instanceof Array)) paints = [paints]
12
15
 
13
16
  recycleMap = PaintImage.recycleImage(attrName, data)
@@ -19,28 +22,54 @@ export function compute(attrName: IPaintAttr, ui: IUI): void {
19
22
 
20
23
  (data as IObject)['_' + attrName] = leafPaints.length ? leafPaints : undefined
21
24
 
22
- if (leafPaints.length && leafPaints[0].image) hasOpacityPixel = leafPaints[0].image.hasOpacityPixel
23
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel
25
+ if (leafPaints.length) {
26
+ if (leafPaints.every(item => item.isTransparent)) {
27
+ if (leafPaints.some(item => item.image)) isAlphaPixel = true
28
+ isTransparent = true
29
+ }
30
+ }
31
+
32
+ if (attrName === 'fill') {
33
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel)
34
+ stintSet(data, '__isTransparentFill', isTransparent)
35
+ } else {
36
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel)
37
+ stintSet(data, '__isTransparentStroke', isTransparent)
38
+ }
24
39
  }
25
40
 
26
41
 
27
42
  function getLeafPaint(attrName: string, paint: IPaint, ui: IUI): ILeafPaint {
28
43
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0) return undefined
44
+
45
+ let data: ILeafPaint
29
46
  const { boxBounds } = ui.__layout
30
47
 
31
48
  switch (paint.type) {
32
- case 'solid':
33
- let { type, blendMode, color, opacity } = paint
34
- return { type, blendMode, style: ColorConvert.string(color, opacity) }
35
49
  case 'image':
36
- return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url])
50
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url])
51
+ break
37
52
  case 'linear':
38
- return PaintGradient.linearGradient(paint, boxBounds)
53
+ data = PaintGradient.linearGradient(paint, boxBounds)
54
+ break
39
55
  case 'radial':
40
- return PaintGradient.radialGradient(paint, boxBounds)
56
+ data = PaintGradient.radialGradient(paint, boxBounds)
57
+ break
41
58
  case 'angular':
42
- return PaintGradient.conicGradient(paint, boxBounds)
59
+ data = PaintGradient.conicGradient(paint, boxBounds)
60
+ break
61
+ case 'solid':
62
+ const { type, blendMode, color, opacity } = paint
63
+ data = { type, blendMode, style: ColorConvert.string(color, opacity) }
64
+ break
43
65
  default:
44
- return (paint as IRGB).r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined
66
+ if ((paint as IRGB).r !== undefined) data = { type: 'solid', style: ColorConvert.string(paint) }
45
67
  }
68
+
69
+ if (data) {
70
+ if (typeof data.style === 'string' && hasTransparent(data.style)) data.isTransparent = true
71
+ if (paint.blendMode) data.blendMode = paint.blendMode
72
+ }
73
+
74
+ return data
46
75
  }
package/src/Fill.ts CHANGED
@@ -8,46 +8,52 @@ import { fillText } from './FillText'
8
8
 
9
9
  export function fill(fill: string, ui: IUI, canvas: ILeaferCanvas): void {
10
10
  canvas.fillStyle = fill
11
- ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill())
11
+ fillPathOrText(ui, canvas)
12
12
  }
13
13
 
14
14
 
15
15
  export function fills(fills: ILeafPaint[], ui: IUI, canvas: ILeaferCanvas): void {
16
16
  let item: ILeafPaint
17
- const { windingRule, __font } = ui.__
18
17
  for (let i = 0, len = fills.length; i < len; i++) {
19
18
  item = fills[i]
20
19
 
21
- if (item.image && PaintImage.checkImage(ui, canvas, item, !__font)) continue
20
+ if (item.image) {
22
21
 
23
- if (item.style) {
22
+ if (PaintImage.checkImage(ui, canvas, item, !ui.__.__font)) continue
24
23
 
25
- canvas.fillStyle = item.style
24
+ if (!item.style) {
25
+ if (!i && item.image.isPlacehold) ui.drawImagePlaceholder(canvas, item.image) // 图片加载中或加载失败
26
+ continue
27
+ }
26
28
 
27
- if (item.transform) {
28
- canvas.save()
29
+ }
29
30
 
30
- canvas.transform(item.transform)
31
+ canvas.fillStyle = item.style
31
32
 
32
- if (item.blendMode) canvas.blendMode = item.blendMode
33
+ if (item.transform) {
33
34
 
34
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill())
35
+ canvas.save()
36
+ canvas.transform(item.transform)
37
+ if (item.blendMode) canvas.blendMode = item.blendMode
38
+ fillPathOrText(ui, canvas)
39
+ canvas.restore()
35
40
 
36
- canvas.restore()
37
- } else {
38
- if (item.blendMode) {
39
- canvas.saveBlendMode(item.blendMode)
41
+ } else {
40
42
 
41
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill())
43
+ if (item.blendMode) {
42
44
 
43
- canvas.restoreBlendMode()
44
- } else {
45
+ canvas.saveBlendMode(item.blendMode)
46
+ fillPathOrText(ui, canvas)
47
+ canvas.restoreBlendMode()
45
48
 
46
- __font ? fillText(ui, canvas) : (windingRule ? canvas.fill(windingRule) : canvas.fill())
49
+ } else fillPathOrText(ui, canvas)
47
50
 
48
- }
49
- }
50
51
  }
51
52
 
52
53
  }
54
+ }
55
+
56
+
57
+ export function fillPathOrText(ui: IUI, canvas: ILeaferCanvas): void {
58
+ ui.__.__font ? fillText(ui, canvas) : (ui.__.windingRule ? canvas.fill(ui.__.windingRule) : canvas.fill())
53
59
  }
package/src/FillText.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import { ILeaferCanvas } from '@leafer/interface'
2
2
 
3
- import { IUI, ITextRowData } from '@leafer-ui/interface'
3
+ import { ITextRowData, IText } from '@leafer-ui/interface'
4
4
 
5
5
 
6
- export function fillText(ui: IUI, canvas: ILeaferCanvas): void {
6
+ export function fillText(ui: IText, canvas: ILeaferCanvas): void {
7
7
 
8
- let row: ITextRowData, data = ui.__.__textDrawData
9
- const { rows, decorationY } = data
8
+ const data = ui.__, { rows, decorationY } = data.__textDrawData
9
+ if (data.__isPlacehold && data.placeholderColor) canvas.fillStyle = data.placeholderColor
10
+
11
+ let row: ITextRowData
10
12
 
11
13
  for (let i = 0, len = rows.length; i < len; i++) {
12
14
  row = rows[i]
@@ -16,7 +18,7 @@ export function fillText(ui: IUI, canvas: ILeaferCanvas): void {
16
18
  }
17
19
 
18
20
  if (decorationY) {
19
- const { decorationColor, decorationHeight } = data
21
+ const { decorationColor, decorationHeight } = data.__textDrawData
20
22
  if (decorationColor) canvas.fillStyle = decorationColor
21
23
  rows.forEach(row => decorationY.forEach(value => canvas.fillRect(row.x, row.y + value, row.width, decorationHeight)))
22
24
  }
package/src/Stroke.ts CHANGED
@@ -1,59 +1,31 @@
1
1
  import { ILeaferCanvas } from '@leafer/interface'
2
+ import { Platform } from '@leafer-ui/core'
2
3
 
3
4
  import { IUI, ILeafPaint } from '@leafer-ui/interface'
5
+ import { Paint } from '@leafer-ui/external'
4
6
 
5
7
  import { strokeText, drawStrokesStyle } from './StrokeText'
6
8
 
7
9
 
8
10
  export function stroke(stroke: string, ui: IUI, canvas: ILeaferCanvas): void {
9
- const options = ui.__
10
- const { __strokeWidth, strokeAlign, __font } = options
11
- if (!__strokeWidth) return
11
+ const data = ui.__
12
+ if (!data.__strokeWidth) return
12
13
 
13
- if (__font) {
14
+ if (data.__font) {
14
15
 
15
16
  strokeText(stroke, ui, canvas)
16
17
 
17
18
  } else {
18
19
 
19
- switch (strokeAlign) {
20
-
20
+ switch (data.strokeAlign) {
21
21
  case 'center':
22
-
23
- canvas.setStroke(stroke, __strokeWidth, options)
24
- canvas.stroke()
25
-
26
- if (options.__useArrow) strokeArrow(ui, canvas)
27
-
22
+ drawCenter(stroke, 1, ui, canvas)
28
23
  break
29
-
30
24
  case 'inside':
31
-
32
- canvas.save()
33
- canvas.setStroke(stroke, __strokeWidth * 2, options)
34
-
35
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip()
36
- canvas.stroke()
37
-
38
- canvas.restore()
39
-
25
+ drawInside(stroke, ui, canvas)
40
26
  break
41
-
42
27
  case 'outside':
43
- const out = canvas.getSameCanvas(true, true)
44
- out.setStroke(stroke, __strokeWidth * 2, options)
45
-
46
- ui.__drawRenderPath(out)
47
-
48
- out.stroke()
49
-
50
- options.windingRule ? out.clip(options.windingRule) : out.clip()
51
- out.clearWorld(ui.__layout.renderBounds)
52
-
53
- if (ui.__worldFlipped) canvas.copyWorldByReset(out, ui.__nowWorld)
54
- else canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds)
55
-
56
- out.recycle(ui.__nowWorld)
28
+ drawOutside(stroke, ui, canvas)
57
29
  break
58
30
  }
59
31
 
@@ -62,64 +34,47 @@ export function stroke(stroke: string, ui: IUI, canvas: ILeaferCanvas): void {
62
34
 
63
35
 
64
36
  export function strokes(strokes: ILeafPaint[], ui: IUI, canvas: ILeaferCanvas): void {
65
- const options = ui.__
66
- const { __strokeWidth, strokeAlign, __font } = options
67
- if (!__strokeWidth) return
68
-
69
- if (__font) {
70
-
71
- strokeText(strokes, ui, canvas)
72
-
73
- } else {
74
-
75
- switch (strokeAlign) {
76
-
77
- case 'center':
78
- canvas.setStroke(undefined, __strokeWidth, options)
79
- drawStrokesStyle(strokes, false, ui, canvas)
80
-
81
- if (options.__useArrow) strokeArrow(ui, canvas)
82
- break
37
+ stroke(strokes as any, ui, canvas)
38
+ }
83
39
 
84
- case 'inside':
85
- canvas.save()
86
- canvas.setStroke(undefined, __strokeWidth * 2, options)
87
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip()
88
40
 
89
- drawStrokesStyle(strokes, false, ui, canvas)
41
+ function drawCenter(stroke: string | ILeafPaint[], strokeWidthScale: number, ui: IUI, canvas: ILeaferCanvas) {
42
+ const data = ui.__
43
+ canvas.setStroke(!data.__isStrokes && stroke as string, data.__strokeWidth * strokeWidthScale, data)
44
+ data.__isStrokes ? drawStrokesStyle(stroke as ILeafPaint[], false, ui, canvas) : canvas.stroke()
90
45
 
91
- canvas.restore()
92
- break
46
+ if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas)
93
47
 
94
- case 'outside':
95
- const { renderBounds } = ui.__layout
96
- const out = canvas.getSameCanvas(true, true)
97
- ui.__drawRenderPath(out)
48
+ }
98
49
 
99
- out.setStroke(undefined, __strokeWidth * 2, options)
50
+ function drawInside(stroke: string | ILeafPaint[], ui: IUI, canvas: ILeaferCanvas) {
51
+ const data = ui.__
52
+ canvas.save()
53
+ data.windingRule ? canvas.clip(data.windingRule) : canvas.clip()
100
54
 
101
- drawStrokesStyle(strokes, false, ui, out)
55
+ drawCenter(stroke, 2, ui, canvas)
56
+ canvas.restore()
57
+ }
102
58
 
103
- options.windingRule ? out.clip(options.windingRule) : out.clip()
104
- out.clearWorld(renderBounds)
59
+ function drawOutside(stroke: string | ILeafPaint[], ui: IUI, canvas: ILeaferCanvas) {
60
+ const data = ui.__
61
+ if (data.__fillAfterStroke) {
105
62
 
106
- if (ui.__worldFlipped) canvas.copyWorldByReset(out, ui.__nowWorld)
107
- else canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds)
63
+ drawCenter(stroke, 2, ui, canvas)
108
64
 
109
- out.recycle(ui.__nowWorld)
110
- break
111
- }
65
+ } else {
66
+ const { renderBounds } = ui.__layout
67
+ const out = canvas.getSameCanvas(true, true)
68
+ ui.__drawRenderPath(out)
112
69
 
113
- }
70
+ drawCenter(stroke, 2, ui, out)
114
71
 
115
- }
72
+ data.windingRule ? out.clip(data.windingRule) : out.clip()
73
+ out.clearWorld(renderBounds)
116
74
 
75
+ if (ui.__worldFlipped || Platform.fullImageShadow) canvas.copyWorldByReset(out, ui.__nowWorld)
76
+ else canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds)
117
77
 
118
- function strokeArrow(ui: IUI, canvas: ILeaferCanvas): void {
119
- if (ui.__.dashPattern) { // fix: dashPattern Arrow
120
- canvas.beginPath()
121
- ui.__drawPathByData(canvas, ui.__.__pathForArrow)
122
- canvas.dashPattern = null
123
- canvas.stroke()
78
+ out.recycle(ui.__nowWorld)
124
79
  }
125
80
  }
package/src/StrokeText.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ILeaferCanvas } from '@leafer/interface'
2
+ import { Platform } from '@leafer-ui/core'
2
3
 
3
4
  import { IUI, ITextRowData, ILeafPaint, IStrokeAlign, ILeafStrokePaint } from '@leafer-ui/interface'
4
5
  import { PaintImage } from "@leafer-ui/draw"
@@ -7,41 +8,41 @@ import { fillText } from './FillText'
7
8
 
8
9
 
9
10
  export function strokeText(stroke: string | ILeafPaint[], ui: IUI, canvas: ILeaferCanvas): void {
10
- const { strokeAlign } = ui.__
11
- const isStrokes = typeof stroke !== 'string'
12
- switch (strokeAlign) {
11
+ switch (ui.__.strokeAlign) {
13
12
  case 'center':
14
- canvas.setStroke(isStrokes ? undefined : stroke, ui.__.strokeWidth, ui.__)
15
- isStrokes ? drawStrokesStyle(stroke as ILeafPaint[], true, ui, canvas) : drawTextStroke(ui, canvas)
13
+ drawCenter(stroke, 1, ui, canvas)
16
14
  break
17
15
  case 'inside':
18
- drawAlignStroke('inside', stroke, isStrokes, ui, canvas)
16
+ drawAlign(stroke, 'inside', ui, canvas)
19
17
  break
20
18
  case 'outside':
21
- drawAlignStroke('outside', stroke, isStrokes, ui, canvas)
19
+ ui.__.__fillAfterStroke ? drawCenter(stroke, 2, ui, canvas) : drawAlign(stroke, 'outside', ui, canvas)
22
20
  break
23
21
  }
24
22
  }
25
23
 
26
- function drawAlignStroke(align: IStrokeAlign, stroke: string | ILeafPaint[], isStrokes: boolean, ui: IUI, canvas: ILeaferCanvas): void {
27
- const { __strokeWidth, __font } = ui.__
24
+ function drawCenter(stroke: string | ILeafPaint[], strokeWidthScale: number, ui: IUI, canvas: ILeaferCanvas): void {
25
+ const data = ui.__
26
+ canvas.setStroke(!data.__isStrokes && stroke as string, data.strokeWidth * strokeWidthScale, data)
27
+ data.__isStrokes ? drawStrokesStyle(stroke as ILeafPaint[], true, ui, canvas) : drawTextStroke(ui, canvas)
28
+ }
28
29
 
30
+ function drawAlign(stroke: string | ILeafPaint[], align: IStrokeAlign, ui: IUI, canvas: ILeaferCanvas): void {
29
31
  const out = canvas.getSameCanvas(true, true)
30
- out.setStroke(isStrokes ? undefined : stroke, __strokeWidth * 2, ui.__)
31
-
32
- out.font = __font
33
- isStrokes ? drawStrokesStyle(stroke as ILeafPaint[], true, ui, out) : drawTextStroke(ui, out)
32
+ out.font = ui.__.__font
33
+ drawCenter(stroke, 2, ui, out)
34
34
 
35
35
  out.blendMode = align === 'outside' ? 'destination-out' : 'destination-in'
36
36
  fillText(ui, out)
37
37
  out.blendMode = 'normal'
38
38
 
39
- if (ui.__worldFlipped) canvas.copyWorldByReset(out, ui.__nowWorld)
39
+ if (ui.__worldFlipped || Platform.fullImageShadow) canvas.copyWorldByReset(out, ui.__nowWorld)
40
40
  else canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds)
41
41
 
42
42
  out.recycle(ui.__nowWorld)
43
43
  }
44
44
 
45
+
45
46
  export function drawTextStroke(ui: IUI, canvas: ILeaferCanvas): void {
46
47
 
47
48
  let row: ITextRowData, data = ui.__.__textDrawData
package/src/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IPaintModule } from '@leafer-ui/interface'
2
2
 
3
- import { fill, fills } from './Fill'
3
+ import { fill, fills, fillPathOrText } from './Fill'
4
4
  import { fillText } from './FillText'
5
5
  import { stroke, strokes } from './Stroke'
6
6
  import { strokeText, drawTextStroke } from './StrokeText'
@@ -12,6 +12,7 @@ export const PaintModule: IPaintModule = {
12
12
  compute,
13
13
  fill,
14
14
  fills,
15
+ fillPathOrText,
15
16
  fillText,
16
17
  stroke,
17
18
  strokes,