@leafer-ui/paint 1.0.0-rc.6 → 1.0.0-rc.8
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 +4 -4
- package/src/Compute.ts +2 -2
- package/src/Stroke.ts +2 -2
- package/src/StrokeText.ts +1 -1
- package/src/paint/image/check.ts +15 -8
- package/src/paint/image/data.ts +3 -1
- package/src/paint/image/image.ts +4 -0
- package/src/paint/image/pattern.ts +32 -24
- package/src/paint/image/recycle.ts +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leafer-ui/paint",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.8",
|
|
4
4
|
"description": "@leafer-ui/paint",
|
|
5
5
|
"author": "Chao (Leafer) Wan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"leaferjs"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@leafer/core": "1.0.0-rc.
|
|
25
|
+
"@leafer/core": "1.0.0-rc.8"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@leafer/interface": "1.0.0-rc.
|
|
29
|
-
"@leafer-ui/interface": "1.0.0-rc.
|
|
28
|
+
"@leafer/interface": "1.0.0-rc.8",
|
|
29
|
+
"@leafer-ui/interface": "1.0.0-rc.8"
|
|
30
30
|
}
|
|
31
31
|
}
|
package/src/Compute.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IUI, IPaint, ILeafPaint, IRGB, IBooleanMap, IImagePaint } from '@leafer-ui/interface'
|
|
1
|
+
import { IUI, IPaint, ILeafPaint, IRGB, IBooleanMap, IImagePaint, IObject } from '@leafer-ui/interface'
|
|
2
2
|
import { ColorConvert, ImageManager } from '@leafer-ui/core'
|
|
3
3
|
|
|
4
4
|
import { image } from "./paint/image/image"
|
|
@@ -26,7 +26,7 @@ export function compute(attrName: 'fill' | 'stroke', ui: IUI): void {
|
|
|
26
26
|
if (item) value.push(item)
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
data['_' + attrName] = value.length ? value : undefined
|
|
29
|
+
(data as IObject)['_' + attrName] = value.length ? value : undefined
|
|
30
30
|
|
|
31
31
|
// check png / svg / webp
|
|
32
32
|
|
package/src/Stroke.ts
CHANGED
|
@@ -47,7 +47,7 @@ export function stroke(stroke: string, ui: IUI, canvas: ILeaferCanvas, renderOpt
|
|
|
47
47
|
options.windingRule ? out.clip(options.windingRule) : out.clip()
|
|
48
48
|
out.clearWorld(ui.__layout.renderBounds)
|
|
49
49
|
|
|
50
|
-
if (ui.
|
|
50
|
+
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
51
51
|
canvas.copyWorldByReset(out)
|
|
52
52
|
} else {
|
|
53
53
|
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds)
|
|
@@ -102,7 +102,7 @@ export function strokes(strokes: ILeafPaint[], ui: IUI, canvas: ILeaferCanvas, r
|
|
|
102
102
|
options.windingRule ? out.clip(options.windingRule) : out.clip()
|
|
103
103
|
out.clearWorld(renderBounds)
|
|
104
104
|
|
|
105
|
-
if (ui.
|
|
105
|
+
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
106
106
|
canvas.copyWorldByReset(out)
|
|
107
107
|
} else {
|
|
108
108
|
canvas.copyWorldToInner(out, ui.__world, renderBounds)
|
package/src/StrokeText.ts
CHANGED
|
@@ -36,7 +36,7 @@ function drawAlignStroke(align: IStrokeAlign, stroke: string | ILeafPaint[], isS
|
|
|
36
36
|
fillText(ui, out)
|
|
37
37
|
out.blendMode = 'normal'
|
|
38
38
|
|
|
39
|
-
if (ui.
|
|
39
|
+
if (ui.__worldFlipped || renderOptions.matrix) {
|
|
40
40
|
canvas.copyWorldByReset(out)
|
|
41
41
|
} else {
|
|
42
42
|
canvas.copyWorldToInner(out, ui.__world, ui.__layout.renderBounds)
|
package/src/paint/image/check.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
import { ILeaferCanvas } from '@leafer/interface'
|
|
3
|
-
import { ImageManager } from '@leafer/core'
|
|
3
|
+
import { ImageManager, Platform } from '@leafer/core'
|
|
4
4
|
|
|
5
5
|
import { IUI, ILeafPaint } from '@leafer-ui/interface'
|
|
6
|
+
import { Export } from '@leafer-ui/external'
|
|
6
7
|
|
|
7
8
|
import { createPattern } from './pattern'
|
|
8
9
|
|
|
10
|
+
const { abs } = Math
|
|
9
11
|
|
|
10
12
|
export function checkImage(ui: IUI, canvas: ILeaferCanvas, paint: ILeafPaint, allowPaint?: boolean): boolean {
|
|
11
13
|
const { scaleX, scaleY } = ui.__world
|
|
@@ -14,12 +16,18 @@ export function checkImage(ui: IUI, canvas: ILeaferCanvas, paint: ILeafPaint, al
|
|
|
14
16
|
return false
|
|
15
17
|
} else {
|
|
16
18
|
|
|
19
|
+
const { data } = paint
|
|
20
|
+
|
|
17
21
|
if (allowPaint) {
|
|
18
|
-
if (
|
|
19
|
-
let { width, height } =
|
|
20
|
-
width *= scaleX * canvas.pixelRatio
|
|
21
|
-
height *= scaleY * canvas.pixelRatio
|
|
22
|
-
|
|
22
|
+
if (!data.repeat) {
|
|
23
|
+
let { width, height } = data
|
|
24
|
+
width *= abs(scaleX) * canvas.pixelRatio
|
|
25
|
+
height *= abs(scaleY) * canvas.pixelRatio
|
|
26
|
+
if (data.scaleX) {
|
|
27
|
+
width *= data.scaleX
|
|
28
|
+
height *= data.scaleY
|
|
29
|
+
}
|
|
30
|
+
allowPaint = width * height > Platform.image.maxCacheSize
|
|
23
31
|
} else {
|
|
24
32
|
allowPaint = false
|
|
25
33
|
}
|
|
@@ -28,7 +36,6 @@ export function checkImage(ui: IUI, canvas: ILeaferCanvas, paint: ILeafPaint, al
|
|
|
28
36
|
if (allowPaint) {
|
|
29
37
|
canvas.save()
|
|
30
38
|
canvas.clip()
|
|
31
|
-
const { data } = paint
|
|
32
39
|
if (paint.blendMode) canvas.blendMode = paint.blendMode
|
|
33
40
|
if (data.opacity) canvas.opacity *= data.opacity
|
|
34
41
|
if (data.transform) canvas.transform(data.transform)
|
|
@@ -36,7 +43,7 @@ export function checkImage(ui: IUI, canvas: ILeaferCanvas, paint: ILeafPaint, al
|
|
|
36
43
|
canvas.restore()
|
|
37
44
|
return true
|
|
38
45
|
} else {
|
|
39
|
-
if (!paint.style) {
|
|
46
|
+
if (!paint.style || Export.running) {
|
|
40
47
|
createPattern(ui, paint, canvas.pixelRatio)
|
|
41
48
|
} else {
|
|
42
49
|
if (!paint.patternTask) {
|
package/src/paint/image/data.ts
CHANGED
|
@@ -11,7 +11,7 @@ const { get, translate } = MatrixHelper
|
|
|
11
11
|
export function createData(leafPaint: ILeafPaint, image: ILeaferImage, paint: IImagePaint, box: IBoundsData): void {
|
|
12
12
|
let { width, height } = image
|
|
13
13
|
|
|
14
|
-
const { opacity, mode, offset, scale, rotation, blendMode } = paint
|
|
14
|
+
const { opacity, mode, offset, scale, rotation, blendMode, repeat } = paint
|
|
15
15
|
const sameBox = box.width === width && box.height === height
|
|
16
16
|
if (blendMode) leafPaint.blendMode = blendMode
|
|
17
17
|
|
|
@@ -30,6 +30,7 @@ export function createData(leafPaint: ILeafPaint, image: ILeaferImage, paint: II
|
|
|
30
30
|
break
|
|
31
31
|
case 'repeat':
|
|
32
32
|
if (!sameBox || scale || rotation) repeatMode(data, box, width, height, scale as number, rotation)
|
|
33
|
+
if (!repeat) data.repeat = 'repeat'
|
|
33
34
|
break
|
|
34
35
|
case 'fit':
|
|
35
36
|
case 'cover':
|
|
@@ -40,4 +41,5 @@ export function createData(leafPaint: ILeafPaint, image: ILeaferImage, paint: II
|
|
|
40
41
|
data.width = width
|
|
41
42
|
data.height = height
|
|
42
43
|
if (opacity) data.opacity = opacity
|
|
44
|
+
if (repeat) data.repeat = typeof repeat === 'string' ? (repeat === 'x' ? 'repeat-x' : 'repeat-y') : 'repeat'
|
|
43
45
|
}
|
package/src/paint/image/image.ts
CHANGED
|
@@ -65,6 +65,10 @@ function hasNaturalSize(ui: IUI, attrName: string, image: ISizeData): boolean {
|
|
|
65
65
|
d.__naturalHeight = image.height
|
|
66
66
|
if (!d.__getInput('width') || !d.__getInput('height')) {
|
|
67
67
|
ui.forceUpdate('width')
|
|
68
|
+
if (ui.__proxyData) {
|
|
69
|
+
ui.setProxyAttr('width', ui.__.width)
|
|
70
|
+
ui.setProxyAttr('height', ui.__.height)
|
|
71
|
+
}
|
|
68
72
|
return false
|
|
69
73
|
}
|
|
70
74
|
}
|
|
@@ -3,7 +3,7 @@ import { Platform, MatrixHelper } from '@leafer/core'
|
|
|
3
3
|
import { IUI, ILeafPaint, IMatrixData } from '@leafer-ui/interface'
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
const { get, scale
|
|
6
|
+
const { get, scale, copy } = MatrixHelper
|
|
7
7
|
|
|
8
8
|
export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): boolean {
|
|
9
9
|
|
|
@@ -13,20 +13,16 @@ export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): b
|
|
|
13
13
|
|
|
14
14
|
if (paint.patternId !== id && !ui.destroyed) {
|
|
15
15
|
|
|
16
|
-
paint.patternId = id
|
|
17
|
-
|
|
18
16
|
scaleX = Math.abs(scaleX) // maybe -1
|
|
19
17
|
scaleY = Math.abs(scaleY)
|
|
20
18
|
|
|
21
19
|
const { image, data } = paint
|
|
22
|
-
|
|
23
|
-
const maxHeight = image.isSVG ? 4096 : Math.min(image.height, 4096)
|
|
24
|
-
let scale: number, matrix: IMatrixData, { width, height, scaleX: sx, scaleY: sy, opacity, transform, mode } = data
|
|
20
|
+
let imageScale: number, imageMatrix: IMatrixData, { width, height, scaleX: sx, scaleY: sy, opacity, transform, repeat } = data
|
|
25
21
|
|
|
26
22
|
if (sx) {
|
|
27
|
-
|
|
28
|
-
copy(
|
|
29
|
-
|
|
23
|
+
imageMatrix = get()
|
|
24
|
+
copy(imageMatrix, transform)
|
|
25
|
+
scale(imageMatrix, 1 / sx, 1 / sy)
|
|
30
26
|
scaleX *= sx
|
|
31
27
|
scaleY *= sy
|
|
32
28
|
}
|
|
@@ -36,15 +32,26 @@ export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): b
|
|
|
36
32
|
width *= scaleX
|
|
37
33
|
height *= scaleY
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
const size = width * height
|
|
36
|
+
|
|
37
|
+
if (!repeat) {
|
|
38
|
+
if (size > Platform.image.maxCacheSize) return false // same as check()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let maxSize = Platform.image.maxPatternSize
|
|
42
|
+
|
|
43
|
+
if (!image.isSVG) {
|
|
44
|
+
const imageSize = image.width * image.height
|
|
45
|
+
if (maxSize > imageSize) maxSize = imageSize
|
|
41
46
|
}
|
|
42
47
|
|
|
43
|
-
if (
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
if (size > maxSize) imageScale = Math.sqrt(size / maxSize)
|
|
49
|
+
|
|
50
|
+
if (imageScale) {
|
|
51
|
+
scaleX /= imageScale
|
|
52
|
+
scaleY /= imageScale
|
|
53
|
+
width /= imageScale
|
|
54
|
+
height /= imageScale
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
if (sx) {
|
|
@@ -53,23 +60,24 @@ export function createPattern(ui: IUI, paint: ILeafPaint, pixelRatio: number): b
|
|
|
53
60
|
}
|
|
54
61
|
|
|
55
62
|
if (transform || scaleX !== 1 || scaleY !== 1) {
|
|
56
|
-
if (!
|
|
57
|
-
|
|
58
|
-
if (transform) copy(
|
|
63
|
+
if (!imageMatrix) {
|
|
64
|
+
imageMatrix = get()
|
|
65
|
+
if (transform) copy(imageMatrix, transform)
|
|
59
66
|
}
|
|
60
|
-
|
|
67
|
+
scale(imageMatrix, 1 / scaleX, 1 / scaleY)
|
|
61
68
|
}
|
|
62
69
|
|
|
63
|
-
const
|
|
70
|
+
const pattern = Platform.canvas.createPattern(image.getCanvas(width < 1 ? 1 : width, height < 1 ? 1 : height, opacity) as any, repeat || (Platform.origin.noRepeat || 'no-repeat'))
|
|
64
71
|
|
|
65
72
|
try {
|
|
66
73
|
if (paint.transform) paint.transform = null
|
|
67
|
-
if (
|
|
74
|
+
if (imageMatrix) pattern.setTransform ? pattern.setTransform(imageMatrix) : paint.transform = imageMatrix
|
|
68
75
|
} catch {
|
|
69
|
-
paint.transform =
|
|
76
|
+
paint.transform = imageMatrix
|
|
70
77
|
}
|
|
71
78
|
|
|
72
|
-
paint.style =
|
|
79
|
+
paint.style = pattern
|
|
80
|
+
paint.patternId = id
|
|
73
81
|
|
|
74
82
|
return true
|
|
75
83
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { IBooleanMap, ILeaferImage } from '@leafer/interface'
|
|
1
|
+
import { IBooleanMap, ILeaferImage, IObject } from '@leafer/interface'
|
|
2
2
|
import { ImageManager } from '@leafer/core'
|
|
3
3
|
|
|
4
4
|
import { IImagePaint, ILeafPaint, IUIData } from '@leafer-ui/interface'
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
export function recycleImage(attrName: 'fill' | 'stroke', data: IUIData): IBooleanMap {
|
|
8
|
-
const paints = (
|
|
8
|
+
const paints = (data as IObject)['_' + attrName] as ILeafPaint[]
|
|
9
9
|
|
|
10
10
|
if (paints instanceof Array) {
|
|
11
11
|
|