@leafer-ui/hit 1.0.0-rc.19 → 1.0.0-rc.20

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/hit",
3
- "version": "1.0.0-rc.19",
3
+ "version": "1.0.0-rc.20",
4
4
  "description": "@leafer-ui/hit",
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.0.0-rc.19",
26
- "@leafer-ui/draw": "1.0.0-rc.19"
25
+ "@leafer/core": "1.0.0-rc.20",
26
+ "@leafer-ui/draw": "1.0.0-rc.20"
27
27
  },
28
28
  "devDependencies": {
29
- "@leafer/interface": "1.0.0-rc.19",
30
- "@leafer-ui/interface": "1.0.0-rc.19"
29
+ "@leafer/interface": "1.0.0-rc.20",
30
+ "@leafer-ui/interface": "1.0.0-rc.20"
31
31
  }
32
32
  }
package/src/LeafHit.ts CHANGED
@@ -1,16 +1,13 @@
1
- import { IRadiusPointData } from '@leafer/interface'
1
+ import { IRadiusPointData, ILeaferCanvas } from '@leafer/interface'
2
2
  import { Leaf, PointHelper, BoundsHelper } from '@leafer/core'
3
3
 
4
4
 
5
5
  const { toInnerRadiusPointOf, copy, setRadius } = PointHelper
6
6
  const inner = {} as IRadiusPointData
7
7
 
