@peteai/presentation-editor 0.0.2 → 0.0.4

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 (211) hide show
  1. package/README.md +2 -2
  2. package/dist/components/presentation-editor/active-layers-buttons.svelte +53 -0
  3. package/dist/components/presentation-editor/active-layers-buttons.svelte.d.ts +3 -0
  4. package/dist/components/presentation-editor/active-layers.svelte +181 -0
  5. package/dist/components/presentation-editor/active-layers.svelte.d.ts +3 -0
  6. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient-def.svelte +81 -0
  7. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient-def.svelte.d.ts +9 -0
  8. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient.svelte +21 -0
  9. package/dist/components/presentation-editor/color-indicator/color-indicator-gradient.svelte.d.ts +8 -0
  10. package/dist/components/presentation-editor/color-indicator/color-indicator.svelte +23 -0
  11. package/dist/components/presentation-editor/color-indicator/color-indicator.svelte.d.ts +6 -0
  12. package/dist/components/presentation-editor/color-indicator/index.d.ts +4 -0
  13. package/dist/components/presentation-editor/color-indicator/index.js +6 -0
  14. package/dist/components/presentation-editor/cursor-tooltip.svelte +1 -1
  15. package/dist/components/presentation-editor/dragged.svelte +21 -11
  16. package/dist/components/presentation-editor/fonts.d.ts +3 -0
  17. package/dist/components/presentation-editor/fonts.js +1278 -0
  18. package/dist/components/presentation-editor/header.svelte +21 -33
  19. package/dist/components/presentation-editor/header.svelte.d.ts +16 -6
  20. package/dist/components/presentation-editor/hotkeys.svelte +85 -0
  21. package/dist/components/presentation-editor/{sidebar/layers.svelte.d.ts → hotkeys.svelte.d.ts} +3 -3
  22. package/dist/components/presentation-editor/layers/active-background-border.svelte +3 -7
  23. package/dist/components/presentation-editor/layers/active-layer-border.svelte +2 -5
  24. package/dist/components/presentation-editor/layers/active-layer-border.svelte.d.ts +0 -1
  25. package/dist/components/presentation-editor/layers/buttons/border-button/border-button.svelte +113 -129
  26. package/dist/components/presentation-editor/layers/buttons/border-button/border-button.svelte.d.ts +2 -2
  27. package/dist/components/presentation-editor/layers/buttons/corner-radius-button/corner-radius-button.svelte +51 -32
  28. package/dist/components/presentation-editor/layers/buttons/corner-radius-button/corner-radius-button.svelte.d.ts +2 -2
  29. package/dist/components/presentation-editor/layers/buttons/flip-button/flip-button.svelte +30 -7
  30. package/dist/components/presentation-editor/layers/buttons/flip-button/flip-button.svelte.d.ts +3 -3
  31. package/dist/components/presentation-editor/layers/buttons/opacity-button/opacity-button.svelte +76 -33
  32. package/dist/components/presentation-editor/layers/buttons/opacity-button/opacity-button.svelte.d.ts +3 -3
  33. package/dist/components/presentation-editor/layers/controls/corner-scale-control/corner-scale-control.svelte +89 -59
  34. package/dist/components/presentation-editor/layers/controls/corner-scale-control/corner-scale-control.svelte.d.ts +5 -100
  35. package/dist/components/presentation-editor/layers/controls/group-resize-control/group-resize-control.svelte +337 -0
  36. package/dist/components/presentation-editor/layers/controls/group-resize-control/group-resize-control.svelte.d.ts +104 -0
  37. package/dist/components/presentation-editor/layers/controls/group-resize-control/index.d.ts +2 -0
  38. package/dist/components/presentation-editor/layers/controls/group-resize-control/index.js +4 -0
  39. package/dist/components/presentation-editor/layers/controls/rotate-control/rotate-control.svelte +128 -43
  40. package/dist/components/presentation-editor/layers/controls/rotate-control/rotate-control.svelte.d.ts +1 -5
  41. package/dist/components/presentation-editor/layers/controls/side-resize-control/side-resize-control.svelte +68 -57
  42. package/dist/components/presentation-editor/layers/controls/side-resize-control/side-resize-control.svelte.d.ts +2 -110
  43. package/dist/components/presentation-editor/layers/controls/side-scale-control/side-scale-control.svelte +45 -32
  44. package/dist/components/presentation-editor/layers/controls/side-scale-control/side-scale-control.svelte.d.ts +2 -54
  45. package/dist/components/presentation-editor/layers/index.d.ts +4 -5
  46. package/dist/components/presentation-editor/layers/index.js +7 -8
  47. package/dist/components/presentation-editor/layers/layer-button.svelte +25 -7
  48. package/dist/components/presentation-editor/layers/layer-wrapper.svelte +212 -162
  49. package/dist/components/presentation-editor/layers/layer-wrapper.svelte.d.ts +2 -2
  50. package/dist/components/presentation-editor/layers/types/background/background-content-image.svelte +41 -0
  51. package/dist/components/presentation-editor/layers/types/background/background-content-image.svelte.d.ts +8 -0
  52. package/dist/components/presentation-editor/layers/types/background/background-layer-buttons.svelte +28 -74
  53. package/dist/components/presentation-editor/layers/types/background/background-layer-buttons.svelte.d.ts +2 -17
  54. package/dist/components/presentation-editor/layers/types/background/background-layer-content.svelte +19 -0
  55. package/dist/components/presentation-editor/layers/types/background/background-layer-content.svelte.d.ts +8 -0
  56. package/dist/components/presentation-editor/layers/types/background/background-layer.svelte +69 -61
  57. package/dist/components/presentation-editor/layers/types/background/background-layer.svelte.d.ts +2 -3
  58. package/dist/components/presentation-editor/layers/types/background/index.d.ts +2 -3
  59. package/dist/components/presentation-editor/layers/types/background/index.js +2 -3
  60. package/dist/components/presentation-editor/layers/types/html/buttons/alignment-button/alignment-button.svelte +55 -12
  61. package/dist/components/presentation-editor/layers/types/html/buttons/alignment-button/alignment-button.svelte.d.ts +3 -3
  62. package/dist/components/presentation-editor/layers/types/html/buttons/bold-button/bold-button.svelte +60 -8
  63. package/dist/components/presentation-editor/layers/types/html/buttons/bold-button/bold-button.svelte.d.ts +3 -3
  64. package/dist/components/presentation-editor/layers/types/html/buttons/case-button/case-button.svelte +59 -24
  65. package/dist/components/presentation-editor/layers/types/html/buttons/case-button/case-button.svelte.d.ts +3 -3
  66. package/dist/components/presentation-editor/layers/types/html/buttons/color-button/color-button.svelte +27 -76
  67. package/dist/components/presentation-editor/layers/types/html/buttons/color-button/color-button.svelte.d.ts +3 -3
  68. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/font-family-button.svelte +36 -0
  69. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/font-family-button.svelte.d.ts +7 -0
  70. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/index.d.ts +2 -0
  71. package/dist/components/presentation-editor/layers/types/html/buttons/font-family-button/index.js +2 -0
  72. package/dist/components/presentation-editor/layers/types/html/buttons/font-size-button/font-size-button.svelte +72 -29
  73. package/dist/components/presentation-editor/layers/types/html/buttons/font-size-button/font-size-button.svelte.d.ts +3 -5
  74. package/dist/components/presentation-editor/layers/types/html/buttons/italic-button/italic-button.svelte +60 -8
  75. package/dist/components/presentation-editor/layers/types/html/buttons/italic-button/italic-button.svelte.d.ts +3 -3
  76. package/dist/components/presentation-editor/layers/types/html/buttons/list-button/list-button.svelte +71 -18
  77. package/dist/components/presentation-editor/layers/types/html/buttons/list-button/list-button.svelte.d.ts +3 -3
  78. package/dist/components/presentation-editor/layers/types/html/buttons/strikethrough-button/strikethrough-button.svelte +54 -8
  79. package/dist/components/presentation-editor/layers/types/html/buttons/strikethrough-button/strikethrough-button.svelte.d.ts +3 -3
  80. package/dist/components/presentation-editor/layers/types/html/buttons/underline-button/underline-button.svelte +54 -9
  81. package/dist/components/presentation-editor/layers/types/html/buttons/underline-button/underline-button.svelte.d.ts +3 -3
  82. package/dist/components/presentation-editor/layers/types/html/editor/createEditor.js +2 -2
  83. package/dist/components/presentation-editor/layers/types/html/editor/utils.d.ts +11 -0
  84. package/dist/components/presentation-editor/layers/types/html/editor/utils.js +88 -0
  85. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/font-family.d.ts +27 -0
  86. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/font-family.js +40 -0
  87. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/index.d.ts +3 -0
  88. package/dist/components/presentation-editor/layers/types/html/extensions/font-family/index.js +3 -0
  89. package/dist/components/presentation-editor/layers/types/html/extensions/font-size/font-size.d.ts +5 -1
  90. package/dist/components/presentation-editor/layers/types/html/extensions/font-size/font-size.js +3 -7
  91. package/dist/components/presentation-editor/layers/types/html/extensions.d.ts +1 -0
  92. package/dist/components/presentation-editor/layers/types/html/extensions.js +56 -0
  93. package/dist/components/presentation-editor/layers/types/html/html-content.svelte +26 -5
  94. package/dist/components/presentation-editor/layers/types/html/html-layer-content.svelte +26 -0
  95. package/dist/components/presentation-editor/layers/types/html/html-layer-content.svelte.d.ts +9 -0
  96. package/dist/components/presentation-editor/layers/types/html/html-layer-edit.svelte +103 -0
  97. package/dist/components/presentation-editor/layers/types/html/html-layer-edit.svelte.d.ts +8 -0
  98. package/dist/components/presentation-editor/layers/types/html/html-layer.svelte +61 -53
  99. package/dist/components/presentation-editor/layers/types/html/index.d.ts +3 -5
  100. package/dist/components/presentation-editor/layers/types/html/index.js +3 -56
  101. package/dist/components/presentation-editor/layers/types/image/{image-content.svelte → image-layer-content.svelte} +11 -3
  102. package/dist/components/presentation-editor/layers/types/image/image-layer-content.svelte.d.ts +8 -0
  103. package/dist/components/presentation-editor/layers/types/image/image-layer.svelte +51 -21
  104. package/dist/components/presentation-editor/layers/types/image/index.d.ts +2 -4
  105. package/dist/components/presentation-editor/layers/types/image/index.js +2 -4
  106. package/dist/components/presentation-editor/layers/utils.d.ts +68 -9
  107. package/dist/components/presentation-editor/layers/utils.js +260 -25
  108. package/dist/components/presentation-editor/menu/background-menu-content.svelte +80 -0
  109. package/dist/components/presentation-editor/menu/background-menu-content.svelte.d.ts +9 -0
  110. package/dist/components/presentation-editor/menu/layer-menu-content.svelte +183 -0
  111. package/dist/components/presentation-editor/menu/layer-menu-content.svelte.d.ts +3 -0
  112. package/dist/components/presentation-editor/menu/slide-menu-content.svelte +67 -0
  113. package/dist/components/presentation-editor/menu/slide-menu-content.svelte.d.ts +9 -0
  114. package/dist/components/presentation-editor/presentation-editor.svelte +119 -175
  115. package/dist/components/presentation-editor/presentation-editor.svelte.js +597 -136
  116. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte +58 -0
  117. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-color.svelte.d.ts +10 -0
  118. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte +144 -0
  119. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar-gradient-picker.svelte.d.ts +7 -0
  120. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte +404 -0
  121. package/dist/components/presentation-editor/sidebar/color-sidebar/color-sidebar.svelte.d.ts +3 -0
  122. package/dist/components/presentation-editor/sidebar/color-sidebar/index.d.ts +2 -0
  123. package/dist/components/presentation-editor/sidebar/color-sidebar/index.js +2 -0
  124. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte +26 -0
  125. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar-button.svelte.d.ts +8 -0
  126. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte +216 -0
  127. package/dist/components/presentation-editor/sidebar/font-sidebar/font-sidebar.svelte.d.ts +3 -0
  128. package/dist/components/presentation-editor/sidebar/font-sidebar/index.d.ts +2 -0
  129. package/dist/components/presentation-editor/sidebar/font-sidebar/index.js +2 -0
  130. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte +130 -0
  131. package/dist/components/presentation-editor/sidebar/position-slidebar.svelte.d.ts +18 -0
  132. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte +90 -0
  133. package/dist/components/presentation-editor/sidebar/sidebar-text-tab-button.svelte.d.ts +7 -0
  134. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte +82 -0
  135. package/dist/components/presentation-editor/sidebar/sidebar-text-tab.svelte.d.ts +18 -0
  136. package/dist/components/presentation-editor/sidebar/{images-library.svelte → sidebar-uploads-tab.svelte} +0 -1
  137. package/dist/components/presentation-editor/sidebar/sidebar-uploads-tab.svelte.d.ts +3 -0
  138. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte +25 -0
  139. package/dist/components/presentation-editor/sidebar/sidebar-wrapper.svelte.d.ts +7 -0
  140. package/dist/components/presentation-editor/sidebar/sidebar.svelte +71 -15
  141. package/dist/components/presentation-editor/sidebar/sidebar.svelte.d.ts +16 -5
  142. package/dist/components/presentation-editor/sidebar/uploads-image.svelte +28 -11
  143. package/dist/components/presentation-editor/slide-editor.svelte +20 -22
  144. package/dist/components/presentation-editor/slide-inner.svelte +19 -18
  145. package/dist/components/presentation-editor/slides-navigation/slide-preview.svelte +61 -52
  146. package/dist/components/presentation-editor/slides-navigation/slides-navigation.svelte +6 -8
  147. package/dist/components/presentation-editor/snapping-guides.svelte +3 -3
  148. package/dist/components/presentation-editor/types.d.ts +67 -27
  149. package/dist/components/presentation-editor/utils.d.ts +50 -1
  150. package/dist/components/presentation-editor/utils.js +101 -6
  151. package/dist/components/ui/button/button.svelte +3 -2
  152. package/dist/components/ui/button/button.svelte.d.ts +5 -82
  153. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte +43 -0
  154. package/dist/components/ui/color-picker/color-picker-alpha-grid.svelte.d.ts +8 -0
  155. package/dist/components/ui/color-picker/color-picker.svelte +344 -0
  156. package/dist/components/ui/color-picker/color-picker.svelte.d.ts +13 -0
  157. package/dist/components/ui/color-picker/index.d.ts +3 -0
  158. package/dist/components/ui/color-picker/index.js +5 -0
  159. package/dist/components/ui/context-menu/context-menu-shortcut.svelte +6 -3
  160. package/dist/components/ui/context-menu/context-menu-sub-trigger.svelte +1 -1
  161. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +1 -1
  162. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +6 -3
  163. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +1 -1
  164. package/dist/components/ui/infinite-loader/index.d.ts +4 -0
  165. package/dist/components/ui/infinite-loader/index.js +4 -0
  166. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.d.ts +13 -0
  167. package/dist/components/ui/infinite-loader/infinite-loader-loop-tracker.js +44 -0
  168. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.d.ts +15 -0
  169. package/dist/components/ui/infinite-loader/infinite-loader-state.svelte.js +28 -0
  170. package/dist/components/ui/infinite-loader/infinite-loader.svelte +149 -0
  171. package/dist/components/ui/infinite-loader/infinite-loader.svelte.d.ts +17 -0
  172. package/dist/components/ui/input/input.svelte +1 -1
  173. package/dist/components/ui/slider/slider.svelte +20 -18
  174. package/dist/components/ui/tabs/index.d.ts +6 -0
  175. package/dist/components/ui/tabs/index.js +8 -0
  176. package/dist/components/ui/tabs/tabs-content.svelte +19 -0
  177. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +4 -0
  178. package/dist/components/ui/tabs/tabs-list.svelte +19 -0
  179. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +4 -0
  180. package/dist/components/ui/tabs/tabs-trigger.svelte +19 -0
  181. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +4 -0
  182. package/dist/components/ui/toggle/toggle.svelte +3 -2
  183. package/dist/components/ui/toggle/toggle.svelte.d.ts +2 -46
  184. package/dist/plugin.js +3 -2
  185. package/dist/utils.d.ts +1 -0
  186. package/dist/utils.js +1 -0
  187. package/package.json +28 -25
  188. package/dist/components/presentation-editor/app.css +0 -12
  189. package/dist/components/presentation-editor/layers/hovered-layer.svelte +0 -34
  190. package/dist/components/presentation-editor/layers/hovered-layer.svelte.d.ts +0 -7
  191. package/dist/components/presentation-editor/layers/types/background/background-content.svelte +0 -11
  192. package/dist/components/presentation-editor/layers/types/background/background-content.svelte.d.ts +0 -7
  193. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte +0 -12
  194. package/dist/components/presentation-editor/layers/types/background/background-layer-thumb.svelte.d.ts +0 -7
  195. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte +0 -159
  196. package/dist/components/presentation-editor/layers/types/html/html-layer-active.svelte.d.ts +0 -8
  197. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte +0 -42
  198. package/dist/components/presentation-editor/layers/types/html/html-layer-buttons.svelte.d.ts +0 -10
  199. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte +0 -24
  200. package/dist/components/presentation-editor/layers/types/html/html-layer-thumb.svelte.d.ts +0 -8
  201. package/dist/components/presentation-editor/layers/types/image/image-content.svelte.d.ts +0 -8
  202. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte +0 -21
  203. package/dist/components/presentation-editor/layers/types/image/image-layer-buttons.svelte.d.ts +0 -7
  204. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte +0 -13
  205. package/dist/components/presentation-editor/layers/types/image/image-layer-thumb.svelte.d.ts +0 -8
  206. package/dist/components/presentation-editor/sidebar/images-library.svelte.d.ts +0 -3
  207. package/dist/components/presentation-editor/sidebar/layers.svelte +0 -94
  208. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte +0 -32
  209. package/dist/components/presentation-editor/slides-navigation/buttons/slide-delete-button.svelte.d.ts +0 -10
  210. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte +0 -34
  211. package/dist/components/presentation-editor/slides-navigation/buttons/slide-duplicate-button.svelte.d.ts +0 -10
