@itwin/imodel-components-react 5.19.0 → 5.20.0
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/CHANGELOG.md +7 -0
- package/lib/imodel-components-react/UiIModelComponents.js +1 -1
- package/lib/imodel-components-react/UiIModelComponents.js.map +1 -1
- package/lib/imodel-components-react/color/AlphaSlider.js +100 -100
- package/lib/imodel-components-react/color/AlphaSlider.js.map +1 -1
- package/lib/imodel-components-react/editors/ColorEditor.js +20 -23
- package/lib/imodel-components-react/editors/ColorEditor.js.map +1 -1
- package/lib/imodel-components-react/editors/WeightEditor.js +21 -21
- package/lib/imodel-components-react/editors/WeightEditor.js.map +1 -1
- package/lib/imodel-components-react/lineweight/WeightPickerButton.js +53 -53
- package/lib/imodel-components-react/lineweight/WeightPickerButton.js.map +1 -1
- package/lib/imodel-components-react/navigationaids/Cube.js +1 -4
- package/lib/imodel-components-react/navigationaids/Cube.js.map +1 -1
- package/lib/imodel-components-react/navigationaids/CubeNavigationAid.js +296 -302
- package/lib/imodel-components-react/navigationaids/CubeNavigationAid.js.map +1 -1
- package/lib/imodel-components-react/navigationaids/DrawingNavigationAid.js +428 -425
- package/lib/imodel-components-react/navigationaids/DrawingNavigationAid.js.map +1 -1
- package/lib/imodel-components-react/timeline/BaseSolarDataProvider.js +20 -17
- package/lib/imodel-components-react/timeline/BaseSolarDataProvider.js.map +1 -1
- package/lib/imodel-components-react/timeline/BaseTimelineDataProvider.js +13 -10
- package/lib/imodel-components-react/timeline/BaseTimelineDataProvider.js.map +1 -1
- package/lib/imodel-components-react/timeline/InlineEdit.js +20 -20
- package/lib/imodel-components-react/timeline/InlineEdit.js.map +1 -1
- package/lib/imodel-components-react/timeline/SolarTimeline.js +144 -144
- package/lib/imodel-components-react/timeline/SolarTimeline.js.map +1 -1
- package/lib/imodel-components-react/viewport/ViewportComponentEvents.js +16 -15
- package/lib/imodel-components-react/viewport/ViewportComponentEvents.js.map +1 -1
- package/package.json +7 -7
|
@@ -104,195 +104,26 @@ export var CubeHover;
|
|
|
104
104
|
* @public
|
|
105
105
|
*/
|
|
106
106
|
export class CubeNavigationAid extends React.Component {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// Synchronize with rotation coming from the Viewport
|
|
128
|
-
this._handleViewRotationChangeEvent = (args) => {
|
|
129
|
-
const { animation, dragging, endRotMatrix } = this.state;
|
|
130
|
-
if (this.props.viewport === args.viewport && animation >= 1 && !dragging) {
|
|
131
|
-
const newMatrix = this.props.viewport.view.getRotation().clone();
|
|
132
|
-
if (!endRotMatrix.isAlmostEqual(newMatrix)) {
|
|
133
|
-
this.setState({
|
|
134
|
-
startRotMatrix: newMatrix,
|
|
135
|
-
endRotMatrix: newMatrix,
|
|
136
|
-
animation: 1,
|
|
137
|
-
face: Face.None,
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
this._animation = () => {
|
|
143
|
-
const t = Date.now();
|
|
144
|
-
const delta = this._lastTime ? t - this._lastTime : 16;
|
|
145
|
-
this._lastTime = t;
|
|
146
|
-
if (this.state.animation !== 1) {
|
|
147
|
-
const animation = Math.min(1, this.state.animation +
|
|
148
|
-
delta / (1000 * (this.props.animationTime || 0.4)));
|
|
149
|
-
if (this._mounted) {
|
|
150
|
-
this.setState({ animation }, () => {
|
|
151
|
-
this._animationFrame = setTimeout(this._animation, 16.667);
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
this._lastTime = undefined;
|
|
157
|
-
this._animationEnd();
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
this._animationEnd = () => {
|
|
161
|
-
ViewportComponentEvents.setCubeMatrix(this.state.endRotMatrix, this.state.face, true);
|
|
162
|
-
const startRotMatrix = this.state.endRotMatrix.clone();
|
|
163
|
-
if (this._mounted) {
|
|
164
|
-
this.setState({ startRotMatrix }, () => {
|
|
165
|
-
if (this.props.onAnimationEnd)
|
|
166
|
-
this.props.onAnimationEnd();
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
this._handleCellHoverChange = (vect, state) => {
|
|
171
|
-
if (this._isInteractionLocked()) {
|
|
172
|
-
this.props.onAnimationEnd?.();
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
const hoverMap = this.state.hoverMap;
|
|
176
|
-
hoverMap[`${vect.x}-${vect.y}-${vect.z}`] = state;
|
|
177
|
-
this.setState({ hoverMap });
|
|
178
|
-
};
|
|
179
|
-
this._isInteractionLocked = () => {
|
|
180
|
-
// Locked by markup
|
|
181
|
-
if (undefined !== this.props.viewport &&
|
|
182
|
-
this.props.viewport === IModelApp.toolAdmin.markupView) {
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
|
-
return false;
|
|
186
|
-
};
|
|
187
|
-
this._onArrowClick = (arrow) => {
|
|
188
|
-
if (this._isInteractionLocked()) {
|
|
189
|
-
this.props.onAnimationEnd?.();
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
const { newRotation, face } = this.getArrowRotationAndFace(arrow);
|
|
193
|
-
this._animateRotation(newRotation, face);
|
|
194
|
-
};
|
|
195
|
-
this._lastClientXY = Vector2d.createZero();
|
|
196
|
-
this._handleBoxMouseDown = (event) => {
|
|
197
|
-
if (this._isInteractionLocked()) {
|
|
198
|
-
this.props.onAnimationEnd?.();
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
event.preventDefault();
|
|
202
|
-
// only start listening after drag is confirmed. Ie. the 3D box is clicked.
|
|
203
|
-
window.addEventListener("mousemove", this._onMouseMove, false);
|
|
204
|
-
window.addEventListener("mouseup", this._onMouseUp, false);
|
|
205
|
-
this._lastClientXY = Vector2d.create(event.clientX, event.clientY);
|
|
206
|
-
this._start = this._lastClientXY;
|
|
207
|
-
};
|
|
208
|
-
this._onMouseMove = (event) => {
|
|
209
|
-
const mousePos = Vector2d.create(event.clientX, event.clientY);
|
|
210
|
-
this._processDrag(mousePos);
|
|
211
|
-
};
|
|
212
|
-
this._onMouseUp = () => {
|
|
213
|
-
if (this.state.dragging) {
|
|
214
|
-
this.setState({ dragging: false });
|
|
215
|
-
ViewportComponentEvents.setCubeMatrix(this.state.endRotMatrix, CubeNavigationAid._getMatrixFace(this.state.endRotMatrix), true);
|
|
216
|
-
}
|
|
217
|
-
// remove so event only triggers after this.onMouseStartDrag
|
|
218
|
-
window.removeEventListener("mousemove", this._onMouseMove);
|
|
219
|
-
window.removeEventListener("mouseup", this._onMouseUp);
|
|
220
|
-
};
|
|
221
|
-
this._handleBoxTouchStart = (event) => {
|
|
222
|
-
if (this._isInteractionLocked()) {
|
|
223
|
-
this.props.onAnimationEnd?.();
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
if (1 !== event.targetTouches.length)
|
|
227
|
-
return;
|
|
228
|
-
window.addEventListener("touchmove", this._onTouchMove, false);
|
|
229
|
-
window.addEventListener("touchend", this._onTouchEnd, false);
|
|
230
|
-
this._lastClientXY = Vector2d.create(event.targetTouches[0].clientX, event.targetTouches[0].clientY);
|
|
231
|
-
this._start = this._lastClientXY;
|
|
232
|
-
};
|
|
233
|
-
this._onTouchMove = (event) => {
|
|
234
|
-
if (1 !== event.targetTouches.length)
|
|
235
|
-
return;
|
|
236
|
-
const mousePos = Vector2d.create(event.targetTouches[0].clientX, event.targetTouches[0].clientY);
|
|
237
|
-
this._processDrag(mousePos);
|
|
238
|
-
};
|
|
239
|
-
this._onTouchEnd = (event) => {
|
|
240
|
-
if (0 !== event.targetTouches.length)
|
|
241
|
-
return;
|
|
242
|
-
if (this.state.dragging) {
|
|
243
|
-
this.setState({ dragging: false });
|
|
244
|
-
ViewportComponentEvents.setCubeMatrix(this.state.endRotMatrix, CubeNavigationAid._getMatrixFace(this.state.endRotMatrix), true);
|
|
245
|
-
}
|
|
246
|
-
window.removeEventListener("touchmove", this._onTouchMove);
|
|
247
|
-
window.removeEventListener("touchend", this._onTouchEnd);
|
|
248
|
-
};
|
|
249
|
-
this._handleFaceCellClick = (pos, face) => {
|
|
250
|
-
if (this._isInteractionLocked()) {
|
|
251
|
-
this.props.onAnimationEnd?.();
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
const { endRotMatrix } = this.state;
|
|
255
|
-
let rotMatrix = Matrix3d.createRigidViewAxesZTowardsEye(pos.x, pos.y, pos.z).inverse();
|
|
256
|
-
if (rotMatrix) {
|
|
257
|
-
// if isMatrixFace and user is clicking on top/bottom, the current matrix face must be top or bottom
|
|
258
|
-
if (!CubeNavigationAid._isMatrixFace(endRotMatrix) &&
|
|
259
|
-
(face === Face.Top || face === Face.Bottom)) {
|
|
260
|
-
const angleAxis = endRotMatrix.getAxisAndAngleOfRotation();
|
|
261
|
-
if (angleAxis.ok) {
|
|
262
|
-
const xAx = endRotMatrix.columnX();
|
|
263
|
-
const a = Math.atan2(xAx.y, xAx.x);
|
|
264
|
-
const r = (Math.round((a * 2) / Math.PI) * Math.PI) / 2; // round to quarter turn intervals
|
|
265
|
-
const rot = Matrix3d.createRotationAroundAxisIndex(AxisIndex.Z, Angle.createRadians(r));
|
|
266
|
-
rotMatrix = rot.multiplyMatrixMatrix(rotMatrix);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
this._animateRotation(rotMatrix, face);
|
|
270
|
-
}
|
|
271
|
-
window.removeEventListener("mousemove", this._onMouseMove);
|
|
272
|
-
};
|
|
273
|
-
this._animateRotation = (endRotMatrix, face) => {
|
|
274
|
-
if (this.state.endRotMatrix.isAlmostEqual(endRotMatrix))
|
|
275
|
-
return;
|
|
276
|
-
// set animation variables, let css transitions animate it.
|
|
277
|
-
this._animationFrame = setTimeout(this._animation, 16.667);
|
|
278
|
-
this.setState((prevState) => ({
|
|
279
|
-
startRotMatrix: prevState.endRotMatrix,
|
|
280
|
-
endRotMatrix,
|
|
281
|
-
animation: 0,
|
|
282
|
-
face,
|
|
283
|
-
}));
|
|
284
|
-
};
|
|
285
|
-
this._setRotation = (endRotMatrix, face) => {
|
|
286
|
-
ViewportComponentEvents.setCubeMatrix(endRotMatrix, face);
|
|
287
|
-
// set variables, with animTime at 0 to prevent animation.
|
|
288
|
-
this.setState({
|
|
289
|
-
startRotMatrix: endRotMatrix,
|
|
290
|
-
endRotMatrix,
|
|
291
|
-
animation: 1,
|
|
292
|
-
face,
|
|
293
|
-
});
|
|
294
|
-
};
|
|
295
|
-
}
|
|
107
|
+
_start = Vector2d.createZero();
|
|
108
|
+
state = {
|
|
109
|
+
dragging: false,
|
|
110
|
+
startRotMatrix: Matrix3d.createIdentity(),
|
|
111
|
+
endRotMatrix: Matrix3d.createIdentity(),
|
|
112
|
+
animation: 1,
|
|
113
|
+
hoverMap: {},
|
|
114
|
+
face: Face.Top,
|
|
115
|
+
};
|
|
116
|
+
_lastTime;
|
|
117
|
+
_animationFrame;
|
|
118
|
+
_mounted = false;
|
|
119
|
+
_labels = {
|
|
120
|
+
[Face.Right]: UiIModelComponents.translate("cube.right"),
|
|
121
|
+
[Face.Left]: UiIModelComponents.translate("cube.left"),
|
|
122
|
+
[Face.Back]: UiIModelComponents.translate("cube.back"),
|
|
123
|
+
[Face.Front]: UiIModelComponents.translate("cube.front"),
|
|
124
|
+
[Face.Top]: UiIModelComponents.translate("cube.top"),
|
|
125
|
+
[Face.Bottom]: UiIModelComponents.translate("cube.bottom"),
|
|
126
|
+
};
|
|
296
127
|
componentDidMount() {
|
|
297
128
|
this._mounted = true;
|
|
298
129
|
ViewportComponentEvents.onViewRotationChangeEvent.addListener(this._handleViewRotationChangeEvent);
|
|
@@ -311,6 +142,60 @@ export class CubeNavigationAid extends React.Component {
|
|
|
311
142
|
clearTimeout(this._animationFrame);
|
|
312
143
|
this._mounted = false;
|
|
313
144
|
}
|
|
145
|
+
// Synchronize with rotation coming from the Viewport
|
|
146
|
+
_handleViewRotationChangeEvent = (args) => {
|
|
147
|
+
const { animation, dragging, endRotMatrix } = this.state;
|
|
148
|
+
if (this.props.viewport === args.viewport && animation >= 1 && !dragging) {
|
|
149
|
+
const newMatrix = this.props.viewport.view.getRotation().clone();
|
|
150
|
+
if (!endRotMatrix.isAlmostEqual(newMatrix)) {
|
|
151
|
+
this.setState({
|
|
152
|
+
startRotMatrix: newMatrix,
|
|
153
|
+
endRotMatrix: newMatrix,
|
|
154
|
+
animation: 1,
|
|
155
|
+
face: Face.None,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
_animation = () => {
|
|
161
|
+
const t = Date.now();
|
|
162
|
+
const delta = this._lastTime ? t - this._lastTime : 16;
|
|
163
|
+
this._lastTime = t;
|
|
164
|
+
if (this.state.animation !== 1) {
|
|
165
|
+
const animation = Math.min(1, this.state.animation +
|
|
166
|
+
delta / (1000 * (this.props.animationTime || 0.4)));
|
|
167
|
+
if (this._mounted) {
|
|
168
|
+
this.setState({ animation }, () => {
|
|
169
|
+
this._animationFrame = setTimeout(this._animation, 16.667);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
this._lastTime = undefined;
|
|
175
|
+
this._animationEnd();
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
_animationEnd = () => {
|
|
179
|
+
ViewportComponentEvents.setCubeMatrix(this.state.endRotMatrix, this.state.face, true);
|
|
180
|
+
const startRotMatrix = this.state.endRotMatrix.clone();
|
|
181
|
+
if (this._mounted) {
|
|
182
|
+
this.setState({ startRotMatrix }, () => {
|
|
183
|
+
if (this.props.onAnimationEnd)
|
|
184
|
+
this.props.onAnimationEnd();
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
static _animationFn = (t) => t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t;
|
|
189
|
+
static _isMatrixFace = (matrix) => {
|
|
190
|
+
let sum = 0;
|
|
191
|
+
for (const coff of matrix.coffs) {
|
|
192
|
+
if (Geometry.isAlmostEqualNumber(Math.abs(coff), 1))
|
|
193
|
+
sum++;
|
|
194
|
+
}
|
|
195
|
+
// Assuming matrix is a proper rotation matrix:
|
|
196
|
+
// if matrix viewing a face, there will be a total of 3 values either almost -1, or almost 1.
|
|
197
|
+
return sum === 3;
|
|
198
|
+
};
|
|
314
199
|
render() {
|
|
315
200
|
const { animation, startRotMatrix, endRotMatrix } = this.state;
|
|
316
201
|
const visible = CubeNavigationAid._isMatrixFace(endRotMatrix) && animation === 1.0;
|
|
@@ -338,6 +223,73 @@ export class CubeNavigationAid extends React.Component {
|
|
|
338
223
|
React.createElement(PointerButton, { "data-testid": "cube-pointer-button-left", visible: visible, pointerType: Pointer.Left, onArrowClick: this._onArrowClick, title: leftTitle }),
|
|
339
224
|
React.createElement(PointerButton, { "data-testid": "cube-pointer-button-right", visible: visible, pointerType: Pointer.Right, onArrowClick: this._onArrowClick, title: rightTitle })));
|
|
340
225
|
}
|
|
226
|
+
_handleCellHoverChange = (vect, state) => {
|
|
227
|
+
if (this._isInteractionLocked()) {
|
|
228
|
+
this.props.onAnimationEnd?.();
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const hoverMap = this.state.hoverMap;
|
|
232
|
+
hoverMap[`${vect.x}-${vect.y}-${vect.z}`] = state;
|
|
233
|
+
this.setState({ hoverMap });
|
|
234
|
+
};
|
|
235
|
+
_isInteractionLocked = () => {
|
|
236
|
+
// Locked by markup
|
|
237
|
+
if (undefined !== this.props.viewport &&
|
|
238
|
+
this.props.viewport === IModelApp.toolAdmin.markupView) {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
return false;
|
|
242
|
+
};
|
|
243
|
+
static _getMatrixFace = (rotMatrix) => {
|
|
244
|
+
if (!CubeNavigationAid._isMatrixFace(rotMatrix)) {
|
|
245
|
+
return Face.None;
|
|
246
|
+
}
|
|
247
|
+
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Top].coffs[6] &&
|
|
248
|
+
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Top].coffs[7] &&
|
|
249
|
+
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Top].coffs[8])
|
|
250
|
+
return Face.Top;
|
|
251
|
+
if (rotMatrix.coffs[6] ===
|
|
252
|
+
cubeNavigationFaceRotations[Face.Bottom].coffs[6] &&
|
|
253
|
+
rotMatrix.coffs[7] ===
|
|
254
|
+
cubeNavigationFaceRotations[Face.Bottom].coffs[7] &&
|
|
255
|
+
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Bottom].coffs[8])
|
|
256
|
+
return Face.Bottom;
|
|
257
|
+
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Left].coffs[6] &&
|
|
258
|
+
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Left].coffs[7] &&
|
|
259
|
+
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Left].coffs[8])
|
|
260
|
+
return Face.Left;
|
|
261
|
+
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Right].coffs[6] &&
|
|
262
|
+
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Right].coffs[7] &&
|
|
263
|
+
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Right].coffs[8])
|
|
264
|
+
return Face.Right;
|
|
265
|
+
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Back].coffs[6] &&
|
|
266
|
+
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Back].coffs[7] &&
|
|
267
|
+
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Back].coffs[8])
|
|
268
|
+
return Face.Back;
|
|
269
|
+
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Front].coffs[6] &&
|
|
270
|
+
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Front].coffs[7] &&
|
|
271
|
+
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Front].coffs[8])
|
|
272
|
+
return Face.Front;
|
|
273
|
+
return Face.None;
|
|
274
|
+
};
|
|
275
|
+
static _interpolateRotMatrix = (start, anim, end) => {
|
|
276
|
+
if (anim === 0)
|
|
277
|
+
return start;
|
|
278
|
+
if (anim === 1 || start.isAlmostEqual(end))
|
|
279
|
+
return end;
|
|
280
|
+
const startInverse = start.transpose();
|
|
281
|
+
const diff = end.multiplyMatrixMatrix(startInverse);
|
|
282
|
+
const angleAxis = diff.getAxisAndAngleOfRotation();
|
|
283
|
+
if (angleAxis.ok) {
|
|
284
|
+
const angle = Angle.createRadians(angleAxis.angle.radians * CubeNavigationAid._animationFn(anim));
|
|
285
|
+
const newDiff = Matrix3d.createRotationAroundVector(angleAxis.axis, angle);
|
|
286
|
+
if (newDiff) {
|
|
287
|
+
const newMatrix = newDiff.multiplyMatrixMatrix(start);
|
|
288
|
+
return newMatrix;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
return end;
|
|
292
|
+
};
|
|
341
293
|
static correctSmallNumber(value, tolerance) {
|
|
342
294
|
return Math.abs(value) < tolerance ? 0 : value;
|
|
343
295
|
}
|
|
@@ -416,10 +368,19 @@ export class CubeNavigationAid extends React.Component {
|
|
|
416
368
|
const face = CubeNavigationAid._getMatrixFace(newRotation);
|
|
417
369
|
return { newRotation, face };
|
|
418
370
|
}
|
|
371
|
+
_onArrowClick = (arrow) => {
|
|
372
|
+
if (this._isInteractionLocked()) {
|
|
373
|
+
this.props.onAnimationEnd?.();
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const { newRotation, face } = this.getArrowRotationAndFace(arrow);
|
|
377
|
+
this._animateRotation(newRotation, face);
|
|
378
|
+
};
|
|
419
379
|
getArrowTitle(arrow) {
|
|
420
380
|
const { face } = this.getArrowRotationAndFace(arrow);
|
|
421
381
|
return this._labels[face];
|
|
422
382
|
}
|
|
383
|
+
_lastClientXY = Vector2d.createZero();
|
|
423
384
|
_processDrag(mousePos) {
|
|
424
385
|
if (!this._start.isAlmostEqual(mousePos)) {
|
|
425
386
|
const movement = mousePos.minus(this._lastClientXY);
|
|
@@ -437,68 +398,106 @@ export class CubeNavigationAid extends React.Component {
|
|
|
437
398
|
}
|
|
438
399
|
this._lastClientXY = mousePos;
|
|
439
400
|
}
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
for (const coff of matrix.coffs) {
|
|
445
|
-
if (Geometry.isAlmostEqualNumber(Math.abs(coff), 1))
|
|
446
|
-
sum++;
|
|
447
|
-
}
|
|
448
|
-
// Assuming matrix is a proper rotation matrix:
|
|
449
|
-
// if matrix viewing a face, there will be a total of 3 values either almost -1, or almost 1.
|
|
450
|
-
return sum === 3;
|
|
451
|
-
};
|
|
452
|
-
CubeNavigationAid._getMatrixFace = (rotMatrix) => {
|
|
453
|
-
if (!CubeNavigationAid._isMatrixFace(rotMatrix)) {
|
|
454
|
-
return Face.None;
|
|
455
|
-
}
|
|
456
|
-
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Top].coffs[6] &&
|
|
457
|
-
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Top].coffs[7] &&
|
|
458
|
-
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Top].coffs[8])
|
|
459
|
-
return Face.Top;
|
|
460
|
-
if (rotMatrix.coffs[6] ===
|
|
461
|
-
cubeNavigationFaceRotations[Face.Bottom].coffs[6] &&
|
|
462
|
-
rotMatrix.coffs[7] ===
|
|
463
|
-
cubeNavigationFaceRotations[Face.Bottom].coffs[7] &&
|
|
464
|
-
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Bottom].coffs[8])
|
|
465
|
-
return Face.Bottom;
|
|
466
|
-
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Left].coffs[6] &&
|
|
467
|
-
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Left].coffs[7] &&
|
|
468
|
-
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Left].coffs[8])
|
|
469
|
-
return Face.Left;
|
|
470
|
-
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Right].coffs[6] &&
|
|
471
|
-
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Right].coffs[7] &&
|
|
472
|
-
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Right].coffs[8])
|
|
473
|
-
return Face.Right;
|
|
474
|
-
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Back].coffs[6] &&
|
|
475
|
-
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Back].coffs[7] &&
|
|
476
|
-
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Back].coffs[8])
|
|
477
|
-
return Face.Back;
|
|
478
|
-
if (rotMatrix.coffs[6] === cubeNavigationFaceRotations[Face.Front].coffs[6] &&
|
|
479
|
-
rotMatrix.coffs[7] === cubeNavigationFaceRotations[Face.Front].coffs[7] &&
|
|
480
|
-
rotMatrix.coffs[8] === cubeNavigationFaceRotations[Face.Front].coffs[8])
|
|
481
|
-
return Face.Front;
|
|
482
|
-
return Face.None;
|
|
483
|
-
};
|
|
484
|
-
CubeNavigationAid._interpolateRotMatrix = (start, anim, end) => {
|
|
485
|
-
if (anim === 0)
|
|
486
|
-
return start;
|
|
487
|
-
if (anim === 1 || start.isAlmostEqual(end))
|
|
488
|
-
return end;
|
|
489
|
-
const startInverse = start.transpose();
|
|
490
|
-
const diff = end.multiplyMatrixMatrix(startInverse);
|
|
491
|
-
const angleAxis = diff.getAxisAndAngleOfRotation();
|
|
492
|
-
if (angleAxis.ok) {
|
|
493
|
-
const angle = Angle.createRadians(angleAxis.angle.radians * CubeNavigationAid._animationFn(anim));
|
|
494
|
-
const newDiff = Matrix3d.createRotationAroundVector(angleAxis.axis, angle);
|
|
495
|
-
if (newDiff) {
|
|
496
|
-
const newMatrix = newDiff.multiplyMatrixMatrix(start);
|
|
497
|
-
return newMatrix;
|
|
401
|
+
_handleBoxMouseDown = (event) => {
|
|
402
|
+
if (this._isInteractionLocked()) {
|
|
403
|
+
this.props.onAnimationEnd?.();
|
|
404
|
+
return;
|
|
498
405
|
}
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
406
|
+
event.preventDefault();
|
|
407
|
+
// only start listening after drag is confirmed. Ie. the 3D box is clicked.
|
|
408
|
+
window.addEventListener("mousemove", this._onMouseMove, false);
|
|
409
|
+
window.addEventListener("mouseup", this._onMouseUp, false);
|
|
410
|
+
this._lastClientXY = Vector2d.create(event.clientX, event.clientY);
|
|
411
|
+
this._start = this._lastClientXY;
|
|
412
|
+
};
|
|
413
|
+
_onMouseMove = (event) => {
|
|
414
|
+
const mousePos = Vector2d.create(event.clientX, event.clientY);
|
|
415
|
+
this._processDrag(mousePos);
|
|
416
|
+
};
|
|
417
|
+
_onMouseUp = () => {
|
|
418
|
+
if (this.state.dragging) {
|
|
419
|
+
this.setState({ dragging: false });
|
|
420
|
+
ViewportComponentEvents.setCubeMatrix(this.state.endRotMatrix, CubeNavigationAid._getMatrixFace(this.state.endRotMatrix), true);
|
|
421
|
+
}
|
|
422
|
+
// remove so event only triggers after this.onMouseStartDrag
|
|
423
|
+
window.removeEventListener("mousemove", this._onMouseMove);
|
|
424
|
+
window.removeEventListener("mouseup", this._onMouseUp);
|
|
425
|
+
};
|
|
426
|
+
_handleBoxTouchStart = (event) => {
|
|
427
|
+
if (this._isInteractionLocked()) {
|
|
428
|
+
this.props.onAnimationEnd?.();
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
if (1 !== event.targetTouches.length)
|
|
432
|
+
return;
|
|
433
|
+
window.addEventListener("touchmove", this._onTouchMove, false);
|
|
434
|
+
window.addEventListener("touchend", this._onTouchEnd, false);
|
|
435
|
+
this._lastClientXY = Vector2d.create(event.targetTouches[0].clientX, event.targetTouches[0].clientY);
|
|
436
|
+
this._start = this._lastClientXY;
|
|
437
|
+
};
|
|
438
|
+
_onTouchMove = (event) => {
|
|
439
|
+
if (1 !== event.targetTouches.length)
|
|
440
|
+
return;
|
|
441
|
+
const mousePos = Vector2d.create(event.targetTouches[0].clientX, event.targetTouches[0].clientY);
|
|
442
|
+
this._processDrag(mousePos);
|
|
443
|
+
};
|
|
444
|
+
_onTouchEnd = (event) => {
|
|
445
|
+
if (0 !== event.targetTouches.length)
|
|
446
|
+
return;
|
|
447
|
+
if (this.state.dragging) {
|
|
448
|
+
this.setState({ dragging: false });
|
|
449
|
+
ViewportComponentEvents.setCubeMatrix(this.state.endRotMatrix, CubeNavigationAid._getMatrixFace(this.state.endRotMatrix), true);
|
|
450
|
+
}
|
|
451
|
+
window.removeEventListener("touchmove", this._onTouchMove);
|
|
452
|
+
window.removeEventListener("touchend", this._onTouchEnd);
|
|
453
|
+
};
|
|
454
|
+
_handleFaceCellClick = (pos, face) => {
|
|
455
|
+
if (this._isInteractionLocked()) {
|
|
456
|
+
this.props.onAnimationEnd?.();
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const { endRotMatrix } = this.state;
|
|
460
|
+
let rotMatrix = Matrix3d.createRigidViewAxesZTowardsEye(pos.x, pos.y, pos.z).inverse();
|
|
461
|
+
if (rotMatrix) {
|
|
462
|
+
// if isMatrixFace and user is clicking on top/bottom, the current matrix face must be top or bottom
|
|
463
|
+
if (!CubeNavigationAid._isMatrixFace(endRotMatrix) &&
|
|
464
|
+
(face === Face.Top || face === Face.Bottom)) {
|
|
465
|
+
const angleAxis = endRotMatrix.getAxisAndAngleOfRotation();
|
|
466
|
+
if (angleAxis.ok) {
|
|
467
|
+
const xAx = endRotMatrix.columnX();
|
|
468
|
+
const a = Math.atan2(xAx.y, xAx.x);
|
|
469
|
+
const r = (Math.round((a * 2) / Math.PI) * Math.PI) / 2; // round to quarter turn intervals
|
|
470
|
+
const rot = Matrix3d.createRotationAroundAxisIndex(AxisIndex.Z, Angle.createRadians(r));
|
|
471
|
+
rotMatrix = rot.multiplyMatrixMatrix(rotMatrix);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
this._animateRotation(rotMatrix, face);
|
|
475
|
+
}
|
|
476
|
+
window.removeEventListener("mousemove", this._onMouseMove);
|
|
477
|
+
};
|
|
478
|
+
_animateRotation = (endRotMatrix, face) => {
|
|
479
|
+
if (this.state.endRotMatrix.isAlmostEqual(endRotMatrix))
|
|
480
|
+
return;
|
|
481
|
+
// set animation variables, let css transitions animate it.
|
|
482
|
+
this._animationFrame = setTimeout(this._animation, 16.667);
|
|
483
|
+
this.setState((prevState) => ({
|
|
484
|
+
startRotMatrix: prevState.endRotMatrix,
|
|
485
|
+
endRotMatrix,
|
|
486
|
+
animation: 0,
|
|
487
|
+
face,
|
|
488
|
+
}));
|
|
489
|
+
};
|
|
490
|
+
_setRotation = (endRotMatrix, face) => {
|
|
491
|
+
ViewportComponentEvents.setCubeMatrix(endRotMatrix, face);
|
|
492
|
+
// set variables, with animTime at 0 to prevent animation.
|
|
493
|
+
this.setState({
|
|
494
|
+
startRotMatrix: endRotMatrix,
|
|
495
|
+
endRotMatrix,
|
|
496
|
+
animation: 1,
|
|
497
|
+
face,
|
|
498
|
+
});
|
|
499
|
+
};
|
|
500
|
+
}
|
|
502
501
|
/** @internal */
|
|
503
502
|
export class NavCubeFace extends React.Component {
|
|
504
503
|
includeCell(vector) {
|
|
@@ -524,20 +523,20 @@ export class NavCubeFace extends React.Component {
|
|
|
524
523
|
})));
|
|
525
524
|
})));
|
|
526
525
|
}
|
|
526
|
+
static faceCellToPos = (face, x, y) => {
|
|
527
|
+
const faceVect = cubeNavigationFaceLocs[face];
|
|
528
|
+
const route = cubeNavigationRoutes[face];
|
|
529
|
+
const faceX = x < 0 ? route.left : x > 0 ? route.right : Face.None;
|
|
530
|
+
const xVect = faceX !== Face.None
|
|
531
|
+
? cubeNavigationFaceLocs[faceX]
|
|
532
|
+
: Vector3d.createZero();
|
|
533
|
+
const faceY = y < 0 ? route.up : y > 0 ? route.down : Face.None;
|
|
534
|
+
const yVect = faceY !== Face.None
|
|
535
|
+
? cubeNavigationFaceLocs[faceY]
|
|
536
|
+
: Vector3d.createZero();
|
|
537
|
+
return faceVect.plus(xVect).plus(yVect);
|
|
538
|
+
};
|
|
527
539
|
}
|
|
528
|
-
NavCubeFace.faceCellToPos = (face, x, y) => {
|
|
529
|
-
const faceVect = cubeNavigationFaceLocs[face];
|
|
530
|
-
const route = cubeNavigationRoutes[face];
|
|
531
|
-
const faceX = x < 0 ? route.left : x > 0 ? route.right : Face.None;
|
|
532
|
-
const xVect = faceX !== Face.None
|
|
533
|
-
? cubeNavigationFaceLocs[faceX]
|
|
534
|
-
: Vector3d.createZero();
|
|
535
|
-
const faceY = y < 0 ? route.up : y > 0 ? route.down : Face.None;
|
|
536
|
-
const yVect = faceY !== Face.None
|
|
537
|
-
? cubeNavigationFaceLocs[faceY]
|
|
538
|
-
: Vector3d.createZero();
|
|
539
|
-
return faceVect.plus(xVect).plus(yVect);
|
|
540
|
-
};
|
|
541
540
|
class FaceRow extends React.Component {
|
|
542
541
|
render() {
|
|
543
542
|
const { center, children, ...props } = this.props;
|
|
@@ -547,37 +546,7 @@ class FaceRow extends React.Component {
|
|
|
547
546
|
}
|
|
548
547
|
/** @internal */
|
|
549
548
|
export class FaceCell extends React.Component {
|
|
550
|
-
|
|
551
|
-
super(...arguments);
|
|
552
|
-
this._handleMouseOver = () => {
|
|
553
|
-
const { vector } = this.props;
|
|
554
|
-
this.props.onFaceCellHoverChange &&
|
|
555
|
-
this.props.onFaceCellHoverChange(vector, CubeHover.Hover);
|
|
556
|
-
};
|
|
557
|
-
this._handleMouseOut = () => {
|
|
558
|
-
const { vector } = this.props;
|
|
559
|
-
this.props.onFaceCellHoverChange &&
|
|
560
|
-
this.props.onFaceCellHoverChange(vector, CubeHover.None);
|
|
561
|
-
};
|
|
562
|
-
this._handleMouseDown = (event) => {
|
|
563
|
-
const { clientX, clientY } = event;
|
|
564
|
-
this.handlePointerDown(clientX, clientY);
|
|
565
|
-
};
|
|
566
|
-
this._handleMouseUp = (event) => {
|
|
567
|
-
const { clientX, clientY } = event;
|
|
568
|
-
this.handlePointerUp(clientX, clientY);
|
|
569
|
-
};
|
|
570
|
-
this._handleTouchStart = (event) => {
|
|
571
|
-
event.preventDefault();
|
|
572
|
-
event.targetTouches.length === 1 &&
|
|
573
|
-
this.handlePointerDown(event.targetTouches[0].clientX, event.targetTouches[0].clientY);
|
|
574
|
-
};
|
|
575
|
-
this._handleTouchEnd = (event) => {
|
|
576
|
-
event.preventDefault();
|
|
577
|
-
event.changedTouches.length === 1 &&
|
|
578
|
-
this.handlePointerUp(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
|
|
579
|
-
};
|
|
580
|
-
}
|
|
549
|
+
_startMouse;
|
|
581
550
|
render() {
|
|
582
551
|
const { center, children, onFaceCellClick, onFaceCellHoverChange, hoverMap, face, vector, ...props } = this.props;
|
|
583
552
|
const { x, y, z } = vector;
|
|
@@ -591,6 +560,34 @@ export class FaceCell extends React.Component {
|
|
|
591
560
|
// eslint-disable-next-line jsx-a11y/mouse-events-have-key-events
|
|
592
561
|
onMouseOut: this._handleMouseOut, onTouchStart: this._handleTouchStart, onTouchEnd: this._handleTouchEnd, "data-testid": `nav-cube-face-cell-${face}-${n}`, className: classNames, role: "presentation", ...props }, children));
|
|
593
562
|
}
|
|
563
|
+
_handleMouseOver = () => {
|
|
564
|
+
const { vector } = this.props;
|
|
565
|
+
this.props.onFaceCellHoverChange &&
|
|
566
|
+
this.props.onFaceCellHoverChange(vector, CubeHover.Hover);
|
|
567
|
+
};
|
|
568
|
+
_handleMouseOut = () => {
|
|
569
|
+
const { vector } = this.props;
|
|
570
|
+
this.props.onFaceCellHoverChange &&
|
|
571
|
+
this.props.onFaceCellHoverChange(vector, CubeHover.None);
|
|
572
|
+
};
|
|
573
|
+
_handleMouseDown = (event) => {
|
|
574
|
+
const { clientX, clientY } = event;
|
|
575
|
+
this.handlePointerDown(clientX, clientY);
|
|
576
|
+
};
|
|
577
|
+
_handleMouseUp = (event) => {
|
|
578
|
+
const { clientX, clientY } = event;
|
|
579
|
+
this.handlePointerUp(clientX, clientY);
|
|
580
|
+
};
|
|
581
|
+
_handleTouchStart = (event) => {
|
|
582
|
+
event.preventDefault();
|
|
583
|
+
event.targetTouches.length === 1 &&
|
|
584
|
+
this.handlePointerDown(event.targetTouches[0].clientX, event.targetTouches[0].clientY);
|
|
585
|
+
};
|
|
586
|
+
_handleTouchEnd = (event) => {
|
|
587
|
+
event.preventDefault();
|
|
588
|
+
event.changedTouches.length === 1 &&
|
|
589
|
+
this.handlePointerUp(event.changedTouches[0].clientX, event.changedTouches[0].clientY);
|
|
590
|
+
};
|
|
594
591
|
handlePointerDown(x, y) {
|
|
595
592
|
const { vector } = this.props;
|
|
596
593
|
this._startMouse = Point2d.create(x, y);
|
|
@@ -631,14 +628,6 @@ const pointerClass = {
|
|
|
631
628
|
[Pointer.Right]: "cube-right",
|
|
632
629
|
};
|
|
633
630
|
class PointerButton extends React.Component {
|
|
634
|
-
constructor() {
|
|
635
|
-
super(...arguments);
|
|
636
|
-
this._handleClick = (event) => {
|
|
637
|
-
const { pointerType } = this.props;
|
|
638
|
-
event.preventDefault();
|
|
639
|
-
this.props.onArrowClick(pointerType);
|
|
640
|
-
};
|
|
641
|
-
}
|
|
642
631
|
render() {
|
|
643
632
|
const { visible, pointerType, onArrowClick, title, ...props } = this.props;
|
|
644
633
|
const classes = classnames("cube-pointer", "icon", pointerClass[pointerType], visible && "cube-visible");
|
|
@@ -647,5 +636,10 @@ class PointerButton extends React.Component {
|
|
|
647
636
|
React.createElement("div", { className: classes, role: "button", tabIndex: -1, title: title, ...props, onClick: this._handleClick },
|
|
648
637
|
React.createElement(Icon, { iconSpec: pointerIconSpec[pointerType] })));
|
|
649
638
|
}
|
|
639
|
+
_handleClick = (event) => {
|
|
640
|
+
const { pointerType } = this.props;
|
|
641
|
+
event.preventDefault();
|
|
642
|
+
this.props.onArrowClick(pointerType);
|
|
643
|
+
};
|
|
650
644
|
}
|
|
651
645
|
//# sourceMappingURL=CubeNavigationAid.js.map
|