@peteai/presentation-editor 0.0.7 → 0.0.8

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 (40) hide show
  1. package/dist/components/editor/active-layers.svelte +22 -7
  2. package/dist/components/editor/active-layers.svelte.d.ts +6 -1
  3. package/dist/components/editor/editor.svelte +15 -17
  4. package/dist/components/editor/editor.svelte.js +10 -8
  5. package/dist/components/editor/header.svelte +24 -20
  6. package/dist/components/editor/hotkeys.svelte +7 -0
  7. package/dist/components/editor/layers/buttons/opacity-button/opacity-button.svelte +1 -6
  8. package/dist/components/editor/layers/controls/group-resize-control/group-resize-control.svelte +11 -11
  9. package/dist/components/editor/layers/controls/rotate-control/rotate-control.svelte +11 -5
  10. package/dist/components/editor/layers/controls/rotate-control/rotate-control.svelte.d.ts +4 -1
  11. package/dist/components/editor/layers/controls/side-resize-control/side-resize-control.svelte +13 -13
  12. package/dist/components/editor/layers/index.d.ts +2 -2
  13. package/dist/components/editor/layers/index.js +2 -2
  14. package/dist/components/editor/layers/types/background/background-content-image.svelte +15 -20
  15. package/dist/components/editor/layers/types/background/background-layer.svelte +2 -2
  16. package/dist/components/editor/layers/types/image/controls/image-rotate-control/image-rotate-control.svelte +120 -0
  17. package/dist/components/editor/layers/types/image/controls/image-rotate-control/image-rotate-control.svelte.d.ts +8 -0
  18. package/dist/components/editor/layers/types/image/controls/image-rotate-control/index.d.ts +2 -0
  19. package/dist/components/editor/layers/types/image/controls/image-rotate-control/index.js +4 -0
  20. package/dist/components/editor/layers/types/image/controls/image-scale-control/image-scale-control.svelte +154 -0
  21. package/dist/components/editor/layers/types/image/controls/image-scale-control/image-scale-control.svelte.d.ts +91 -0
  22. package/dist/components/editor/layers/types/image/controls/image-scale-control/index.d.ts +2 -0
  23. package/dist/components/editor/layers/types/image/controls/image-scale-control/index.js +4 -0
  24. package/dist/components/editor/layers/types/image/image-layer-content.svelte +3 -3
  25. package/dist/components/editor/layers/types/image/image-layer-crop.svelte +182 -0
  26. package/dist/components/editor/layers/types/image/image-layer-crop.svelte.d.ts +10 -0
  27. package/dist/components/editor/layers/types/image/image-layer.svelte +16 -0
  28. package/dist/components/editor/layers/types/image/index.d.ts +2 -1
  29. package/dist/components/editor/layers/types/image/index.js +2 -1
  30. package/dist/components/editor/layers/types/text/extensions/list-item/list-item.js +0 -2
  31. package/dist/components/editor/layers/utils.d.ts +24 -9
  32. package/dist/components/editor/layers/utils.js +107 -54
  33. package/dist/components/editor/page-editor.svelte +6 -2
  34. package/dist/components/editor/sidebar/image-crop-sidebar.svelte +112 -0
  35. package/dist/components/editor/sidebar/image-crop-sidebar.svelte.d.ts +7 -0
  36. package/dist/components/editor/sidebar/position-sidebar.svelte +0 -2
  37. package/dist/components/editor/sidebar/sidebar.svelte +6 -3
  38. package/dist/components/editor/types.d.ts +2 -1
  39. package/dist/components/editor/utils.js +1 -0
  40. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ import Root from './image-rotate-control.svelte';