@@ -1,90 +1,175 @@
1
- <script lang="ts" module>
2
- import type { Layer } from '../../../types.js';
3
-
4
- interface Props {
5
- layer: Layer;
6
- }
7
- </script>
8
-
9
1
  <script lang="ts">
10
2
  import RotateIcon from 'lucide-svelte/icons/refresh-cw';
11
3
  import { getPresentationEditorContext } from '../../../presentation-editor.svelte.js';
4
+ import {
5
+ calculateGroupRotatedBoundingBox,
6
+ calculateLayerTransform,
7
+ type Transform,
8
+ } from '../../utils.js';
9
+ import type { Layer } from '../../../types.js';
12
10
 
13
- let { layer = $bindable() }: Props = $props();
11
+ const type = 'rotate';
14
12
 
15
13
  const editor = getPresentationEditorContext();
16
14
 
17
15
  let element: HTMLElement | null = $state(null);
18
16
 
17
+ let initial: {
18
+ clientX: number;
19
+ clientY: number;
20
+ bbox: Transform;
21
+ layers: (Layer & { state: Layer })[];
22
+ } | null = null;
23
+ const actionId = editor.generateId();
24
+ let currentRotate = 0;
25
+
26
+ /**
27
+ * Normalize the rotation angle to be between -180 and 180 degrees.
28
+ *
29
+ * @param rotate - The rotation angle in degrees.
30
+ * @returns The normalized rotation angle.
31
+ */
32
+ const normalizeRotation = (rotate: number) => {
33
+ // Adjust the rotation to be within the range of 0 to 360 degrees
34
+ const adjustedRotate = (rotate + 360) % 360;
35
+ // If the adjusted rotation is greater than or equal to 180, subtract 360 to bring it within the range of -180 to 180
36
+ return adjustedRotate >= 180 ? adjustedRotate - 360 : adjustedRotate;
37
+ };
38
+
19
39
  const onMouseDown = (e: MouseEvent) => {
40
+ if (e.button !== 0) return;
20
41
  e.preventDefault();
21
42
  e.stopPropagation();
22
- console.log('rotate', 'mousedown', layer.id);
23
- editor.activeAction = {
24
- type: 'rotate',
25
- cursor: 'cursor-grabbing',
43
+ console.log(type, 'mousedown', e);
44
+
45
+ if (!editor.activeLayers.length) return;
46
+ initial = {
26
47
  clientX: e.clientX,
27
48
  clientY: e.clientY,
28
- layer: { ...layer },
49
+ bbox:
50
+ editor.activeLayers.length === 1
51
+ ? calculateLayerTransform(editor.activeLayers[0])
52
+ : calculateGroupRotatedBoundingBox(
53
+ editor.activeLayers.map(calculateLayerTransform),
54
+ editor.activeGroupRotate,
55
+ ),
56
+ layers: editor.activeLayers.map((layer) => ({ ...layer, state: layer })),
29
57
  };
58
+ editor.activeAction = { id: actionId, type, cursor: 'cursor-grabbing' };
59
+ currentRotate = initial.bbox.rotate;
30
60
  addEventListener('mousemove', onMouseMove);
31
61
  addEventListener('mouseup', onMouseUp);
32
62
  };
33
63
 
34
- const onMouseUp = () => {
35
- console.log('rotate', 'mouseup', layer.id);
36
- if (editor.activeAction && editor.activeAction.layer.rotate !== layer.rotate) {
37
- if (editor.checkIfLayerInBounds(layer)) {
38
- editor.historyPush({
39
- type: 'layer',
40
- layer: { id: layer.id, type: layer.type },
41
- undo: { rotate: editor.activeAction.layer.rotate },
42
- redo: { rotate: layer.rotate },
43
- });
44
- }
45
- }
46
- editor.activeAction = null;
64
+ const onMouseUp = (e: MouseEvent) => {
65
+ console.log(type, 'mouseup', e);
47
66
  removeEventListener('mousemove', onMouseMove);
48
67
  removeEventListener('mouseup', onMouseUp);
68
+
69
+ if (editor.activeAction?.id !== actionId) return;
70
+ editor.activeAction = null;
71
+ if (!initial || currentRotate === initial.bbox.rotate) return;
72
+
73
+ editor.historyPush({
74
+ type: 'layersGroup',
75
+ actions: initial.layers.map((layer) => {
76
+ if (editor.isLayerOutOfBounds(layer.state)) {
77
+ return {
78
+ type: 'layersRemove',
79
+ slideId: editor.activeSlide.id,
80
+ layers: [layer],
81
+ };
82
+ } else {
83
+ return {
84
+ type: 'layer',
85
+ slideId: editor.activeSlide.id,
86
+ layer: { id: layer.id, type: layer.type },
87
+ undo: { x: layer.x, y: layer.y, rotate: layer.rotate },
88
+ redo: { x: layer.state.x, y: layer.state.y, rotate: layer.state.rotate },
89
+ };
90
+ }
91
+ }),
92
+ });
49
93
  };
50
94
 
51
95
  const onMouseMove = (e: MouseEvent) => {
52
- if (!editor.activeAction || !element) return;
96
+ if (!initial || editor.activeAction?.id !== actionId || !element) return;
53
97
 
54
98
  const slideClientRect = element.closest('[data-slide-container]')?.getBoundingClientRect();
55
99
  if (!slideClientRect) return;
56
100
 
57
101
  const { x: slideX, y: slideY } = slideClientRect;
58
102
 
59
- const { width, height, x, y } = editor.activeAction.layer;
60
- const scale = editor.activeAction.layer.scale || 1;
103
+ const { width, height, x, y, rotate } = initial.bbox;
61
104
 
62
105
  // Calculate the center of the layer
63
- const centerX = slideX + x * editor.zoom + (width * scale * editor.zoom) / 2;
64
- const centerY = slideY + y * editor.zoom + (height * scale * editor.zoom) / 2;
106
+ const clientX = slideX + x * editor.zoom + (width * editor.zoom) / 2;
107
+ const clientY = slideY + y * editor.zoom + (height * editor.zoom) / 2;
65
108
 
66
109
  // Calculate the current angle based on the current mouse position relative to the center of the layer
67
110
  const currentAngle = Math.atan2(
68
- (e.clientY - centerY) / editor.zoom,
69
- (e.clientX - centerX) / editor.zoom,
111
+ (e.clientY - clientY) / editor.zoom,
112
+ (e.clientX - clientX) / editor.zoom,
70
113
  );
71
114
 
72
115
  // Convert the current angle from radians to degrees and adjust to make 0 degrees the initial position
73
- let rotate = ((currentAngle * 180) / Math.PI - 90 + 360) % 360;
116
+ currentRotate = (currentAngle * 180) / Math.PI - 90;
74
117
 
75
118
  // Add snapping
76
119
  const snapThreshold = 1;
77
- const remainder = rotate % 45;
120
+ const remainder = Math.abs(currentRotate) % 45;
78
121
  if (remainder < snapThreshold || remainder > 45 - snapThreshold) {
79
- rotate = Math.round(rotate / 45) * 45;
122
+ currentRotate = Math.round(currentRotate / 45) * 45;
80
123
  }
81
124
 
82
- // Normalize the rotation to be between -180 and 180 degrees
83
- if (rotate >= 180) rotate -= 360;
125
+ currentRotate = normalizeRotation(currentRotate);
126
+
127
+ // Apply the new rotation
128
+ if (initial.layers.length > 1) {
129
+ editor.activeGroupRotate = currentRotate;
130
+
131
+ const rotateDiff = currentRotate - rotate;
132
+ const angle = (rotateDiff * Math.PI) / 180;
133
+ const centerX = x + width / 2;
134
+ const centerY = y + height / 2;
135
+
136
+ initial.layers.forEach((layer) => {
137
+ const { width, height, x, y, rotate } = calculateLayerTransform(layer);
138
+ // Find center of layerect
139
+ const layerCenterX = x + width / 2;
140
+ const layerCenterY = y + height / 2;
141
+
142
+ // Translate to origin
143
+ const dx = layerCenterX - centerX;
144
+ const dy = layerCenterY - centerY;
145
+
146
+ // Apply rotation
147
+ const rotatedX = dx * Math.cos(angle) - dy * Math.sin(angle);
148
+ const rotatedY = dx * Math.sin(angle) + dy * Math.cos(angle);
84
149
 
85
- // Apply the new rotation to the layer
86
- layer.rotate = rotate;
87
- editor.activeAction.tooltip = { x: e.clientX, y: e.clientY, text: `${Math.round(rotate)}°` };
150
+ // Translate back
151
+ const newCenterX = rotatedX + centerX;
152
+ const newCenterY = rotatedY + centerY;
153
+
154
+ // Compute new top-left corner
155
+ const newX = newCenterX - width / 2;
156
+ const newY = newCenterY - height / 2;
157
+
158
+ const newRotate = normalizeRotation(rotate + rotateDiff);
159
+
160
+ Object.assign(layer.state, { rotate: newRotate, x: newX, y: newY });
161
+ });
162
+ } else {
163
+ // layer.rotate = rotate;
164
+ initial.layers.forEach((layer) => {
165
+ Object.assign(layer.state, { rotate: currentRotate });
166
+ });
167
+ }
168
+ editor.activeAction.tooltip = {
169
+ x: e.clientX,
170
+ y: e.clientY,
171
+ text: `${Math.round(currentRotate)}°`,
172
+ };
88
173
  };
89
174
  </script>
90
175
 
@@ -96,7 +181,7 @@
96
181
  onmousedown={onMouseDown}
97
182
  ></div>
98
183
  <div
99
- class="flex h-6 w-6 items-center justify-center rounded-full bg-white transition-colors group-hover:bg-purple-500 group-active:bg-purple-500"
184
+ class="group-hover:bg-primary group-active:bg-primary group-hover:text-primary-foreground group-active:text-primary-foreground flex h-6 w-6 items-center justify-center rounded-full bg-white transition-colors"
100
185
  style:box-shadow="0 0 4px 1px rgba(57,76,96,.15), 0 0 0 1px rgba(43,59,74,.3)"
101
186
  >
102
187
  <RotateIcon class="h-4 w-4" />
@@ -1,7 +1,3 @@
1
- import type { Layer } from '../../../types.js';
2
- interface Props {
3
- layer: Layer;
4
- }
5
- declare const RotateControl: import("svelte").Component<Props, {}, "layer">;
1
+ declare const RotateControl: import("svelte").Component<Record<string, never>, {}, "">;
6
2
  type RotateControl = ReturnType<typeof RotateControl>;
7
3
  export default RotateControl;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" module>
2
2
  import { tv, type VariantProps } from 'tailwind-variants';
3
- import type { ActiveAction, ImageLayer } from '../../../types.js';
3
+ import type { ImageLayer } from '../../../types.js';
4
4
 
5
5
  const sideResizeControlVariants = tv({
6
6
  slots: {
@@ -56,42 +56,63 @@
56
56
 
57
57
  const editor = getPresentationEditorContext();
58
58
 
59
- let action: (Omit<ActiveAction, 'layer'> & { layer: ImageLayer }) | null = null;
60
- let isChanged = false;
61
-
62
59
  const { base, handler, grip, cursor } = sideResizeControlVariants({ origin });
63
60
 
61
+ let initial: { clientX: number; clientY: number; layer: ImageLayer } | null = null;
62
+ let isChanged = false;
63
+ const actionId = editor.generateId();
64
+
64
65
  const onMouseDown = (e: MouseEvent) => {
66
+ if (e.button !== 0) return;
65
67
  e.preventDefault();
66
68
  e.stopPropagation();
67
69
  console.log(`${origin}-origin-resize`, 'mousedown', layer.id);
70
+
68
71
  isChanged = false;
69
- action = {
70
- type: `${origin}-origin-resize`,
71
- cursor: cursor(),
72
+ initial = {
72
73
  clientX: e.clientX,
73
74
  clientY: e.clientY,
74
75
  layer: { ...layer },
75
76
  };
76
- editor.activeAction = action;
77
+ editor.activeAction = {
78
+ id: actionId,
79
+ type: `${origin}-origin-resize`,
80
+ cursor: cursor(),
81
+ };
77
82
  addEventListener('mousemove', onMouseMove);
78
83
  addEventListener('mouseup', onMouseUp);
79
84
  };
80
85
 
81
- const onMouseUp = () => {
82
- console.log(`${origin}-origin-resize`, 'mouseup', layer.id);
83
- if (isChanged && action) {
84
- if (editor.checkIfLayerInBounds(layer)) {
85
- const undo = {
86
- scale: action.layer.scale,
87
- x: action.layer.x,
88
- y: action.layer.y,
89
- width: action.layer.width,
90
- height: action.layer.height,
91
- offsetX: action.layer.offsetX,
92
- offsetY: action.layer.offsetY,
93
- };
94
- const redo = {
86
+ const onMouseUp = (e: MouseEvent) => {
87
+ console.log(`${origin}-origin-resize`, 'mouseup', layer.id, e);
88
+ removeEventListener('mousemove', onMouseMove);
89
+ removeEventListener('mouseup', onMouseUp);
90
+
91
+ if (editor.activeAction?.id !== actionId) return;
92
+ editor.activeAction = null;
93
+ if (!initial || !isChanged) return;
94
+
95
+ if (editor.isLayerOutOfBounds(layer)) {
96
+ editor.historyPush({
97
+ type: 'layersRemove',
98
+ slideId: editor.activeSlide.id,
99
+ layers: [initial.layer],
100
+ });
101
+ } else {
102
+ editor.historyPush({
103
+ type: 'layer',
104
+ slideId: editor.activeSlide.id,
105
+ layer: { id: layer.id, type: layer.type },
106
+ undo: {
107
+ scale: initial.layer.scale,
108
+ x: initial.layer.x,
109
+ y: initial.layer.y,
110
+ width: initial.layer.width,
111
+ height: initial.layer.height,
112
+ offsetX: initial.layer.offsetX,
113
+ offsetY: initial.layer.offsetY,
114
+ },
115
+ redo: {
95
116
  scale: layer.scale,
96
117
  x: layer.x,
97
118
  y: layer.y,
@@ -99,37 +120,27 @@
99
120
  height: layer.height,
100
121
  offsetX: layer.offsetX,
101
122
  offsetY: layer.offsetY,
102
- };
103
- editor.historyPush({
104
- type: 'layer',
105
- layer: { id: layer.id, type: layer.type },
106
- undo,
107
- redo,
108
- });
109
- }
123
+ },
124
+ });
110
125
  }
111
- action = null;
112
- editor.activeAction = null;
113
- removeEventListener('mousemove', onMouseMove);
114
- removeEventListener('mouseup', onMouseUp);
126
+ initial = null;
115
127
  };
116
128
 
117
129
  const onMouseMove = async (e: MouseEvent) => {
118
- if (!action) return;
130
+ if (!initial || editor.activeAction?.id !== actionId) return;
119
131
 
120
132
  isChanged = true;
121
- const { clientX, clientY } = action;
122
- const { width, height, x, y } = action.layer;
123
- const scale = action.layer.scale || 1;
124
- const rotate = action.layer.rotate || 0;
125
- const offsetX = action.layer.offsetX || 0;
126
- const offsetY = action.layer.offsetY || 0;
133
+ const { width, height, x, y, flipX, flipY } = initial.layer;
134
+ const scale = initial.layer.scale || 1;
135
+ const rotate = initial.layer.rotate || 0;
136
+ const offsetX = initial.layer.offsetX || 0;
137
+ const offsetY = initial.layer.offsetY || 0;
127
138
 
128
139
  const angle = (rotate * Math.PI) / 180;
129
- const xDiff = (e.clientX - clientX) / editor.zoom;
130
- const yDiff = (e.clientY - clientY) / editor.zoom;
131
- const adjustedXDiff = xDiff * Math.cos(angle) + yDiff * Math.sin(angle);
132
- const adjustedYDiff = -xDiff * Math.sin(angle) + yDiff * Math.cos(angle);
140
+ const xDiff = (e.clientX - initial.clientX) / editor.zoom;
141
+ const yDiff = (e.clientY - initial.clientY) / editor.zoom;
142
+ const adjustedXDiff = (xDiff * Math.cos(angle) + yDiff * Math.sin(angle)) * (flipX ? -1 : 1);
143
+ const adjustedYDiff = (-xDiff * Math.sin(angle) + yDiff * Math.cos(angle)) * (flipY ? -1 : 1);
133
144
 
134
145
  let newWidth = width * scale;
135
146
  let newHeight = height * scale;
@@ -137,8 +148,8 @@
137
148
  let newOffsetX = offsetX;
138
149
  let newOffsetY = offsetY;
139
150
  const snapping = 10;
140
- if (origin === 'left') {
141
- newWidth += adjustedXDiff;
151
+ if ((origin === 'left' && !flipX) || (origin === 'right' && flipX)) {
152
+ newWidth = Math.max(newWidth + adjustedXDiff, 10);
142
153
  const maxWidth = layer.image.width - offsetX;
143
154
  const maxWidthDiff = maxWidth * scale - newWidth;
144
155
  if (Math.abs(maxWidthDiff) < snapping) {
@@ -147,8 +158,8 @@
147
158
  newScale = newWidth / maxWidth;
148
159
  newOffsetY += ((layer.image.height / 2 - offsetY) * (newScale - scale)) / newScale;
149
160
  }
150
- } else if (origin === 'top') {
151
- newHeight += adjustedYDiff;
161
+ } else if ((origin === 'top' && !flipY) || (origin === 'bottom' && flipY)) {
162
+ newHeight = Math.max(newHeight + adjustedYDiff, 10);
152
163
  const maxHeight = layer.image.height - offsetY;
153
164
  const maxHeightDiff = maxHeight * scale - newHeight;
154
165
  if (Math.abs(maxHeightDiff) < snapping) {
@@ -157,9 +168,10 @@
157
168
  newScale = newHeight / maxHeight;
158
169
  newOffsetX += ((layer.image.width / 2 - offsetX) * (newScale - scale)) / newScale;
159
170
  }
160
- } else if (origin === 'right') {
161
- newWidth -= adjustedXDiff;
162
- newOffsetX += adjustedXDiff / scale;
171
+ } else if ((origin === 'right' && !flipX) || (origin === 'left' && flipX)) {
172
+ const adjustedDiff = Math.min(adjustedXDiff, newWidth - 10);
173
+ newWidth -= adjustedDiff;
174
+ newOffsetX += adjustedDiff / scale;
163
175
  if (Math.abs(newOffsetX * scale) < snapping) {
164
176
  newOffsetX = 0;
165
177
  newWidth = (width + offsetX) * scale;
@@ -168,9 +180,10 @@
168
180
  newScale = newWidth / (width + offsetX);
169
181
  newOffsetY += ((layer.image.height / 2 - offsetY) * (newScale - scale)) / newScale;
170
182
  }
171
- } else if (origin === 'bottom') {
172
- newHeight -= adjustedYDiff;
173
- newOffsetY += adjustedYDiff / scale;
183
+ } else if ((origin === 'bottom' && !flipY) || (origin === 'top' && flipY)) {
184
+ const adjustedDiff = Math.min(adjustedYDiff, newHeight - 10);
185
+ newHeight -= adjustedDiff;
186
+ newOffsetY += adjustedDiff / scale;
174
187
  if (Math.abs(newOffsetY * scale) < snapping) {
175
188
  newOffsetY = 0;
176
189
  newHeight = (height + offsetY) * scale;
@@ -180,8 +193,6 @@
180
193
  newOffsetX += ((layer.image.width / 2 - offsetX) * (newScale - scale)) / newScale;
181
194
  }
182
195
  }
183
- newWidth = Math.max(newWidth, 10);
184
- newHeight = Math.max(newHeight, 10);
185
196
 
186
197
  const { newX, newY } = calculateNewPosition(
187
198
  origin,
@@ -32,61 +32,7 @@ declare const sideResizeControlVariants: import("tailwind-variants").TVReturnTyp
32
32
  handler: string;
33
33
  grip: string;
34
34
  cursor: string;
35
- }, undefined, import("tailwind-variants/dist/config.js").TVConfig<{
36
- origin: {
37
- right: {
38
- base: string;
39
- handler: string;
40
- grip: string;
41
- cursor: string;
42
- };
43
- left: {
44
- base: string;
45
- handler: string;
46
- grip: string;
47
- cursor: string;
48
- };
49
- top: {
50
- base: string;
51
- handler: string;
52
- grip: string;
53
- cursor: string;
54
- };
55
- bottom: {
56
- base: string;
57
- handler: string;
58
- grip: string;
59
- cursor: string;
60
- };
61
- };
62
- }, {
63
- origin: {
64
- right: {
65
- base: string;
66
- handler: string;
67
- grip: string;
68
- cursor: string;
69
- };
70
- left: {
71
- base: string;
72
- handler: string;
73
- grip: string;
74
- cursor: string;
75
- };
76
- top: {
77
- base: string;
78
- handler: string;
79
- grip: string;
80
- cursor: string;
81
- };
82
- bottom: {
83
- base: string;
84
- handler: string;
85
- grip: string;
86
- cursor: string;
87
- };
88
- };
89
- }>, {
35
+ }, undefined, {
90
36
  origin: {
91
37
  right: {
92
38
  base: string;
@@ -150,61 +96,7 @@ declare const sideResizeControlVariants: import("tailwind-variants").TVReturnTyp
150
96
  handler: string;
151
97
  grip: string;
152
98
  cursor: string;
153
- }, undefined, import("tailwind-variants/dist/config.js").TVConfig<{
154
- origin: {
155
- right: {
156
- base: string;
157
- handler: string;
158
- grip: string;
159
- cursor: string;
160
- };
161
- left: {
162
- base: string;
163
- handler: string;
164
- grip: string;
165
- cursor: string;
166
- };
167
- top: {
168
- base: string;
169
- handler: string;
170
- grip: string;
171
- cursor: string;
172
- };
173
- bottom: {
174
- base: string;
175
- handler: string;
176
- grip: string;
177
- cursor: string;
178
- };
179
- };
180
- }, {
181
- origin: {
182
- right: {
183
- base: string;
184
- handler: string;
185
- grip: string;
186
- cursor: string;
187
- };
188
- left: {
189
- base: string;
190
- handler: string;
191
- grip: string;
192
- cursor: string;
193
- };
194
- top: {
195
- base: string;
196
- handler: string;
197
- grip: string;
198
- cursor: string;
199
- };
200
- bottom: {
201
- base: string;
202
- handler: string;
203
- grip: string;
204
- cursor: string;
205
- };
206
- };
207
- }>, unknown, unknown, undefined>>;
99
+ }, undefined, unknown, unknown, undefined>>;
208
100
  type Origin = VariantProps<typeof sideResizeControlVariants>['origin'];
209
101
  interface Props {
210
102
  origin: NonNullable<Origin>;
@@ -42,62 +42,74 @@
42
42
 
43
43
  const editor = getPresentationEditorContext();
44
44
 
45
+ let initial: { clientX: number; clientY: number; layer: HtmlLayer } | null = null;
45
46
  let isChanged = false;
47
+ const actionId = editor.generateId();
46
48
 
47
49
  const { base, handler, cursor } = sideScaleControlVariants({ origin });
48
50
 
49
51
  const onMouseDown = (e: MouseEvent) => {
52
+ if (e.button !== 0) return;
50
53
  e.preventDefault();
51
54
  e.stopPropagation();
52
55
  console.log(`${origin}-origin-scale`, 'mousedown', layer.id);
53
56
  isChanged = false;
54
- editor.activeAction = {
55
- type: `${origin}-origin-scale`,
56
- cursor: cursor(),
57
+ initial = {
57
58
  clientX: e.clientX,
58
59
  clientY: e.clientY,
59
60
  layer: { ...layer },
60
61
  };
62
+ editor.activeAction = {
63
+ id: actionId,
64
+ type: `${origin}-origin-scale`,
65
+ cursor: cursor(),
66
+ };
61
67
  addEventListener('mousemove', onMouseMove);
62
68
  addEventListener('mouseup', onMouseUp);
63
69
  };
64
70
 
65
- const onMouseUp = () => {
66
- console.log(`${origin}-origin-scale`, 'mouseup', layer.id);
67
- if (isChanged && editor.activeAction) {
68
- if (editor.checkIfLayerInBounds(layer)) {
69
- const undo = {
70
- x: editor.activeAction.layer.x,
71
- y: editor.activeAction.layer.y,
72
- width: editor.activeAction.layer.width,
73
- height: editor.activeAction.layer.height,
74
- };
75
- const redo = { x: layer.x, y: layer.y, width: layer.width, height: layer.height };
76
- editor.historyPush({
77
- type: 'layer',
78
- layer: { id: layer.id, type: layer.type },
79
- undo,
80
- redo,
81
- });
82
- }
83
- }
84
- editor.activeAction = null;
71
+ const onMouseUp = (e: MouseEvent) => {
72
+ console.log(`${origin}-origin-scale`, 'mouseup', layer.id, e);
85
73
  removeEventListener('mousemove', onMouseMove);
86
74
  removeEventListener('mouseup', onMouseUp);
75
+
76
+ if (editor.activeAction?.id !== actionId) return;
77
+ editor.activeAction = null;
78
+ if (!initial || !isChanged) return;
79
+
80
+ if (editor.isLayerOutOfBounds(layer)) {
81
+ editor.historyPush({
82
+ type: 'layersRemove',
83
+ slideId: editor.activeSlide.id,
84
+ layers: [initial.layer],
85
+ });
86
+ } else {
87
+ editor.historyPush({
88
+ type: 'layer',
89
+ slideId: editor.activeSlide.id,
90
+ layer: { id: layer.id, type: layer.type },
91
+ undo: {
92
+ x: initial.layer.x,
93
+ y: initial.layer.y,
94
+ width: initial.layer.width,
95
+ height: initial.layer.height,
96
+ },
97
+ redo: { x: layer.x, y: layer.y, width: layer.width, height: layer.height },
98
+ });
99
+ }
100
+ initial = null;
87
101
  };
88
102
 
89
103
  const onMouseMove = async (e: MouseEvent) => {
90
- if (!editor.activeAction) return;
104
+ if (!initial || editor.activeAction?.id !== actionId) return;
91
105
 
92
- isChanged = true;
93
- const { clientX, clientY } = editor.activeAction;
94
- const { width, height, x, y } = editor.activeAction.layer;
95
- const scale = editor.activeAction.layer.scale || 1;
96
- const rotate = editor.activeAction.layer.rotate || 0;
106
+ const { width, height, x, y } = initial.layer;
107
+ const scale = initial.layer.scale || 1;
108
+ const rotate = initial.layer.rotate || 0;
97
109
 
98
110
  const angle = (rotate * Math.PI) / 180;
99
- const xDiff = (e.clientX - clientX) / editor.zoom;
100
- const yDiff = (e.clientY - clientY) / editor.zoom;
111
+ const xDiff = (e.clientX - initial.clientX) / editor.zoom;
112
+ const yDiff = (e.clientY - initial.clientY) / editor.zoom;
101
113
  const adjustedXDiff = xDiff * Math.cos(angle) + yDiff * Math.sin(angle);
102
114
 
103
115
  let newWidth = width * scale;
@@ -107,6 +119,7 @@
107
119
  newWidth += adjustedXDiff;
108
120
  }
109
121
  newWidth = Math.max(newWidth, 10);
122
+ isChanged = newWidth !== width * scale;
110
123
 
111
124
  layer.width = newWidth / scale;
112
125
  await tick();
@@ -135,7 +148,7 @@
135
148
  <!-- svelte-ignore a11y_no_static_element_interactions -->
136
149
  <div class={cn(handler(), cursor())} onmousedown={onMouseDown}></div>
137
150
  <div
138
- class="h-4 w-1.5 rounded-sm bg-white transition-colors group-hover:bg-purple-500 group-active:bg-purple-500"
151
+ class="group-hover:bg-primary group-active:bg-primary h-4 w-1.5 rounded-sm bg-white transition-colors"
139
152
  style:box-shadow="0 0 4px 1px rgba(57,76,96,.15), 0 0 0 1px rgba(43,59,74,.3)"
140
153
  ></div>
141
154
  </div>