-
-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathrotatable.js
96 lines (83 loc) · 2.84 KB
/
rotatable.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import Component from "@pencil.js/component";
import MouseEvent from "@pencil.js/mouse-event";
/**
* @module Rotatable
*/
/**
* @typedef {Object} RotatableAPI
* @prop {Function} stop - Stop the component from being rotatable
*/
/**
* Set this component rotatable (use drag and drop interaction to rotate)
* @return {RotatableAPI}
* @memberOf module:Component#
*/
Component.prototype.rotatable = function rotatable () {
if (this.isDraggable) {
throw new Error("Component can't be both draggable and rotatable.");
}
const cursorNotSet = this.options.cursor === Component.cursors.default;
if (cursorNotSet) {
this.options.cursor = Component.cursors.grab;
}
this.isRotatable = true;
this.isRotated = false;
let previousAngle = null;
let startingAngle = null;
const downHandler = ({ position }) => {
if (cursorNotSet) {
this.options.cursor = Component.cursors.grabbing;
}
previousAngle = this.options.rotation;
startingAngle = position.subtract(this.getAbsolutePosition()).angle;
this.isRotated = true;
this.fire(new MouseEvent(MouseEvent.events.grab, this, position));
};
this.on(MouseEvent.events.down, downHandler);
const moveHandler = ({ position }) => {
if (previousAngle !== null) {
const absolutePosition = this.getAbsolutePosition();
this.options.rotation = previousAngle + position.subtract(absolutePosition).angle - startingAngle;
this.fire(new MouseEvent(MouseEvent.events.rotate, this, position));
}
};
const upHandler = ({ position }) => {
if (cursorNotSet) {
this.options.cursor = Component.cursors.grab;
}
if (previousAngle !== null && this.isRotated) {
previousAngle = null;
startingAngle = null;
this.isRotated = false;
this.fire(new MouseEvent(MouseEvent.events.drop, this, position));
}
};
let scene;
this.getScene().then((theScene) => {
if (this.isRotatable) {
scene = theScene;
scene
.on(MouseEvent.events.move, moveHandler)
.on(MouseEvent.events.up, upHandler);
}
});
return {
/**
* Stop the component from being rotatable
* @memberOf RotatableAPI#
*/
stop: () => {
this.removeListener(MouseEvent.events.down, downHandler, true);
if (scene) {
scene
.removeListener(MouseEvent.events.move, moveHandler)
.removeListener(MouseEvent.events.up, upHandler);
}
if (cursorNotSet) {
this.options.cursor = Component.cursors.default;
}
this.isRotatable = false;
this.isRotated = false;
},
};
};