2
+ export { Root, Root as ImageRotateControl, };
@@ -0,0 +1,4 @@
1
+ import Root from './image-rotate-control.svelte';
2
+ export { Root,
3
+ //
4
+ Root as ImageRotateControl, };
@@ -0,0 +1,154 @@
1
+ <script lang="ts" module>
2
+ import { tv, type VariantProps } from 'tailwind-variants';
3
+ import type { ImageLayer } from '../../../../../types.js';
4
+
5
+ const cornerScaleControlVariants = tv({
6
+ slots: {
7
+ base: 'group absolute w-8 h-8 flex items-center justify-center pointer-events-none',
8
+ handler: 'absolute w-4 h-4 pointer-events-auto',
9
+ cursor: '',
10
+ },
11
+ variants: {
12
+ origin: {
13
+ 'bottom-right': {
14
+ base: '-top-4 -left-4',
15
+ handler: '-translate-x-0.5 -translate-y-0.5 rounded-tl-full',
16
+ cursor: 'cursor-nwse-resize',
17
+ },
18
+ 'bottom-left': {
19
+ base: '-top-4 -right-4',
20
+ handler: 'translate-x-0.5 -translate-y-0.5 rounded-tr-full',
21
+ cursor: 'cursor-nesw-resize',
22
+ },
23
+ 'top-right': {
24
+ base: '-bottom-4 -left-4',
25
+ handler: '-translate-x-0.5 translate-y-0.5 rounded-bl-full',
26
+ cursor: 'cursor-nesw-resize',
27
+ },
28
+ 'top-left': {
29
+ base: '-bottom-4 -right-4',
30
+ handler: 'translate-x-0.5 translate-y-0.5 rounded-br-full',
31
+ cursor: 'cursor-nwse-resize',
32
+ },
33
+ },
34
+ },
35
+ });
36
+
37
+ type Variants = VariantProps<typeof cornerScaleControlVariants>;
38
+
39
+ interface Props extends Omit<Variants, 'origin'>, Required<Pick<Variants, 'origin'>> {
40
+ layer: ImageLayer;
41
+ }
42
+ </script>
43
+
44
+ <script lang="ts">
45
+ import { cn } from '../../../../../../../utils.js';
46
+ import {
47
+ getImageLayerBboxRelativeToImageCenter,
48
+ calculateNewPosition,
49
+ degToRad,
50
+ rotatePoint,
51
+ } from '../../../../utils.js';
52
+ import { getEditorContext } from '../../../../../editor.svelte.js';
53
+
54
+ let { origin, layer }: Props = $props();
55
+
56
+ const type = `${origin}-origin-scale`;
57
+
58
+ const editor = getEditorContext();
59
+
60
+ let initial: {
61
+ clientX: number;
62
+ clientY: number;
63
+ layer: ImageLayer;
64
+ minScaleFactor: number;
65
+ } | null = null;
66
+
67
+ const { base, handler, cursor } = cornerScaleControlVariants({ origin });
68
+
69
+ const onMouseDown = (e: MouseEvent) => {
70
+ if (e.button !== 0) return;
71
+ e.preventDefault();
72
+ e.stopPropagation();
73
+ console.log(type, 'mousedown', e);
74
+
75
+ const { minX, minY, maxX, maxY } = getImageLayerBboxRelativeToImageCenter(layer);
76
+
77
+ const minScaleFactor = Math.max(
78
+ ~origin.indexOf('left') ? 0.5 + maxX / layer.image.width : 0.5 - minX / layer.image.width,
79
+ ~origin.indexOf('top') ? 0.5 + maxY / layer.image.height : 0.5 - minY / layer.image.height,
80
+ );
81
+
82
+ initial = {
83
+ clientX: e.clientX,
84
+ clientY: e.clientY,
85
+ layer: $state.snapshot(layer),
86
+ minScaleFactor,
87
+ };
88
+ addEventListener('mousemove', onMouseMove);
89
+ addEventListener('mouseup', onMouseUp);
90
+ };
91
+
92
+ const onMouseUp = (e: MouseEvent) => {
93
+ console.log(type, 'mouseup', e);
94
+ removeEventListener('mousemove', onMouseMove);
95
+ removeEventListener('mouseup', onMouseUp);
96
+ initial = null;
97
+ };
98
+
99
+ const onMouseMove = (e: MouseEvent) => {
100
+ if (!initial) return;
101
+
102
+ const { x, y, width, height, scale, rotate, image, imageRotate, offsetX, offsetY } =
103
+ initial.layer;
104
+ const imageX = x + offsetX * scale;
105
+ const imageY = y + offsetY * scale;
106
+ const rad = degToRad(rotate + imageRotate);
107
+ const xDiff = (e.clientX - initial.clientX) / editor.zoom;
108
+ const yDiff = (e.clientY - initial.clientY) / editor.zoom;
109
+ const adjustedXDiff = xDiff * Math.cos(rad) + yDiff * Math.sin(rad);
110
+ const adjustedYDiff = -xDiff * Math.sin(rad) + yDiff * Math.cos(rad);
111
+
112
+ // Define the new x2 and y2 coordinates based on the variant (corner being dragged)
113
+ const x2 = imageX + image.width * scale + adjustedXDiff * (~origin.indexOf('left') ? 1 : -1);
114
+ const y2 = imageY + image.height * scale + adjustedYDiff * (~origin.indexOf('top') ? 1 : -1);
115
+
116
+ // Calculate the slope of the rectangle
117
+ const slope = image.height / image.width;
118
+
119
+ // Calculate the x-coordinate of the intersection point
120
+ const xIntersect = (y2 + x2 / slope - imageY + imageX * slope) / (slope + 1 / slope);
121
+
122
+ let scaleFactor = Math.max(
123
+ (xIntersect - imageX) / (image.width * scale),
124
+ initial.minScaleFactor,
125
+ );
126
+
127
+ if (scaleFactor > 0) {
128
+ const { newX, newY } = calculateNewPosition(
129
+ origin,
130
+ { ...image, x: offsetX, y: offsetY, rotate: imageRotate, scale: 1 },
131
+ image.width * scaleFactor,
132
+ image.height * scaleFactor,
133
+ );
134
+
135
+ const newProps = {
136
+ scale: scale * scaleFactor,
137
+ width: width / scaleFactor,
138
+ height: height / scaleFactor,
139
+ offsetX: newX / scaleFactor,
140
+ offsetY: newY / scaleFactor,
141
+ };
142
+ Object.assign(layer, newProps);
143
+ }
144
+ };
145
+ </script>
146
+
147
+ <div class={base()}>
148
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
149
+ <div class={cn(handler(), cursor())} onmousedown={onMouseDown}></div>
150
+ <div
151
+ class="group-hover:bg-primary group-active:bg-primary h-3 w-3 rounded-full bg-white transition-colors"
152
+ style:box-shadow="0 0 4px 1px rgba(57,76,96,.15), 0 0 0 1px rgba(43,59,74,.3)"
153
+ ></div>
154
+ </div>
@@ -0,0 +1,91 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ import type { ImageLayer } from '../../../../../types.js';
3
+ declare const cornerScaleControlVariants: import("tailwind-variants").TVReturnType<{
4
+ origin: {
5
+ 'bottom-right': {
6
+ base: string;
7
+ handler: string;
8
+ cursor: string;
9
+ };
10
+ 'bottom-left': {
11
+ base: string;
12
+ handler: string;
13
+ cursor: string;
14
+ };
15
+ 'top-right': {
16
+ base: string;
17
+ handler: string;
18
+ cursor: string;
19
+ };
20
+ 'top-left': {
21
+ base: string;
22
+ handler: string;
23
+ cursor: string;
24
+ };
25
+ };
26
+ }, {
27
+ base: string;
28
+ handler: string;
29
+ cursor: string;
30
+ }, undefined, {
31
+ origin: {
32
+ 'bottom-right': {
33
+ base: string;
34
+ handler: string;
35
+ cursor: string;
36
+ };
37
+ 'bottom-left': {
38
+ base: string;
39
+ handler: string;
40
+ cursor: string;
41
+ };
42
+ 'top-right': {
43
+ base: string;
44
+ handler: string;
45
+ cursor: string;
46
+ };
47
+ 'top-left': {
48
+ base: string;
49
+ handler: string;
50
+ cursor: string;
51
+ };
52
+ };
53
+ }, {
54
+ base: string;
55
+ handler: string;
56
+ cursor: string;
57
+ }, import("tailwind-variants").TVReturnType<{
58
+ origin: {
59
+ 'bottom-right': {
60
+ base: string;
61
+ handler: string;
62
+ cursor: string;
63
+ };
64
+ 'bottom-left': {
65
+ base: string;
66
+ handler: string;
67
+ cursor: string;
68
+ };
69
+ 'top-right': {
70
+ base: string;
71
+ handler: string;
72
+ cursor: string;
73
+ };
74
+ 'top-left': {
75
+ base: string;
76
+ handler: string;
77
+ cursor: string;
78
+ };
79
+ };
80
+ }, {
81
+ base: string;
82
+ handler: string;
83
+ cursor: string;
84
+ }, undefined, unknown, unknown, undefined>>;
85
+ type Variants = VariantProps<typeof cornerScaleControlVariants>;
86
+ interface Props extends Omit<Variants, 'origin'>, Required<Pick<Variants, 'origin'>> {
87
+ layer: ImageLayer;
88
+ }
89
+ declare const ImageScaleControl: import("svelte").Component<Props, {}, "">;
90
+ type ImageScaleControl = ReturnType<typeof ImageScaleControl>;
91
+ export default ImageScaleControl;
@@ -0,0 +1,2 @@
1
+ import Root from './image-scale-control.svelte';
2
+ export { Root, Root as ImageScaleControl, };
@@ -0,0 +1,4 @@
1
+ import Root from './image-scale-control.svelte';
2
+ export { Root,
3
+ //
4
+ Root as ImageScaleControl, };
@@ -32,7 +32,7 @@
32
32
  layer.flipX || layer.flipY ? `scale(${layer.flipX ? -1 : 1}, ${layer.flipY ? -1 : 1})` : null,
