@leafer-ui/paint 1.6.2 → 1.6.4

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.2",
3
+ "version": "1.6.4",
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.2",
26
- "@leafer-ui/draw": "1.6.2"
25
+ "@leafer/core": "1.6.4",
26
+ "@leafer-ui/draw": "1.6.4"
27
27
  },
28
28
  "devDependencies": {
29
- "@leafer/interface": "1.6.2",
30
- "@leafer-ui/interface": "1.6.2"
29
+ "@leafer/interface": "1.6.4",
30
+ "@leafer-ui/interface": "1.6.4"
31
31
  }
32
32
  }
package/src/Compute.ts CHANGED
@@ -1,46 +1,74 @@
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)
14
17
 
15
18
  for (let i = 0, len = paints.length, item: ILeafPaint; i < len; i++) {
16
- item = getLeafPaint(attrName, paints[i], ui)
17
- if (item) leafPaints.push(item)
19
+ (item = getLeafPaint(attrName, paints[i], ui)) && leafPaints.push(item)
18
20
  }
19
21
 
20
22
  (data as IObject)['_' + attrName] = leafPaints.length ? leafPaints : undefined
21
23
 
22
- if (leafPaints.length && leafPaints[0].image) hasOpacityPixel = leafPaints[0].image.hasOpacityPixel
23
- attrName === 'fill' ? data.__pixelFill = hasOpacityPixel : data.__pixelStroke = hasOpacityPixel
24
+ if (leafPaints.length) {
25
+ if (leafPaints.every(item => item.isTransparent)) {
26
+ if (leafPaints.some(item => item.image)) isAlphaPixel = true
27
+ isTransparent = true
28
+ }
29
+ }
30
+
31
+ if (attrName === 'fill') {
32
+ stintSet(data, '__isAlphaPixelFill', isAlphaPixel)
33
+ stintSet(data, '__isTransparentFill', isTransparent)
34
+ } else {
35
+ stintSet(data, '__isAlphaPixelStroke', isAlphaPixel)
36
+ stintSet(data, '__isTransparentStroke', isTransparent)
37
+ }
24
38
  }
25
39
 
26
40
 
27
41
  function getLeafPaint(attrName: string, paint: IPaint, ui: IUI): ILeafPaint {
28
42
  if (typeof paint !== 'object' || paint.visible === false || paint.opacity === 0) return undefined
43
+
44
+ let data: ILeafPaint
29
45
  const { boxBounds } = ui.__layout
30
46
 
31
47
  switch (paint.type) {
32
- case 'solid':
33
- let { type, blendMode, color, opacity } = paint
34
- return { type, blendMode, style: ColorConvert.string(color, opacity) }
35
48
  case 'image':
36
- return PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url])
49
+ data = PaintImage.image(ui, attrName, paint, boxBounds, !recycleMap || !recycleMap[paint.url])
50
+ break
37
51
  case 'linear':
38
- return PaintGradient.linearGradient(paint, boxBounds)
52
+ data = PaintGradient.linearGradient(paint, boxBounds)
53
+ break
39
54
  case 'radial':
40
- return PaintGradient.radialGradient(paint, boxBounds)
55
+ data = PaintGradient.radialGradient(paint, boxBounds)
56
+ break
41
57
  case 'angular':
42
- return PaintGradient.conicGradient(paint, boxBounds)
58
+ data = PaintGradient.conicGradient(paint, boxBounds)
59
+ break
60
+ case 'solid':
61
+ const { type, color, opacity } = paint
62
+ data = { type, style: ColorConvert.string(color, opacity) }
63
+ break
43
64
  default:
44
- return (paint as IRGB).r !== undefined ? { type: 'solid', style: ColorConvert.string(paint) } : undefined
65
+ if ((paint as IRGB).r !== undefined) data = { type: 'solid', style: ColorConvert.string(paint) }
45
66
  }
67
+
68
+ if (data) {
69
+ if (typeof data.style === 'string' && hasTransparent(data.style)) data.isTransparent = true
70
+ if (paint.blendMode) data.blendMode = paint.blendMode
71
+ }
72
+
73
+ return data
46
74
  }
package/src/Stroke.ts CHANGED
@@ -1,59 +1,30 @@
1
1
  import { ILeaferCanvas } from '@leafer/interface'
2
2
 
3
3
  import { IUI, ILeafPaint } from '@leafer-ui/interface'
4
+ import { Paint } from '@leafer-ui/draw'
4
5
 
5
- import { strokeText, drawStrokesStyle } from './StrokeText'
6
+ import { strokeText, drawStrokesStyle, copyWorld } from './StrokeText'
6
7
 
7
8
 
