@itwin/imodel-components-react 5.19.0 → 5.21.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/lib/imodel-components-react/UiIModelComponents.js +1 -1
  3. package/lib/imodel-components-react/UiIModelComponents.js.map +1 -1
  4. package/lib/imodel-components-react/color/AlphaSlider.js +100 -100
  5. package/lib/imodel-components-react/color/AlphaSlider.js.map +1 -1
  6. package/lib/imodel-components-react/editors/ColorEditor.js +20 -23
  7. package/lib/imodel-components-react/editors/ColorEditor.js.map +1 -1
  8. package/lib/imodel-components-react/editors/WeightEditor.js +21 -21
  9. package/lib/imodel-components-react/editors/WeightEditor.js.map +1 -1
  10. package/lib/imodel-components-react/inputs/new-editors/QuantityEditor.js +3 -2
  11. package/lib/imodel-components-react/inputs/new-editors/QuantityEditor.js.map +1 -1
  12. package/lib/imodel-components-react/inputs/new-editors/UseQuantityInfo.d.ts +2 -1
  13. package/lib/imodel-components-react/inputs/new-editors/UseQuantityInfo.d.ts.map +1 -1
  14. package/lib/imodel-components-react/inputs/new-editors/UseQuantityInfo.js +31 -11
  15. package/lib/imodel-components-react/inputs/new-editors/UseQuantityInfo.js.map +1 -1
  16. package/lib/imodel-components-react/lineweight/WeightPickerButton.js +53 -53
  17. package/lib/imodel-components-react/lineweight/WeightPickerButton.js.map +1 -1
  18. package/lib/imodel-components-react/navigationaids/Cube.js +1 -4
  19. package/lib/imodel-components-react/navigationaids/Cube.js.map +1 -1
  20. package/lib/imodel-components-react/navigationaids/CubeNavigationAid.js +296 -302
  21. package/lib/imodel-components-react/navigationaids/CubeNavigationAid.js.map +1 -1
  22. package/lib/imodel-components-react/navigationaids/DrawingNavigationAid.js +428 -425
  23. package/lib/imodel-components-react/navigationaids/DrawingNavigationAid.js.map +1 -1
  24. package/lib/imodel-components-react/timeline/BaseSolarDataProvider.js +20 -17
  25. package/lib/imodel-components-react/timeline/BaseSolarDataProvider.js.map +1 -1
  26. package/lib/imodel-components-react/timeline/BaseTimelineDataProvider.js +13 -10
  27. package/lib/imodel-components-react/timeline/BaseTimelineDataProvider.js.map +1 -1
  28. package/lib/imodel-components-react/timeline/InlineEdit.js +20 -20
  29. package/lib/imodel-components-react/timeline/InlineEdit.js.map +1 -1
  30. package/lib/imodel-components-react/timeline/SolarTimeline.js +144 -144
  31. package/lib/imodel-components-react/timeline/SolarTimeline.js.map +1 -1
  32. package/lib/imodel-components-react/viewport/ViewportComponentEvents.js +16 -15
  33. package/lib/imodel-components-react/viewport/ViewportComponentEvents.js.map +1 -1
  34. 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
- constructor() {
108
- super(...arguments);
109
- this._start = Vector2d.createZero();
110
- this.state = {
111
- dragging: false,
112
- startRotMatrix: Matrix3d.createIdentity(),
113
- endRotMatrix: Matrix3d.createIdentity(),
114
- animation: 1,
115
- hoverMap: {},
116
- face: Face.Top,
117
- };
118
- this._mounted = false;
119
- this._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
- };
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
- CubeNavigationAid._animationFn = (t) => t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t;
442
- CubeNavigationAid._isMatrixFace = (matrix) => {
443
- let sum = 0;
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
- return end;
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
- constructor() {
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