@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 +8 -6
- package/src/Compute.ts +3 -2
- package/src/Shape.ts +4 -2
- package/src/Stroke.ts +4 -4
- package/src/index.ts +2 -1
- package/src/paint/image/check.ts +1 -1
- package/src/paint/image/data.ts +2 -6
- package/src/paint/image/image.ts +26 -26
- package/src/paint/image/index.ts +2 -0
- package/src/paint/image/pattern.ts +8 -7
- package/src/paint/image/recycle.ts +41 -0
- package/src/paint/linear.ts +1 -1
- package/types/index.d.ts +21 -0
package/package.json
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-ui/paint",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
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.
|
|
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.
|
|
27
|
-
"@leafer-ui/interface": "1.0.0-beta.
|
|
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/
|
|
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.__
|
|
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 {
|
|
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'
|
package/src/paint/image/check.ts
CHANGED
|
@@ -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
|
|
package/src/paint/image/data.ts
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { IBoundsData, ILeaferImage } from '@leafer/interface'
|
|
2
2
|
import { MatrixHelper } from '@leafer/core'
|
|
3
3
|
|
|
4
|
-
import {
|
|
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(
|
|
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
|
}
|
package/src/paint/image/image.ts
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
13
|
+
const event: IImageEvent = (firstUse || image.loading) && { target: ui, image, attrName, attrValue }
|
|
14
14
|
|
|
15
|
-
if (
|
|
15
|
+
if (image.ready) {
|
|
16
16
|
|
|
17
|
-
|
|
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
|
-
|
|
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
|
-
|
|
31
|
-
|
|
32
|
-
emit(ImageEvent.LOAD, event)
|
|
32
|
+
} else {
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
() => {
|
|
36
|
-
if (ui.__) {
|
|
34
|
+
if (firstUse) emit(ImageEvent.LOAD, event)
|
|
37
35
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
36
|
+
leafPaint.loadId = image.load(
|
|
37
|
+
() => {
|
|
38
|
+
if (!ui.destroyed) {
|
|
42
39
|
|
|
43
|
-
|
|
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
|
|
package/src/paint/image/index.ts
CHANGED
|
@@ -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
|
|
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
|
+
}
|
package/src/paint/linear.ts
CHANGED
|
@@ -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/
|
|
5
|
+
import { ColorConvert } from '@leafer-ui/core'
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
const defaultFrom = { x: 0.5, y: 0 }
|
package/types/index.d.ts
ADDED
|
@@ -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 };
|