8
9
  export function stroke(stroke: string, ui: IUI, canvas: ILeaferCanvas): void {
9
- const options = ui.__
10
- const { __strokeWidth, strokeAlign, __font } = options
11
- if (!__strokeWidth) return
10
+ const data = ui.__
11
+ if (!data.__strokeWidth) return
12
12
 
13
- if (__font) {
13
+ if (data.__font) {
14
14
 
15
15
  strokeText(stroke, ui, canvas)
16
16
 
17
17
  } else {
18
18
 
19
- switch (strokeAlign) {
20
-
19
+ switch (data.strokeAlign) {
21
20
  case 'center':
22
-
23
- canvas.setStroke(stroke, __strokeWidth, options)
24
- canvas.stroke()
25
-
26
- if (options.__useArrow) strokeArrow(ui, canvas)
27
-
21
+ drawCenter(stroke, 1, ui, canvas)
28
22
  break
29
-
30
23
  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
-
24
+ drawInside(stroke, ui, canvas)
40
25
  break
41
-
42
26
  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)
27
+ drawOutside(stroke, ui, canvas)
57
28
  break
58
29
  }
59
30
 
@@ -62,64 +33,45 @@ export function stroke(stroke: string, ui: IUI, canvas: ILeaferCanvas): void {
62
33
 
63
34
 
64
35
  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)
36
+ stroke(strokes as any, ui, canvas)
37
+ }
72
38
 
73
- } else {
74
39
 
75
- switch (strokeAlign) {
40
+ function drawCenter(stroke: string | ILeafPaint[], strokeWidthScale: number, ui: IUI, canvas: ILeaferCanvas) {
41
+ const data = ui.__
42
+ canvas.setStroke(!data.__isStrokes && stroke as string, data.__strokeWidth * strokeWidthScale, data)
43
+ data.__isStrokes ? drawStrokesStyle(stroke as ILeafPaint[], false, ui, canvas) : canvas.stroke()
76
44
 
77
- case 'center':
78
- canvas.setStroke(undefined, __strokeWidth, options)
79
- drawStrokesStyle(strokes, false, ui, canvas)
45
+ if (data.__useArrow) Paint.strokeArrow(stroke, ui, canvas)
80
46
 
81
- if (options.__useArrow) strokeArrow(ui, canvas)
82
- break
47
+ }
83
48
 
84
- case 'inside':
85
- canvas.save()
86
- canvas.setStroke(undefined, __strokeWidth * 2, options)
87
- options.windingRule ? canvas.clip(options.windingRule) : canvas.clip()
49
+ function drawInside(stroke: string | ILeafPaint[], ui: IUI, canvas: ILeaferCanvas) {
50
+ canvas.save()
51
+ canvas.clipUI(ui)
88
52
 
89
- drawStrokesStyle(strokes, false, ui, canvas)
53
+ drawCenter(stroke, 2, ui, canvas)
54
+ canvas.restore()
55
+ }
90
56
 
91
- canvas.restore()
92
- break
57
+ function drawOutside(stroke: string | ILeafPaint[], ui: IUI, canvas: ILeaferCanvas) {
58
+ const data = ui.__
59
+ if (data.__fillAfterStroke) {
93
60
 
94
- case 'outside':
95
- const { renderBounds } = ui.__layout
96
- const out = canvas.getSameCanvas(true, true)
97
- ui.__drawRenderPath(out)
61
+ drawCenter(stroke, 2, ui, canvas)
98
62
 
99
- out.setStroke(undefined, __strokeWidth * 2, options)
100
-
101
- drawStrokesStyle(strokes, false, ui, out)
63
+ } else {
64
+ const { renderBounds } = ui.__layout
65
+ const out = canvas.getSameCanvas(true, true)
66
+ ui.__drawRenderPath(out)
102
67
 
103
- options.windingRule ? out.clip(options.windingRule) : out.clip()
104
- out.clearWorld(renderBounds)
68
+ drawCenter(stroke, 2, ui, out)
105
69
 
106
- if (ui.__worldFlipped) canvas.copyWorldByReset(out, ui.__nowWorld)
107
- else canvas.copyWorldToInner(out, ui.__nowWorld, renderBounds)
70
+ out.clipUI(data)
71
+ out.clearWorld(renderBounds)
108
72
 
109
- out.recycle(ui.__nowWorld)
110
- break
111
- }
73
+ copyWorld(canvas, out, ui)
112
74
 
75
+ out.recycle(ui.__nowWorld)
113
76
  }
114
-
115
77
  }
116
-
117
-
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()
124
- }
125
- }
package/src/StrokeText.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ILeaferCanvas } from '@leafer/interface'
2
+ import { Platform } from "@leafer/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,46 @@ 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)
40
- else canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds)
39
+ copyWorld(canvas, out, ui)
41
40
 
42
41
  out.recycle(ui.__nowWorld)
43
42
  }
44
43
 
44
+
45
+ export function copyWorld(canvas: ILeaferCanvas, out: ILeaferCanvas, ui: IUI): void {
46
+ if (ui.__worldFlipped || Platform.fullImageShadow) canvas.copyWorldByReset(out, ui.__nowWorld)
47
+ else canvas.copyWorldToInner(out, ui.__nowWorld, ui.__layout.renderBounds)
48
+ }
49
+
50
+
45
51
  export function drawTextStroke(ui: IUI, canvas: ILeaferCanvas): void {
46
52
 
47
53
  let row: ITextRowData, data = ui.__.__textDrawData