@idraw/core 0.4.0-beta.34 → 0.4.0-beta.36

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.
@@ -1,4 +1,5 @@
1
1
  import type { MiddlewareInfoStyle } from '@idraw/types';
2
2
  export declare const infoFontSize = 10;
3
3
  export declare const infoLineHeight = 16;
4
+ export declare const MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE = "@middleware/internal-event/show-info-angle";
4
5
  export declare const defaltStyle: MiddlewareInfoStyle;
@@ -2,6 +2,7 @@ const infoBackground = '#1973bac6';
2
2
  const infoTextColor = '#ffffff';
3
3
  export const infoFontSize = 10;
4
4
  export const infoLineHeight = 16;
5
+ export const MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE = '@middleware/internal-event/show-info-angle';
5
6
  export const defaltStyle = {
6
7
  textBackground: infoBackground,
7
8
  textColor: infoTextColor
@@ -1,5 +1,5 @@
1
1
  import type { PointSize, ViewContext2D } from '@idraw/types';
2
- import type { MiddlewareInfoStyle } from './types';
2
+ import type { MiddlewareInfoStyle } from '@idraw/types';
3
3
  export declare function drawSizeInfoText(ctx: ViewContext2D, opts: {
4
4
  point: PointSize;
5
5
  rotateCenter: PointSize;
@@ -1,3 +1,9 @@
1
1
  import type { BoardMiddleware, MiddlewareInfoConfig, CoreEventMap } from '@idraw/types';
2
2
  import type { DeepInfoSharedStorage } from './types';
3
- export declare const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, CoreEventMap, MiddlewareInfoConfig>;
3
+ import { MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE } from './config';
4
+ export { MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE };
5
+ export declare const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, CoreEventMap & {
6
+ [MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE]: {
7
+ show: boolean;
8
+ };
9
+ }, MiddlewareInfoConfig>;
@@ -1,11 +1,12 @@
1
1
  import { formatNumber, getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot, createUUID, limitAngle, rotatePoint, parseAngleToRadian } from '@idraw/util';
2
2
  import { keySelectedElementList, keyActionType, keyGroupQueue } from '../selector';
3
3
  import { drawSizeInfoText, drawPositionInfoText, drawAngleInfoText } from './draw-info';
4
- import { defaltStyle } from './config';
4
+ import { defaltStyle, MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE } from './config';
5
+ export { MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE };
5
6
  const infoFontSize = 10;
6
7
  const infoLineHeight = 16;
7
8
  export const MiddlewareInfo = (opts, config) => {
8
- const { boardContent, calculator } = opts;
9
+ const { boardContent, calculator, eventHub } = opts;
9
10
  const { overlayContext } = boardContent;
10
11
  const innerConfig = Object.assign(Object.assign({}, defaltStyle), config);
11
12
  const { textBackground, textColor } = innerConfig;
@@ -13,8 +14,18 @@ export const MiddlewareInfo = (opts, config) => {
13
14
  textBackground,
14
15
  textColor
15
16
  };
17
+ let showAngleInfo = true;
18
+ const showInfoAngleCallback = ({ show }) => {
19
+ showAngleInfo = show;
20
+ };
16
21
  return {
17
22
  name: '@middleware/info',
23
+ use() {
24
+ eventHub.on(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, showInfoAngleCallback);
25
+ },
26
+ disuse() {
27
+ eventHub.off(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, showInfoAngleCallback);
28
+ },
18
29
  beforeDrawFrame({ snapshot }) {
19
30
  const { sharedStore } = snapshot;
20
31
  const selectedElementList = sharedStore[keySelectedElementList];
@@ -92,18 +103,20 @@ export const MiddlewareInfo = (opts, config) => {
92
103
  lineHeight: infoLineHeight,
93
104
  style
94
105
  });
95
- drawAngleInfoText(overlayContext, {
96
- point: {
97
- x: rectInfo.top.x + infoFontSize,
98
- y: rectInfo.top.y - infoFontSize * 2
99
- },
100
- rotateCenter: rectInfo.center,
101
- angle: totalAngle,
102
- text: angleText,
103
- fontSize: infoFontSize,
104
- lineHeight: infoLineHeight,
105
- style
106
- });
106
+ if (showAngleInfo) {
107
+ drawAngleInfoText(overlayContext, {
108
+ point: {
109
+ x: rectInfo.top.x + infoFontSize + 4,
110
+ y: rectInfo.top.y - infoFontSize * 2 - 18
111
+ },
112
+ rotateCenter: rectInfo.center,
113
+ angle: totalAngle,
114
+ text: angleText,
115
+ fontSize: infoFontSize,
116
+ lineHeight: infoLineHeight,
117
+ style
118
+ });
119
+ }
107
120
  }
108
121
  }
109
122
  }
@@ -25,4 +25,6 @@ export declare const selectWrapperBorderWidth = 2;
25
25
  export declare const resizeControllerBorderWidth = 4;
26
26
  export declare const areaBorderWidth = 1;
27
27
  export declare const controllerSize = 10;
28
+ export declare const rotateControllerSize = 20;
29
+ export declare const rotateControllerPosition = 22;
28
30
  export declare const defaultStyle: MiddlewareSelectorStyle;
@@ -24,6 +24,8 @@ export const selectWrapperBorderWidth = 2;
24
24
  export const resizeControllerBorderWidth = 4;
25
25
  export const areaBorderWidth = 1;
26
26
  export const controllerSize = 10;
27
+ export const rotateControllerSize = 20;
28
+ export const rotateControllerPosition = 22;
27
29
  const activeColor = '#1973ba';
28
30
  const activeAreaColor = '#1976d21c';
29
31
  const lockedColor = '#5b5959b5';
@@ -0,0 +1,5 @@
1
+ import type { ElementSizeController, ViewContext2D, ViewSizeInfo, ViewScaleInfo } from '@idraw/types';
2
+ export declare function drawDebugStoreSelectedElementController(ctx: ViewContext2D, controller: ElementSizeController | null, opts: {
3
+ viewSizeInfo: ViewSizeInfo;
4
+ viewScaleInfo: ViewScaleInfo;
5
+ }): void;
@@ -0,0 +1,30 @@
1
+ import { calcViewPointSize } from '@idraw/util';
2
+ function drawDebugControllerVertexes(opts) {
3
+ const { ctx, viewScaleInfo, vertexes } = opts;
4
+ const v0 = calcViewPointSize(vertexes[0], { viewScaleInfo });
5
+ const v1 = calcViewPointSize(vertexes[1], { viewScaleInfo });
6
+ const v2 = calcViewPointSize(vertexes[2], { viewScaleInfo });
7
+ const v3 = calcViewPointSize(vertexes[3], { viewScaleInfo });
8
+ ctx.beginPath();
9
+ ctx.fillStyle = '#FF0000A1';
10
+ ctx.moveTo(v0.x, v0.y);
11
+ ctx.lineTo(v1.x, v1.y);
12
+ ctx.lineTo(v2.x, v2.y);
13
+ ctx.lineTo(v3.x, v3.y);
14
+ ctx.lineTo(v0.x, v0.y);
15
+ ctx.closePath();
16
+ ctx.fill();
17
+ return false;
18
+ }
19
+ export function drawDebugStoreSelectedElementController(ctx, controller, opts) {
20
+ if (!controller) {
21
+ return;
22
+ }
23
+ const { viewSizeInfo, viewScaleInfo } = opts;
24
+ const { left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, rotate } = controller;
25
+ const ctrls = [left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, rotate];
26
+ for (let i = 0; i < ctrls.length; i++) {
27
+ const ctrl = ctrls[i];
28
+ drawDebugControllerVertexes({ ctx, vertexes: ctrl.vertexes, viewSizeInfo, viewScaleInfo });
29
+ }
30
+ }
@@ -18,6 +18,7 @@ export declare function drawSelectedElementControllersVertexes(ctx: ViewContext2
18
18
  element: Element | null;
19
19
  calculator: ViewCalculator;
20
20
  style: MiddlewareSelectorStyle;
21
+ rotateControllerPattern: ViewContext2D;
21
22
  }): void;
22
23
  export declare function drawElementListShadows(ctx: ViewContext2D, elements: Element<ElementType>[], opts?: Omit<RendererDrawElementOptions, 'loader'>): void;
23
24
  export declare function drawArea(ctx: ViewContext2D, opts: {
@@ -1,6 +1,6 @@
1
1
  import { rotateElementVertexes, calcViewPointSize, calcViewVertexes, calcViewElementSize } from '@idraw/util';
2
- import { resizeControllerBorderWidth, areaBorderWidth, selectWrapperBorderWidth, controllerSize } from './config';
3
- import { drawVertexes, drawLine, drawCircleController, drawCrossVertexes } from './draw-base';
2
+ import { resizeControllerBorderWidth, areaBorderWidth, selectWrapperBorderWidth } from './config';
3
+ import { drawVertexes, drawCircleController, drawCrossVertexes } from './draw-base';
4
4
  export function drawHoverVertexesWrapper(ctx, vertexes, opts) {
5
5
  if (!vertexes) {
6
6
  return;
@@ -36,19 +36,21 @@ export function drawSelectedElementControllersVertexes(ctx, controller, opts) {
36
36
  if (!controller) {
37
37
  return;
38
38
  }
39
- const { hideControllers, style } = opts;
39
+ const { hideControllers, style, rotateControllerPattern, viewSizeInfo } = opts;
40
+ const { devicePixelRatio = 1 } = viewSizeInfo;
40
41
  const { activeColor } = style;
41
- const { elementWrapper, topLeft, topRight, bottomLeft, bottomRight, top, rotate } = controller;
42
+ const { elementWrapper, topLeft, topRight, bottomLeft, bottomRight, rotate } = controller;
42
43
  const wrapperOpts = { borderColor: activeColor, borderWidth: selectWrapperBorderWidth, background: 'transparent', lineDash: [] };
43
44
  const ctrlOpts = Object.assign(Object.assign({}, wrapperOpts), { borderWidth: resizeControllerBorderWidth, background: '#FFFFFF' });
44
45
  drawVertexes(ctx, calcViewVertexes(elementWrapper, opts), wrapperOpts);
45
46
  if (!hideControllers) {
46
- drawLine(ctx, calcViewPointSize(top.center, opts), calcViewPointSize(rotate.center, opts), Object.assign(Object.assign({}, ctrlOpts), { borderWidth: 2 }));
47
47
  drawVertexes(ctx, calcViewVertexes(topLeft.vertexes, opts), ctrlOpts);
48
48
  drawVertexes(ctx, calcViewVertexes(topRight.vertexes, opts), ctrlOpts);
49
49
  drawVertexes(ctx, calcViewVertexes(bottomLeft.vertexes, opts), ctrlOpts);
50
50
  drawVertexes(ctx, calcViewVertexes(bottomRight.vertexes, opts), ctrlOpts);
51
- drawCircleController(ctx, calcViewPointSize(rotate.center, opts), Object.assign(Object.assign({}, ctrlOpts), { size: controllerSize, borderWidth: 2 }));
51
+ drawCircleController(ctx, calcViewPointSize(rotate.center, opts), Object.assign(Object.assign({}, ctrlOpts), { size: rotate.size, borderWidth: 0 }));
52
+ const rotateCenter = calcViewPointSize(rotate.center, opts);
53
+ ctx.drawImage(rotateControllerPattern.canvas, 0, 0, rotateControllerPattern.canvas.width / devicePixelRatio, rotateControllerPattern.canvas.height / devicePixelRatio, rotateCenter.x - rotate.size / 2, rotateCenter.y - rotate.size / 2, rotate.size, rotate.size);
52
54
  }
53
55
  }
54
56
  export function drawElementListShadows(ctx, elements, opts) {
@@ -1,6 +1,11 @@
1
1
  import type { CoreEventMap, MiddlewareSelectorConfig } from '@idraw/types';
2
2
  import type { BoardMiddleware, ActionType, DeepSelectorSharedStorage } from './types';
3
3
  import { keyActionType, keyResizeType, keyGroupQueue, keyHoverElement, keySelectedElementList } from './config';
4
+ import { MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE } from '../info';
4
5
  export { keySelectedElementList, keyHoverElement, keyActionType, keyResizeType, keyGroupQueue };
5
6
  export type { DeepSelectorSharedStorage, ActionType };
6
- export declare const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, CoreEventMap, MiddlewareSelectorConfig>;
7
+ export declare const MiddlewareSelector: BoardMiddleware<DeepSelectorSharedStorage, CoreEventMap & {
8
+ [MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE]: {
9
+ show: boolean;
10
+ };
11
+ }, MiddlewareSelectorConfig>;
@@ -1,11 +1,13 @@
1
- import { is, calcElementsViewInfo, calcElementVertexesInGroup, calcElementQueueVertexesQueueInGroup, calcElementSizeController, calcElementCenterFromVertexes, rotatePointInGroup, getGroupQueueFromList, findElementsFromList, findElementsFromListByPositions, getElementPositionFromList, deepResizeGroupElement, getElementSize } from '@idraw/util';
1
+ import { is, calcElementsViewInfo, calcElementVertexesInGroup, calcElementQueueVertexesQueueInGroup, calcElementSizeController, calcElementCenterFromVertexes, rotatePointInGroup, getGroupQueueFromList, findElementsFromList, findElementsFromListByPositions, getElementPositionFromList, getElementPositionMapFromList, deepResizeGroupElement, getElementSize } from '@idraw/util';
2
2
  import { drawHoverVertexesWrapper, drawLockedVertexesWrapper, drawArea, drawListArea, drawGroupQueueVertexesWrappers, drawSelectedElementControllersVertexes } from './draw-wrapper';
3
3
  import { drawReferenceLines } from './draw-reference';
4
4
  import { getPointTarget, resizeElement, rotateElement, getSelectedListArea, calcSelectedElementsArea, isElementInGroup, isPointInViewActiveGroup, calcMoveInGroup } from './util';
5
- import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keySelectedElementPosition, keyIsMoving, keyEnableSelectInGroup, keyEnableSnapToGrid, controllerSize, defaultStyle } from './config';
5
+ import { keyActionType, keyResizeType, keyAreaStart, keyAreaEnd, keyGroupQueue, keyGroupQueueVertexesList, keyHoverElement, keyHoverElementVertexes, keySelectedElementList, keySelectedElementListVertexes, keySelectedElementController, keySelectedElementPosition, keyIsMoving, keyEnableSelectInGroup, keyEnableSnapToGrid, controllerSize, rotateControllerSize, rotateControllerPosition, defaultStyle } from './config';
6
6
  import { calcReferenceInfo } from './reference';
7
7
  import { coreEventKeys } from '../../config';
8
8
  import { keyLayoutIsSelected } from '../layout-selector';
9
+ import { createRotateControllerPattern } from './pattern';
10
+ import { MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE } from '../info';
9
11
  export { keySelectedElementList, keyHoverElement, keyActionType, keyResizeType, keyGroupQueue };
10
12
  export const MiddlewareSelector = (opts, config) => {
11
13
  const innerConfig = Object.assign(Object.assign({}, defaultStyle), config);
@@ -17,6 +19,11 @@ export const MiddlewareSelector = (opts, config) => {
17
19
  let moveOriginalStartPoint = null;
18
20
  let moveOriginalStartElementSize = null;
19
21
  let inBusyMode = null;
22
+ let hasChangedData = null;
23
+ const rotateControllerPattern = createRotateControllerPattern({
24
+ fill: style.activeColor,
25
+ devicePixelRatio: sharer.getActiveViewSizeInfo().devicePixelRatio
26
+ });
20
27
  sharer.setSharedStorage(keyActionType, null);
21
28
  sharer.setSharedStorage(keyEnableSnapToGrid, true);
22
29
  const getActiveElements = () => {
@@ -53,16 +60,24 @@ export const MiddlewareSelector = (opts, config) => {
53
60
  }
54
61
  sharer.setSharedStorage(keyHoverElementVertexes, vertexes);
55
62
  };
56
- const updateSelectedElementList = (list, opts) => {
57
- var _a;
58
- sharer.setSharedStorage(keySelectedElementList, list);
63
+ const updateSelectedElemenetController = () => {
64
+ const list = sharer.getSharedStorage(keySelectedElementList);
59
65
  if (list.length === 1) {
60
66
  const controller = calcElementSizeController(list[0], {
61
67
  groupQueue: sharer.getSharedStorage(keyGroupQueue),
62
68
  controllerSize,
63
- viewScaleInfo: sharer.getActiveViewScaleInfo()
69
+ viewScaleInfo: sharer.getActiveViewScaleInfo(),
70
+ rotateControllerPosition,
71
+ rotateControllerSize
64
72
  });
65
73
  sharer.setSharedStorage(keySelectedElementController, controller);
74
+ }
75
+ };
76
+ const updateSelectedElementList = (list, opts) => {
77
+ var _a;
78
+ sharer.setSharedStorage(keySelectedElementList, list);
79
+ if (list.length === 1) {
80
+ updateSelectedElemenetController();
66
81
  sharer.setSharedStorage(keySelectedElementPosition, getElementPositionFromList(list[0].uuid, ((_a = sharer.getActiveStorage('data')) === null || _a === void 0 ? void 0 : _a.elements) || []));
67
82
  }
68
83
  else {
@@ -70,7 +85,10 @@ export const MiddlewareSelector = (opts, config) => {
70
85
  sharer.setSharedStorage(keySelectedElementPosition, []);
71
86
  }
72
87
  if ((opts === null || opts === void 0 ? void 0 : opts.triggerEvent) === true) {
73
- eventHub.trigger(coreEventKeys.SELECT, { uuids: list.map((elem) => elem.uuid), positions: [] });
88
+ const uuids = list.map((elem) => elem.uuid);
89
+ const data = sharer.getActiveStorage('data');
90
+ const positionMap = getElementPositionMapFromList(uuids, (data === null || data === void 0 ? void 0 : data.elements) || []);
91
+ eventHub.trigger(coreEventKeys.SELECT, { uuids, positions: list.map((elem) => [...positionMap[elem.uuid]]) });
74
92
  }
75
93
  };
76
94
  const pointTargetBaseOptions = () => {
@@ -339,7 +357,9 @@ export const MiddlewareSelector = (opts, config) => {
339
357
  const groupQueue = sharer.getSharedStorage(keyGroupQueue);
340
358
  const enableSnapToGrid = sharer.getSharedStorage(keyEnableSnapToGrid);
341
359
  if (actionType === 'drag') {
360
+ hasChangedData = true;
342
361
  inBusyMode = 'drag';
362
+ eventHub.trigger(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, { show: false });
343
363
  if (data && (elems === null || elems === void 0 ? void 0 : elems.length) === 1 && moveOriginalStartElementSize && originalStart && end && ((_b = (_a = elems[0]) === null || _a === void 0 ? void 0 : _a.operations) === null || _b === void 0 ? void 0 : _b.locked) !== true) {
344
364
  const { moveX, moveY } = calcMoveInGroup(originalStart, end, groupQueue);
345
365
  let totalMoveX = calculator.toGridNum(moveX / scale);
@@ -384,6 +404,7 @@ export const MiddlewareSelector = (opts, config) => {
384
404
  viewer.drawFrame();
385
405
  }
386
406
  else if (actionType === 'drag-list') {
407
+ hasChangedData = true;
387
408
  inBusyMode = 'drag-list';
388
409
  if (data && originalStart && start && end && (elems === null || elems === void 0 ? void 0 : elems.length) > 1) {
389
410
  const moveX = (end.x - start.x) / scale;
@@ -412,6 +433,7 @@ export const MiddlewareSelector = (opts, config) => {
412
433
  }
413
434
  else if (actionType === 'resize') {
414
435
  if (data && (elems === null || elems === void 0 ? void 0 : elems.length) === 1 && originalStart && moveOriginalStartElementSize && (resizeType === null || resizeType === void 0 ? void 0 : resizeType.startsWith('resize-'))) {
436
+ hasChangedData = true;
415
437
  inBusyMode = 'resize';
416
438
  const pointGroupQueue = [];
417
439
  groupQueue.forEach((group) => {
@@ -501,6 +523,9 @@ export const MiddlewareSelector = (opts, config) => {
501
523
  prevPoint = null;
502
524
  moveOriginalStartPoint = null;
503
525
  moveOriginalStartElementSize = null;
526
+ if (actionType === 'drag') {
527
+ eventHub.trigger(MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE, { show: true });
528
+ }
504
529
  if (actionType === 'resize' && resizeType) {
505
530
  sharer.setSharedStorage(keyResizeType, null);
506
531
  needDrawFrame = true;
@@ -562,18 +587,21 @@ export const MiddlewareSelector = (opts, config) => {
562
587
  if (type === 'resize') {
563
588
  type = 'resizeElement';
564
589
  }
565
- eventHub.trigger(coreEventKeys.CHANGE, { data, type, selectedElements, hoverElement });
590
+ if (hasChangedData) {
591
+ eventHub.trigger(coreEventKeys.CHANGE, { data, type, selectedElements, hoverElement });
592
+ hasChangedData = false;
593
+ }
566
594
  }
567
595
  viewer.drawFrame();
568
596
  };
569
597
  finalDrawFrame();
570
598
  },
571
599
  pointLeave() {
572
- prevPoint = null;
573
- moveOriginalStartPoint = null;
574
- moveOriginalStartElementSize = null;
575
- clear();
576
- viewer.drawFrame();
600
+ inBusyMode = null;
601
+ sharer.setSharedStorage(keyResizeType, null);
602
+ eventHub.trigger(coreEventKeys.CURSOR, {
603
+ type: 'default'
604
+ });
577
605
  },
578
606
  doubleClick(e) {
579
607
  var _a, _b, _c, _d, _e, _f, _g, _h;
@@ -604,6 +632,12 @@ export const MiddlewareSelector = (opts, config) => {
604
632
  }
605
633
  sharer.setSharedStorage(keyActionType, null);
606
634
  },
635
+ wheel() {
636
+ updateSelectedElemenetController();
637
+ },
638
+ wheelScale() {
639
+ updateSelectedElemenetController();
640
+ },
607
641
  contextMenu: (e) => {
608
642
  var _a, _b, _c, _d, _e, _f, _g, _h;
609
643
  const groupQueue = sharer.getSharedStorage(keyGroupQueue);
@@ -661,30 +695,21 @@ export const MiddlewareSelector = (opts, config) => {
661
695
  const isMoving = sharedStore[keyIsMoving];
662
696
  const enableSnapToGrid = sharedStore[keyEnableSnapToGrid];
663
697
  const drawBaseOpts = { calculator, viewScaleInfo, viewSizeInfo, style };
664
- const selectedElementController = elem
665
- ? calcElementSizeController(elem, {
666
- groupQueue,
667
- controllerSize: 10,
668
- viewScaleInfo
669
- })
670
- : null;
698
+ const selectedElementController = sharedStore[keySelectedElementController];
671
699
  const isHoverLocked = !!((_a = hoverElement === null || hoverElement === void 0 ? void 0 : hoverElement.operations) === null || _a === void 0 ? void 0 : _a.locked);
672
700
  if ((groupQueue === null || groupQueue === void 0 ? void 0 : groupQueue.length) > 0) {
673
701
  drawGroupQueueVertexesWrappers(overlayContext, groupQueueVertexesList, drawBaseOpts);
674
702
  if (hoverElement && actionType !== 'drag') {
675
703
  if (isHoverLocked) {
676
- drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, Object.assign(Object.assign({}, drawBaseOpts), { controller: calcElementSizeController(hoverElement, {
677
- groupQueue,
678
- controllerSize: 10,
679
- viewScaleInfo
680
- }), style }));
704
+ drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, Object.assign(Object.assign({}, drawBaseOpts), { controller: selectedElementController, style }));
681
705
  }
682
706
  else {
683
707
  drawHoverVertexesWrapper(overlayContext, hoverElementVertexes, drawBaseOpts);
684
708
  }
685
709
  }
686
710
  if (elem && ['select', 'drag', 'resize'].includes(actionType)) {
687
- drawSelectedElementControllersVertexes(overlayContext, selectedElementController, Object.assign(Object.assign({}, drawBaseOpts), { element: elem, calculator, hideControllers: !!isMoving && actionType === 'drag', style }));
711
+ drawSelectedElementControllersVertexes(overlayContext, selectedElementController, Object.assign(Object.assign({}, drawBaseOpts), { element: elem, calculator, hideControllers: !!isMoving && actionType === 'drag', rotateControllerPattern,
712
+ style }));
688
713
  if (actionType === 'drag') {
689
714
  if (enableSnapToGrid === true) {
690
715
  const referenceInfo = calcReferenceInfo(elem.uuid, {
@@ -711,18 +736,15 @@ export const MiddlewareSelector = (opts, config) => {
711
736
  else {
712
737
  if (hoverElement && actionType !== 'drag') {
713
738
  if (isHoverLocked) {
714
- drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, Object.assign(Object.assign({}, drawBaseOpts), { controller: calcElementSizeController(hoverElement, {
715
- groupQueue,
716
- controllerSize: 10,
717
- viewScaleInfo
718
- }), style }));
739
+ drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, Object.assign(Object.assign({}, drawBaseOpts), { controller: selectedElementController, style }));
719
740
  }
720
741
  else {
721
742
  drawHoverVertexesWrapper(overlayContext, hoverElementVertexes, drawBaseOpts);
722
743
  }
723
744
  }
724
745
  if (elem && ['select', 'drag', 'resize'].includes(actionType)) {
725
- drawSelectedElementControllersVertexes(overlayContext, selectedElementController, Object.assign(Object.assign({}, drawBaseOpts), { element: elem, calculator, hideControllers: !!isMoving && actionType === 'drag', style }));
746
+ drawSelectedElementControllersVertexes(overlayContext, selectedElementController, Object.assign(Object.assign({}, drawBaseOpts), { element: elem, calculator, hideControllers: !!isMoving && actionType === 'drag', rotateControllerPattern,
747
+ style }));
726
748
  if (actionType === 'drag') {
727
749
  if (enableSnapToGrid === true) {
728
750
  const referenceInfo = calcReferenceInfo(elem.uuid, {
@@ -0,0 +1,4 @@
1
+ import type { Element } from '@idraw/types';
2
+ export declare const createIconRotate: (opts?: {
3
+ fill?: string;
4
+ }) => Element<"path", Record<string, any>>;
@@ -0,0 +1,88 @@
1
+ import { createUUID } from '@idraw/util';
2
+ export const createIconRotate = (opts) => {
3
+ const iconRotate = {
4
+ uuid: createUUID(),
5
+ type: 'path',
6
+ x: 0,
7
+ y: 0,
8
+ w: 200,
9
+ h: 200,
10
+ detail: Object.assign({ commands: [
11
+ {
12
+ type: 'M',
13
+ params: [512, 0]
14
+ },
15
+ {
16
+ type: 'c',
17
+ params: [282.8, 0, 512, 229.2, 512, 512]
18
+ },
19
+ {
20
+ type: 's',
21
+ params: [-229.2, 512, -512, 512]
22
+ },
23
+ {
24
+ type: 'S',
25
+ params: [0, 794.8, 0, 512, 229.2, 0, 512, 0]
26
+ },
27
+ {
28
+ type: 'z',
29
+ params: []
30
+ },
31
+ {
32
+ type: 'm',
33
+ params: [309.8, 253.8]
34
+ },
35
+ {
36
+ type: 'c',
37
+ params: [0, -10.5, -6.5, -19.8, -15.7, -23.8, -9.7, -4, -21, -2, -28.2, 5.6]
38
+ },
39
+ {
40
+ type: 'l',
41
+ params: [-52.5, 52]
42
+ },
43
+ {
44
+ type: 'c',
45
+ params: [
46
+ -56.9, -53.7, -133.9, -85.5, -213.4, -85.5, -170.7, 0, -309.8, 139.2, -309.8, 309.8, 0, 170.6, 139.2, 309.8, 309.8, 309.8, 92.4, 0, 179.5, -40.8,
47
+ 238.4, -111.8, 4, -5.2, 4, -12.9, -0.8, -17.3
48
+ ]
49
+ },
50
+ {
51
+ type: 'L',
52
+ params: [694.3, 637]
53
+ },
54
+ {
55
+ type: 'c',
56
+ params: [
57
+ -2.8, -2.4, -6.5, -3.6, -10.1, -3.6, -3.6, 0.4, -7.3, 2, -9.3, 4.8, -39.5, 51.2, -98.8, 80.3, -163, 80.3, -113.8, 0, -206.5, -92.8, -206.5, -206.5,
58
+ 0, -113.8, 92.8, -206.5, 206.5, -206.5, 52.8, 0, 102.9, 20.2, 140.8, 55.3
59
+ ]
60
+ },
61
+ {
62
+ type: 'L',
63
+ params: [597, 416.5]
64
+ },
65
+ {
66
+ type: 'c',
67
+ params: [-7.7, 7.3, -9.7, 18.6, -5.6, 27.9, 4, 9.7, 13.3, 16.1, 23.8, 16.1]
68
+ },
69
+ {
70
+ type: 'H',
71
+ params: [796]
72
+ },
73
+ {
74
+ type: 'c',
75
+ params: [14.1, 0, 25.8, -11.7, 25.8, -25.8]
76
+ },
77
+ {
78
+ type: 'V',
79
+ params: [253.8]
80
+ },
81
+ {
82
+ type: 'z',
83
+ params: []
84
+ }
85
+ ], fill: '#2c2c2c', stroke: 'transparent', strokeWidth: 0, originX: 0, originY: 0, originW: 1024, originH: 1024, opacity: 1 }, opts)
86
+ };
87
+ return iconRotate;
88
+ };
@@ -0,0 +1,5 @@
1
+ import type { ViewContext2D } from '@idraw/types';
2
+ export declare function createRotateControllerPattern(opts: {
3
+ fill: string;
4
+ devicePixelRatio: number;
5
+ }): ViewContext2D;
@@ -0,0 +1,38 @@
1
+ import { createOffscreenContext2D } from '@idraw/util';
2
+ import { drawElement } from '@idraw/renderer';
3
+ import { createIconRotate } from './icon-rotate';
4
+ export function createRotateControllerPattern(opts) {
5
+ const { fill, devicePixelRatio } = opts;
6
+ const iconRotate = createIconRotate({ fill });
7
+ const { w, h } = iconRotate;
8
+ const context2d = createOffscreenContext2D({
9
+ width: w,
10
+ height: h,
11
+ devicePixelRatio
12
+ });
13
+ drawElement(context2d, iconRotate, {
14
+ loader: undefined,
15
+ viewScaleInfo: {
16
+ scale: 1,
17
+ offsetTop: 0,
18
+ offsetBottom: 0,
19
+ offsetLeft: 0,
20
+ offsetRight: 0
21
+ },
22
+ viewSizeInfo: {
23
+ width: w,
24
+ height: h,
25
+ devicePixelRatio,
26
+ contextWidth: w,
27
+ contextHeight: h
28
+ },
29
+ parentElementSize: {
30
+ x: 0,
31
+ y: 0,
32
+ w,
33
+ h
34
+ },
35
+ parentOpacity: 1
36
+ });
37
+ return context2d;
38
+ }
@@ -679,7 +679,7 @@ export function rotateElement(elem, opts) {
679
679
  });
680
680
  const startAngle = limitAngle(angle);
681
681
  const changedRadian = calcRadian(elemCenter, start, end);
682
- const endAngle = startAngle + parseRadianToAngle(changedRadian);
682
+ const endAngle = limitAngle(startAngle + parseRadianToAngle(changedRadian));
683
683
  return {
684
684
  x,
685
685
  y,