@leafer-in/viewport 1.1.1
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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/viewport.cjs +353 -0
- package/dist/viewport.esm.js +346 -0
- package/dist/viewport.esm.min.js +1 -0
- package/dist/viewport.js +357 -0
- package/dist/viewport.min.cjs +1 -0
- package/dist/viewport.min.js +1 -0
- package/package.json +41 -0
- package/src/Leafer.ts +46 -0
- package/src/LeaferTypeCreator.ts +34 -0
- package/src/index.ts +9 -0
- package/src/interaction/Dragger.ts +73 -0
- package/src/interaction/Interaction.ts +63 -0
- package/src/interaction/MultiTouchHelper.ts +23 -0
- package/src/interaction/Transformer.ts +98 -0
- package/src/interaction/WheelEventHelper.ts +48 -0
- package/src/type/custom.ts +8 -0
- package/src/type/design.ts +17 -0
- package/src/type/document.ts +11 -0
- package/src/type/viewport.ts +32 -0
- package/types/index.d.ts +40 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { IMultiTouchData, IKeepTouchData } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { PointHelper } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export const MultiTouchHelper = {
|
|
7
|
+
|
|
8
|
+
getData(list: IKeepTouchData[]): IMultiTouchData {
|
|
9
|
+
const a = list[0], b = list[1]
|
|
10
|
+
const lastCenter = PointHelper.getCenter(a.from, b.from)
|
|
11
|
+
const center = PointHelper.getCenter(a.to, b.to)
|
|
12
|
+
const move = { x: center.x - lastCenter.x, y: center.y - lastCenter.y }
|
|
13
|
+
|
|
14
|
+
const lastDistance = PointHelper.getDistance(a.from, b.from)
|
|
15
|
+
const distance = PointHelper.getDistance(a.to, b.to)
|
|
16
|
+
const scale = distance / lastDistance
|
|
17
|
+
|
|
18
|
+
const rotation = PointHelper.getRotation(a.from, b.from, a.to, b.to)
|
|
19
|
+
|
|
20
|
+
return { move, scale, rotation, center }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { IMoveEvent, IZoomEvent, IRotateEvent, ITimer } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { InteractionBase, MoveEvent, ZoomEvent, RotateEvent } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export class Transformer {
|
|
7
|
+
|
|
8
|
+
public get transforming(): boolean { return !!(this.moveData || this.zoomData || this.rotateData) }
|
|
9
|
+
|
|
10
|
+
protected interaction: InteractionBase
|
|
11
|
+
protected moveData: IMoveEvent
|
|
12
|
+
protected zoomData: IZoomEvent
|
|
13
|
+
protected rotateData: IRotateEvent
|
|
14
|
+
protected transformTimer: ITimer
|
|
15
|
+
|
|
16
|
+
constructor(interaction: InteractionBase) {
|
|
17
|
+
this.interaction = interaction
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public move(data: IMoveEvent): void {
|
|
21
|
+
const { interaction } = this
|
|
22
|
+
if (!data.moveType) data.moveType = 'move'
|
|
23
|
+
|
|
24
|
+
if (!this.moveData) {
|
|
25
|
+
this.setPath(data)
|
|
26
|
+
this.moveData = { ...data, moveX: 0, moveY: 0 }
|
|
27
|
+
interaction.emit(MoveEvent.START, this.moveData)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
data.path = this.moveData.path
|
|
31
|
+
interaction.emit(MoveEvent.BEFORE_MOVE, data)
|
|
32
|
+
interaction.emit(MoveEvent.MOVE, data)
|
|
33
|
+
|
|
34
|
+
this.transformEndWait()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public zoom(data: IZoomEvent): void {
|
|
38
|
+
const { interaction } = this
|
|
39
|
+
|
|
40
|
+
if (!this.zoomData) {
|
|
41
|
+
this.setPath(data)
|
|
42
|
+
this.zoomData = { ...data, scale: 1 }
|
|
43
|
+
interaction.emit(ZoomEvent.START, this.zoomData)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
data.path = this.zoomData.path
|
|
47
|
+
interaction.emit(ZoomEvent.BEFORE_ZOOM, data)
|
|
48
|
+
interaction.emit(ZoomEvent.ZOOM, data)
|
|
49
|
+
|
|
50
|
+
this.transformEndWait()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
public rotate(data: IRotateEvent): void {
|
|
54
|
+
const { interaction } = this
|
|
55
|
+
|
|
56
|
+
if (!this.rotateData) {
|
|
57
|
+
this.setPath(data)
|
|
58
|
+
this.rotateData = { ...data, rotation: 0 }
|
|
59
|
+
interaction.emit(RotateEvent.START, this.rotateData)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
data.path = this.rotateData.path
|
|
63
|
+
interaction.emit(RotateEvent.BEFORE_ROTATE, data)
|
|
64
|
+
interaction.emit(RotateEvent.ROTATE, data)
|
|
65
|
+
|
|
66
|
+
this.transformEndWait()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public setPath(data: any): void {
|
|
70
|
+
const { interaction } = this
|
|
71
|
+
const { path } = interaction.selector.getByPoint(data, interaction.hitRadius)
|
|
72
|
+
data.path = path
|
|
73
|
+
interaction.cancelHover()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
protected transformEndWait(): void {
|
|
77
|
+
clearTimeout(this.transformTimer)
|
|
78
|
+
this.transformTimer = setTimeout(() => {
|
|
79
|
+
this.transformEnd()
|
|
80
|
+
}, this.interaction.p.transformTime)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
public transformEnd(): void {
|
|
84
|
+
const { interaction, moveData, zoomData, rotateData } = this
|
|
85
|
+
if (moveData) interaction.emit(MoveEvent.END, moveData)
|
|
86
|
+
if (zoomData) interaction.emit(ZoomEvent.END, zoomData)
|
|
87
|
+
if (rotateData) interaction.emit(RotateEvent.END, rotateData)
|
|
88
|
+
this.reset()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public reset(): void {
|
|
92
|
+
this.zoomData = this.moveData = this.rotateData = null
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public destroy(): void {
|
|
96
|
+
this.reset()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { IPointData, IWheelEvent, IWheelConfig } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { MathHelper, Platform } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export const WheelEventHelper = {
|
|
7
|
+
|
|
8
|
+
getMove(event: IWheelEvent, config: IWheelConfig): IPointData {
|
|
9
|
+
let { moveSpeed } = config
|
|
10
|
+
let { deltaX, deltaY } = event
|
|
11
|
+
if (event.shiftKey && !deltaX) { // Window
|
|
12
|
+
deltaX = deltaY
|
|
13
|
+
deltaY = 0
|
|
14
|
+
}
|
|
15
|
+
if (deltaX > 50) deltaX = Math.max(50, deltaX / 3)
|
|
16
|
+
if (deltaY > 50) deltaY = Math.max(50, deltaY / 3)
|
|
17
|
+
return { x: -deltaX * moveSpeed * 2, y: -deltaY * moveSpeed * 2 }
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
getScale(event: IWheelEvent, config: IWheelConfig): number {
|
|
21
|
+
|
|
22
|
+
let zoom: boolean
|
|
23
|
+
let scale = 1
|
|
24
|
+
let { zoomMode, zoomSpeed } = config
|
|
25
|
+
|
|
26
|
+
const delta = event.deltaY || event.deltaX
|
|
27
|
+
|
|
28
|
+
if (zoomMode) {
|
|
29
|
+
// mac 触摸板滚动手势的deltaY是整数, 鼠标滚动/触摸板缩放的deltaY有小数点, firfox鼠标滚动为整数,为18或19的倍数
|
|
30
|
+
// windows 始终是整数
|
|
31
|
+
zoom = (zoomMode === 'mouse') ? true : (!event.deltaX && (Platform.intWheelDeltaY ? Math.abs(delta) > 17 : Math.ceil(delta) !== delta))
|
|
32
|
+
if (event.shiftKey || event.metaKey || event.ctrlKey) zoom = true
|
|
33
|
+
} else {
|
|
34
|
+
zoom = !event.shiftKey && (event.metaKey || event.ctrlKey)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (zoom) {
|
|
38
|
+
zoomSpeed = MathHelper.within(zoomSpeed, 0, 1)
|
|
39
|
+
const min = event.deltaY ? config.delta.y : config.delta.x
|
|
40
|
+
scale = 1 - delta / (min * 4) * zoomSpeed // zoomSpeed
|
|
41
|
+
if (scale < 0.5) scale = 0.5
|
|
42
|
+
if (scale >= 1.5) scale = 1.5
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return scale
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ILeaferBase } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { addViewport } from './viewport'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export function design(leafer: ILeaferBase): void {
|
|
7
|
+
addViewport(leafer, {
|
|
8
|
+
zoom: {
|
|
9
|
+
min: 0.01,
|
|
10
|
+
max: 256
|
|
11
|
+
},
|
|
12
|
+
move: {
|
|
13
|
+
holdSpaceKey: true,
|
|
14
|
+
holdMiddleKey: true,
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ILeaferBase, IPointData, ILeaferConfig } from '@leafer-ui/interface'
|
|
2
|
+
|
|
3
|
+
import { MoveEvent, ZoomEvent, PointHelper, DataHelper } from '@leafer-ui/core'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
export function addViewport(leafer: ILeaferBase, mergeConfig?: ILeaferConfig, custom?: boolean): void {
|
|
7
|
+
addViewportConfig(leafer.parentApp ? leafer.parentApp : leafer, mergeConfig)
|
|
8
|
+
if (leafer.isApp || custom) return
|
|
9
|
+
|
|
10
|
+
leafer.__eventIds.push(
|
|
11
|
+
leafer.on_(MoveEvent.BEFORE_MOVE, (e: MoveEvent) => {
|
|
12
|
+
leafer.zoomLayer.move(leafer.getValidMove(e.moveX, e.moveY))
|
|
13
|
+
}),
|
|
14
|
+
leafer.on_(ZoomEvent.BEFORE_ZOOM, (e: ZoomEvent) => {
|
|
15
|
+
const { zoomLayer } = leafer
|
|
16
|
+
const changeScale = leafer.getValidScale(e.scale)
|
|
17
|
+
if (changeScale !== 1) {
|
|
18
|
+
PointHelper.scaleOf(zoomLayer as IPointData, e, changeScale)
|
|
19
|
+
zoomLayer.scale = zoomLayer.__.scaleX * changeScale
|
|
20
|
+
}
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function addViewportConfig(leafer: ILeaferBase, mergeConfig?: ILeaferConfig): void {
|
|
26
|
+
if (mergeConfig) DataHelper.assign(leafer.config, mergeConfig)
|
|
27
|
+
DataHelper.assign(leafer.config, {
|
|
28
|
+
wheel: { preventDefault: true },
|
|
29
|
+
touch: { preventDefault: true },
|
|
30
|
+
pointer: { preventDefaultMenu: true }
|
|
31
|
+
} as ILeaferConfig, leafer.userConfig)
|
|
32
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ILeaferTypeList, ILeaferTypeFunction, ILeaferBase, ILeaferConfig, IKeepTouchData, IMultiTouchData, IWheelEvent, IWheelConfig, IPointData, IMoveEvent, IZoomEvent, IRotateEvent, ITimer } from '@leafer-ui/interface';
|
|
2
|
+
import { InteractionBase } from '@leafer-ui/core';
|
|
3
|
+
|
|
4
|
+
declare const LeaferTypeCreator: {
|
|
5
|
+
list: ILeaferTypeList;
|
|
6
|
+
register(name: string, fn: ILeaferTypeFunction): void;
|
|
7
|
+
run(name: string, leafer: ILeaferBase): void;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
declare function addViewport(leafer: ILeaferBase, mergeConfig?: ILeaferConfig, custom?: boolean): void;
|
|
11
|
+
declare function addViewportConfig(leafer: ILeaferBase, mergeConfig?: ILeaferConfig): void;
|
|
12
|
+
|
|
13
|
+
declare const MultiTouchHelper: {
|
|
14
|
+
getData(list: IKeepTouchData[]): IMultiTouchData;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
declare const WheelEventHelper: {
|
|
18
|
+
getMove(event: IWheelEvent, config: IWheelConfig): IPointData;
|
|
19
|
+
getScale(event: IWheelEvent, config: IWheelConfig): number;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
declare class Transformer {
|
|
23
|
+
get transforming(): boolean;
|
|
24
|
+
protected interaction: InteractionBase;
|
|
25
|
+
protected moveData: IMoveEvent;
|
|
26
|
+
protected zoomData: IZoomEvent;
|
|
27
|
+
protected rotateData: IRotateEvent;
|
|
28
|
+
protected transformTimer: ITimer;
|
|
29
|
+
constructor(interaction: InteractionBase);
|
|
30
|
+
move(data: IMoveEvent): void;
|
|
31
|
+
zoom(data: IZoomEvent): void;
|
|
32
|
+
rotate(data: IRotateEvent): void;
|
|
33
|
+
setPath(data: any): void;
|
|
34
|
+
protected transformEndWait(): void;
|
|
35
|
+
transformEnd(): void;
|
|
36
|
+
reset(): void;
|
|
37
|
+
destroy(): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { LeaferTypeCreator, MultiTouchHelper, Transformer, WheelEventHelper, addViewport, addViewportConfig };
|