8
- Leaf.prototype.__hitWorld = function (point: IRadiusPointData): boolean {
9
- if (this.__layout.hitCanvasChanged || !this.__hitCanvas) {
10
- this.__updateHitCanvas()
11
- if (!this.__layout.boundsChanged) this.__layout.hitCanvasChanged = false
12
- }
8
+ const leaf = Leaf.prototype
13
9
 
10
+ leaf.__hitWorld = function (point: IRadiusPointData): boolean {
14
11
  if (this.__.hitRadius) {
15
12
  copy(inner, point), point = inner
16
13
  setRadius(point, this.__.hitRadius)
@@ -18,9 +15,26 @@ Leaf.prototype.__hitWorld = function (point: IRadiusPointData): boolean {
18
15
 
19
16
  toInnerRadiusPointOf(point, this.__world, inner)
20
17
 
21
- if (this.__.hitBox) {
18
+ const { width, height } = this.__world
19
+ const isSmall = width < 10 && height < 10
20
+
21
+ if (this.__.hitBox || isSmall) {
22
22
  if (BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner)) return true
23
+ if (isSmall) return false
24
+ }
25
+
26
+ if (this.__layout.hitCanvasChanged || !this.__hitCanvas) {
27
+ this.__updateHitCanvas()
28
+ if (!this.__layout.boundsChanged) this.__layout.hitCanvasChanged = false
23
29
  }
24
30
 
25
31
  return this.__hit(inner)
26
- }
32
+ }
33
+
34
+ leaf.__hitFill = function (inner: IRadiusPointData): boolean { return this.__hitCanvas?.hitFill(inner, this.__.windingRule) }
35
+
36
+ leaf.__hitStroke = function (inner: IRadiusPointData, strokeWidth: number): boolean { return this.__hitCanvas?.hitStroke(inner, strokeWidth) }
37
+
38
+ leaf.__hitPixel = function (inner: IRadiusPointData): boolean { return this.__hitCanvas?.hitPixel(inner, this.__layout.renderBounds, this.__hitCanvas.hitScale) }
39
+
40
+ leaf.__drawHitPath = function (canvas: ILeaferCanvas): void { if (canvas) this.__drawRenderPath(canvas) }
package/src/RectHit.ts CHANGED
@@ -11,6 +11,6 @@ Rect.prototype.__updateHitCanvas = function () {
11
11
  if (this.stroke || this.cornerRadius) ui.__updateHitCanvas.call(this)
12
12
  }
13
13
 
14
- Rect.prototype.__hitFill = function (inner: IRadiusPointData, windingRule?: string): boolean {
15
- return this.__hitCanvas ? ui.__hitFill.call(this, inner, windingRule) : BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner)
14
+ Rect.prototype.__hitFill = function (inner: IRadiusPointData): boolean {
15
+ return this.__hitCanvas ? ui.__hitFill.call(this, inner) : BoundsHelper.hitRadiusPoint(this.__layout.boxBounds, inner)
16
16
  }
package/src/UIHit.ts CHANGED
@@ -1,34 +1,71 @@
1
1
  import { IRadiusPointData } from '@leafer/interface'
2
- import { Platform } from '@leafer/core'
3
- import { UI } from '@leafer-ui/draw'
2
+ import { Platform, Matrix, tempBounds } from '@leafer/core'
3
+ import { UI, ImageManager } from '@leafer-ui/draw'
4
4
 
5
5
 
6
- UI.prototype.__updateHitCanvas = function (): void {
7
- if (!this.__hitCanvas) this.__hitCanvas = this.leafer.hitCanvasManager.getPathType(this)
6
+ const matrix = new Matrix()
7
+ const ui = UI.prototype
8
+
9
+ ui.__updateHitCanvas = function (): void {
10
+ const data = this.__, { hitCanvasManager } = this.leafer
11
+
12
+ const isHitPixelFill = data.__pixelFill && data.hitFill === 'pixel'
13
+ const isHitPixelStroke = data.__pixelStroke && data.hitStroke === 'pixel'
14
+ const isHitPixel = isHitPixelFill || isHitPixelStroke
15
+
16
+ if (!this.__hitCanvas) this.__hitCanvas = isHitPixel ? hitCanvasManager.getPixelType(this, { contextSettings: { willReadFrequently: true } }) : hitCanvasManager.getPathType(this)
17
+
8
18
  const h = this.__hitCanvas
19
+
20
+ if (isHitPixel) {
21
+ const { renderBounds } = this.__layout
22
+ const size = Platform.image.hitCanvasSize
23
+ const scale = h.hitScale = tempBounds.set(0, 0, size, size).getFitMatrix(renderBounds, 0.5).a
24
+ const { x, y, width, height } = tempBounds.set(renderBounds).scale(scale)
25
+ h.resize({ width, height, pixelRatio: 1 })
26
+ h.clear()
27
+
28
+ ImageManager.patternLocked = true
29
+ this.__renderShape(h, { matrix: matrix.setWith(this.__world).scaleWith(1 / scale).invertWith().translate(-x, -y) }, !isHitPixelFill, !isHitPixelStroke) // 矩阵
30
+ ImageManager.patternLocked = false
31
+ h.resetTransform()
32
+
33
+ data.__isHitPixel = true
34
+ } else {
35
+ data.__isHitPixel && (data.__isHitPixel = false)
36
+ }
37
+
9
38
  this.__drawHitPath(h)
10
- h.setStrokeOptions(this.__)
39
+ h.setStrokeOptions(data)
40
+
11
41
  }
12
42
 
13
- UI.prototype.__hit = function (inner: IRadiusPointData): boolean {
43
+ ui.__hit = function (inner: IRadiusPointData): boolean {
14
44
  if (Platform.name === 'miniapp') this.__drawHitPath(this.__hitCanvas) // fix: 小程序需要实时更新
15
45
 
16
- const { fill, hitFill, windingRule } = this.__
17
- const needHitFill = (fill && hitFill === 'path') || hitFill === 'all'
18
- const isHitFill = this.__hitFill(inner, windingRule)
19
- if (needHitFill && isHitFill) return true
46
+ // hit pixel
20
47
 
21
- const { stroke, hitStroke, __strokeWidth, strokeAlign } = this.__
22
- const needHitStroke = (stroke && hitStroke === 'path') || hitStroke === 'all'
23
- const radiusWidth = inner.radiusX * 2
48
+ const data = this.__
49
+ if (data.__isHitPixel && this.__hitPixel(inner)) return true
50
+
51
+ // hit path
24
52
 
53
+ const { hitFill } = data
54
+ const needHitFillPath = ((data.fill && hitFill == 'path') || hitFill === 'all')
55
+ if (needHitFillPath && this.__hitFill(inner)) return true
56
+
57
+ const { hitStroke, __strokeWidth } = data
58
+ const needHitStrokePath = ((data.stroke && hitStroke == 'path') || hitStroke === 'all')
59
+ if (!needHitFillPath && !needHitStrokePath) return false
60
+
61
+ const radiusWidth = inner.radiusX * 2
25
62
  let hitWidth = radiusWidth
26
63
 
27
- if (needHitStroke) {
28
- switch (strokeAlign) {
64
+ if (needHitStrokePath) {
65
+ switch (data.strokeAlign) {
29
66
  case 'inside':
30
67
  hitWidth += __strokeWidth * 2
31
- if (!needHitFill && (isHitFill && this.__hitStroke(inner, hitWidth))) return true
68
+ if (!needHitFillPath && this.__hitFill(inner) && this.__hitStroke(inner, hitWidth)) return true
32
69
  hitWidth = radiusWidth
33
70
  break
34
71
  case 'center':
@@ -36,8 +73,8 @@ UI.prototype.__hit = function (inner: IRadiusPointData): boolean {
36
73
  break
37
74
  case 'outside':
38
75
  hitWidth += __strokeWidth * 2
39
- if (!needHitFill) {
40
- if (!isHitFill && this.__hitStroke(inner, hitWidth)) return true
76
+ if (!needHitFillPath) {
77
+ if (!this.__hitFill(inner) && this.__hitStroke(inner, hitWidth)) return true
41
78
  hitWidth = radiusWidth
42
79
  }
43
80
  break
@@ -45,4 +82,4 @@ UI.prototype.__hit = function (inner: IRadiusPointData): boolean {
45
82
  }
46
83
 
47
84
  return hitWidth ? this.__hitStroke(inner, hitWidth) : false
48
- }
85
+ }