33
33
  );
34
34
 
35
- let cornderRadius = $derived(layer.cornerRadius * thumbScale);
35
+ let cornderRadius = $derived(Math.min(layer.cornerRadius * thumbScale, width / 2, height / 2));
36
36
 
37
37
  const bezier = 0.447715;
38
38
  let roundedClipPath = $derived(
@@ -51,7 +51,7 @@
51
51
  class="relative"
52
52
  style:width="{layer.image.width * scale}px"
53
53
  style:height="{layer.image.height * scale}px"
54
- style:transform={`translate(${-layer.offsetX * scale}px, ${-layer.offsetY * scale}px)`}
54
+ style:transform={`translate(${layer.offsetX * scale}px, ${layer.offsetY * scale}px) rotate(${layer.imageRotate}deg)`}
55
55
  >
56
56
  {#if imageLoaded}
57
57
  <img
@@ -85,7 +85,7 @@
85
85
  <ColorIndicatorGradientDef id={gradientId} color={borderColor} {width} {height} />
86
86
  {/if}
87
87
  <clipPath id={layerBorderId}>
88
- <path d={path}></path>
88
+ <path d={roundedClipPath || path}></path>
89
89
  </clipPath>
90
90
  </defs>
91
91
  <path
@@ -0,0 +1,182 @@
1
+ <script lang="ts">
2
+ import { onMount } from 'svelte';
3
+ import type { ImageLayer } from '../../../types.js';
4
+ import { getEditorContext } from '../../../editor.svelte.js';
5
+ import ImageLayerContent from './image-layer-content.svelte';
6
+ import { ImageScaleControl } from './controls/image-scale-control/index.js';
7
+ import { ImageRotateControl } from './controls/image-rotate-control/index.js';
8
+ import { getImageLayerBboxRelativeToImageCenter, degToRad, rotatePoint } from '../../utils.js';
9
+
10
+ interface Props {
11
+ layer: ImageLayer;
12
+ viewportRef: HTMLDivElement;
13
+ wrapperRef: HTMLDivElement;
14
+ pageRef: HTMLDivElement;
15
+ }
16
+
17
+ const { layer, viewportRef, wrapperRef, pageRef }: Props = $props();
18
+
19
+ const editor = getEditorContext();
20
+
21
+ let overlayRef: HTMLDivElement | null = $state(null);
22
+
23
+ let imageTransform = $derived.by(() => {
24
+ const rad = degToRad(layer.rotate);
25
+
26
+ const layerCenter = {
27
+ x: layer.x + (layer.width * layer.scale) / 2,
28
+ y: layer.y + (layer.height * layer.scale) / 2,
29
+ };
30
+
31
+ const relativeCenter = {
32
+ x: layer.x + (layer.offsetX + layer.image.width / 2) * layer.scale,
33
+ y: layer.y + (layer.offsetY + layer.image.height / 2) * layer.scale,
34
+ };
35
+
36
+ const center = rotatePoint(rad, relativeCenter, layerCenter);
37
+
38
+ return {
39
+ x: center.x - (layer.image.width * layer.scale) / 2,
40
+ y: center.y - (layer.image.height * layer.scale) / 2,
41
+ width: layer.image.width,
42
+ height: layer.image.height,
43
+ rotate: layer.imageRotate + layer.rotate,
44
+ scale: layer.scale,
45
+ };
46
+ });
47
+
48
+ const updateOverlay = () => {
49
+ if (overlayRef) {
50
+ const viewportRect = viewportRef.getBoundingClientRect();
51
+ const wrapperRect = wrapperRef.getBoundingClientRect();
52
+ const pageRect = pageRef.getBoundingClientRect();
53
+
54
+ overlayRef.style.left = `${viewportRect.left - viewportRef.scrollLeft - pageRect.left}px`;
55
+ overlayRef.style.top = `${viewportRect.top - viewportRef.scrollTop - pageRect.top}px`;
56
+ overlayRef.style.width = `${wrapperRect.width > viewportRect.width ? wrapperRect.width : viewportRect.width}px`;
57
+ overlayRef.style.height = `${wrapperRect.height > viewportRect.height ? wrapperRect.height : viewportRect.height}px`;
58
+ }
59
+ };
60
+
61
+ $effect(() => {
62
+ editor.zoom;
63
+ updateOverlay();
64
+ });
65
+
66
+ onMount(() => {
67
+ const observer = new ResizeObserver(updateOverlay);
68
+
69
+ if (viewportRef) observer.observe(viewportRef);
70
+
71
+ return () => observer.disconnect();
72
+ });
73
+
74
+ let initial: {
75
+ clientX: number;
76
+ clientY: number;
77
+ layer: ImageLayer;
78
+ minImageXDiff: number;
79
+ minImageYDiff: number;
80
+ maxImageXDiff: number;
81
+ maxImageYDiff: number;
82
+ } | null = null;
83
+
84
+ const onMouseDown = (e: MouseEvent) => {
85
+ e.preventDefault();
86
+ e.stopPropagation();
87
+
88
+ const { minX, minY, maxX, maxY } = getImageLayerBboxRelativeToImageCenter(layer);
89
+
90
+ initial = {
91
+ clientX: e.clientX,
92
+ clientY: e.clientY,
93
+ layer: $state.snapshot(layer),
94
+ minImageXDiff: maxX - layer.image.width / 2,
95
+ minImageYDiff: maxY - layer.image.height / 2,
96
+ maxImageXDiff: layer.image.width / 2 + minX,
97
+ maxImageYDiff: layer.image.height / 2 + minY,
98
+ };
99
+ addEventListener('mousemove', onMouseMove);
100
+ addEventListener('mouseup', onMouseUp);
101
+ };
102
+
103
+ const onMouseUp = (e: MouseEvent) => {
104
+ removeEventListener('mousemove', onMouseMove);
105
+ removeEventListener('mouseup', onMouseUp);
106
+ initial = null;
107
+ };
108
+
109
+ const onMouseMove = (e: MouseEvent) => {
110
+ if (!initial) return;
111
+ const { scale, rotate, imageRotate, offsetX, offsetY } = initial.layer;
112
+
113
+ const xDiff = (e.clientX - initial.clientX) / scale / editor.zoom;
114
+ const yDiff = (e.clientY - initial.clientY) / scale / editor.zoom;
115
+
116
+ const imageRad = degToRad(rotate + imageRotate);
117
+
118
+ const imageXDiff2 = Math.min(
119
+ Math.max(xDiff * Math.cos(imageRad) + yDiff * Math.sin(imageRad), initial.minImageXDiff),
120
+ initial.maxImageXDiff,
121
+ );
122
+ const imageYDiff2 = Math.min(
123
+ Math.max(-xDiff * Math.sin(imageRad) + yDiff * Math.cos(imageRad), initial.minImageYDiff),
124
+ initial.maxImageYDiff,
125
+ );
126
+
127
+ const rad = degToRad(-imageRotate);
128
+
129
+ const adjustedXDiff = imageXDiff2 * Math.cos(rad) + imageYDiff2 * Math.sin(rad);
130
+ const adjustedYDiff = -imageXDiff2 * Math.sin(rad) + imageYDiff2 * Math.cos(rad);
131
+
132
+ Object.assign(layer, {
133
+ offsetX: offsetX + adjustedXDiff,
134
+ offsetY: offsetY + adjustedYDiff,
135
+ });
136
+ };
137
+ </script>
138
+
139
+ <div class="select-none">
140
+ <div bind:this={overlayRef} class="absolute bg-slate-500/50"></div>
141
+ <div
142
+ class="absolute opacity-50"
143
+ style:width={`${layer.image.width * layer.scale * editor.zoom}px`}
144
+ style:height={`${layer.image.height * layer.scale * editor.zoom}px`}
145
+ style:transform={`translate(${imageTransform.x * editor.zoom}px, ${imageTransform.y * editor.zoom}px) rotate(${imageTransform.rotate}deg)`}
146
+ >
147
+ <img class="pointer-events-none h-full w-full" src={layer.image.src} alt="" />
148
+ </div>
149
+ <div
150
+ class="absolute overflow-hidden"
151
+ style:width={`${layer.width * layer.scale * editor.zoom}px`}
152
+ style:height={`${layer.height * layer.scale * editor.zoom}px`}
153
+ style:transform={`translate(${layer.x * editor.zoom}px, ${layer.y * editor.zoom}px) rotate(${layer.rotate}deg)`}
154
+ >
155
+ <ImageLayerContent {layer} thumbScale={editor.zoom} />
156
+ </div>
157
+ <div class="pointer-events-auto">
158
+ <div
159
+ class="shadow-inner-1 outline-primary/50 pointer-events-none absolute outline outline-2"
160
+ style:width={`${layer.image.width * layer.scale * editor.zoom}px`}
161
+ style:height={`${layer.image.height * layer.scale * editor.zoom}px`}
162
+ style:transform={`translate(${imageTransform.x * editor.zoom}px, ${imageTransform.y * editor.zoom}px) rotate(${imageTransform.rotate}deg)`}
163
+ >
164
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
165
+ <div
166
+ class="pointer-events-auto absolute -inset-3 cursor-move"
167
+ onmousedown={onMouseDown}
168
+ ></div>
169
+ <ImageScaleControl origin="bottom-right" {layer} />
170
+ <ImageScaleControl origin="bottom-left" {layer} />
171
+ <ImageScaleControl origin="top-right" {layer} />
172
+ <ImageScaleControl origin="top-left" {layer} />
173
+ <ImageRotateControl {pageRef} {layer} />
174
+ </div>
175
+ <div
176
+ class="outline-primary pointer-events-none absolute outline outline-2"
177
+ style:width={`${layer.width * layer.scale * editor.zoom}px`}
178
+ style:height={`${layer.height * layer.scale * editor.zoom}px`}
179
+ style:transform={`translate(${layer.x * editor.zoom}px, ${layer.y * editor.zoom}px) rotate(${layer.rotate}deg)`}
180
+ ></div>
181
+ </div>
182
+ </div>
@@ -0,0 +1,10 @@
1
+ import type { ImageLayer } from '../../../types.js';
2
+ interface Props {
3
+ layer: ImageLayer;
4
+ viewportRef: HTMLDivElement;
5
+ wrapperRef: HTMLDivElement;
6
+ pageRef: HTMLDivElement;
7
+ }
8
+ declare const ImageLayerCrop: import("svelte").Component<Props, {}, "">;
9
+ type ImageLayerCrop = ReturnType<typeof ImageLayerCrop>;
10
+ export default ImageLayerCrop;
@@ -12,6 +12,8 @@
12
12
 
13
13
  const editor = getEditorContext();
14
14
 
15
+ let isCropping = $derived(editor.imageCropLayer?.id === layer.id);
16
+
15
17
  let layerSubstitute: ImageLayer | null = $state(null);
16
18
 
17
19
  let ref: HTMLDivElement;
@@ -19,6 +21,7 @@
19
21
  const buildImageDropChanges = (image: Image) => {
20
22
  return {
21
23
  image,
24
+ imageRotate: 0,
22
25
  ...calculateImageCover(image, {
23
26
  width: layer.width * layer.scale,
24
27
  height: layer.height * layer.scale,
@@ -89,12 +92,25 @@
89
92
  }
90
93
  layerSubstitute = null;
91
94
  };
95
+
96
+ const onDoubleClick = () => {
97
+ if (editor.activeLayers.length > 1) return;
98
+ editor.imageCropLayer = $state.snapshot(
99
+ editor.activeGroupAndChild
100
+ ? (editor.getAbsoluteGroupLayers(editor.activeGroupAndChild.groupLayer, [
101
+ layer,
102
+ ])[0] as ImageLayer)
103
+ : layer,
104
+ );
105
+ };
92
106
  </script>
93
107
 
94
108
  <!-- svelte-ignore a11y_no_static_element_interactions -->
95
109
  <div
96
110
  bind:this={ref}
97
111
  class="h-full w-full"
112
+ style:opacity={isCropping ? 0 : null}
113
+ ondblclick={onDoubleClick}
98
114
  ondragenter={onDragEnter}
99
115
  ondragover={onDragOver}
100
116
  ondragleave={onDragLeave}
@@ -1,3 +1,4 @@
1
1
  import Root from './image-layer.svelte';
2
2
  import ImageLayerContent from './image-layer-content.svelte';
3
- export { Root, Root as ImageLayer, ImageLayerContent };
3
+ import ImageLayerCrop from './image-layer-crop.svelte';
4
+ export { Root, Root as ImageLayer, ImageLayerContent, ImageLayerCrop };
@@ -1,3 +1,4 @@
1
1
  import Root from './image-layer.svelte';
2
2
  import ImageLayerContent from './image-layer-content.svelte';
3
- export { Root, Root as ImageLayer, ImageLayerContent };
3
+ import ImageLayerCrop from './image-layer-crop.svelte';
4
+ export { Root, Root as ImageLayer, ImageLayerContent, ImageLayerCrop };
@@ -28,7 +28,6 @@ export const ListItem = TiptapNode.create({
28
28
  addCommands() {
29
29
  return {
30
30
  splitListItem: (typeOrName, overrideAttrs) => ({ editor, tr, state, dispatch }) => {
31
- console.log('splitListItem overwritten');
32
31
  const type = getNodeType(typeOrName, state.schema);
33
32
  const { $from, $to } = state.selection;
34
33
  // @ts-ignore
@@ -160,7 +159,6 @@ export const ListItem = TiptapNode.create({
160
159
  // Check if selection is in first list item
161
160
  const firstListItem = findParentNodeClosestToPos(tr.selection.$from, (node) => node.type.name === this.name);
162
161
  if (firstListItem && newParentList.node.firstChild === firstListItem.node) {
163
- console.log('firstListItem', firstListItem);
164
162
  const attrs = {
165
163
  ...newParentList.node.attrs,
166
164
  ...oldParentList.node.attrs,
@@ -12,13 +12,6 @@ export type Transform = {
12
12
  rotate: number;
13
13
  scale: number;
14
14
  };
15
- export declare const rotatePointOld: (point: {
16
- x: number;
17
- y: number;
18
- }, angleRad: number) => {
19
- x: number;
20
- y: number;
21
- };
22
15
  export declare const calculateLayerTransform: (layer: Layer, groupScale?: number) => Transform;
23
16
  export declare const calculateNewPosition: (origin: Origin, transform: Transform, newWidth: number, newHeight: number) => {
24
17
  newX: number;
@@ -31,7 +24,7 @@ export declare function calculateBoundingBox(transform: Transform): {
31
24
  height: number;
32
25
  };
33
26
  export declare function degToRad(deg: number): number;
34
- export declare function rotatePoint(p: Point, origin: Point, angleRad: number): Point;
27
+ export declare function rotatePoint(rad: number, p: Point, center?: Point): Point;
35
28
  export declare function getRotatedCorners(rect: Transform): Point[];
36
29
  export declare function isRotatedVertically(rotate: number): boolean;
37
30
  interface ScaleResult {
@@ -51,9 +44,9 @@ export declare function calculateRelativeRects(bbox: Transform, absoluteRects: T
51
44
  x: number;
52
45
  y: number;
53
46
  rotate: number;
47
+ scale: number;
54
48
  width: number;
55
49
  height: number;
56
- scale: number;
57
50
  }[];
58
51
  export declare function calculateAbsoluteRects(bbox: Transform, rects: Transform[]): Transform[];
59
52
  export declare const checkPolygonsIntersect: (a: {
@@ -68,6 +61,7 @@ export declare function calculateImageCover(image: {
68
61
  width: number;
69
62
  height: number;
70
63
  rotate?: number | null;
64
+ imageRotate?: number | null;
71
65
  }, bbox: {
72
66
  width: number;
73
67
  height: number;
@@ -81,4 +75,25 @@ export declare function calculateImageCover(image: {
81
75
  export declare const defaultColor = "#000000";
82
76
  export declare function extractBorderColors(layers: ImageLayer[]): string[] | undefined;
83
77
  export declare function buildBackgroundCircleStyle(colors: string[]): string;
78
+ export declare function getImageLayerBboxRelativeToImageCenter(layer: ImageLayer): {
79
+ minX: number;
80
+ minY: number;
81
+ maxX: number;
82
+ maxY: number;
83
+ };
84
+ export declare function calculateImageLayerPropsForImageRotate(layer: ImageLayer, imageRotate: number): {
85
+ imageRotate: number;
86
+ scale?: undefined;
87
+ width?: undefined;
88
+ height?: undefined;
89
+ offsetX?: undefined;
90
+ offsetY?: undefined;
91
+ } | {
92
+ imageRotate: number;
93
+ scale: number;
94
+ width: number;
95
+ height: number;
96
+ offsetX: number;
97
+ offsetY: number;
98
+ };
84
99
  export {};