浏览代码

Transforming rotated items

main
Steve Ruiz 4 年前
父节点
当前提交
da8f812090
共有 5 个文件被更改,包括 91 次插入14 次删除
  1. 2
    0
      lib/shapes/ellipse.tsx
  2. 2
    0
      lib/shapes/index.tsx
  3. 38
    3
      lib/shapes/rectangle.tsx
  4. 8
    0
      state/commands/transform.ts
  5. 41
    11
      state/sessions/transform-session.ts

+ 2
- 0
lib/shapes/ellipse.tsx 查看文件

73
   },
73
   },
74
 
74
 
75
   hitTestBounds(this, shape, brushBounds) {
75
   hitTestBounds(this, shape, brushBounds) {
76
+    // TODO: Account for rotation
77
+
76
     const shapeBounds = this.getBounds(shape)
78
     const shapeBounds = this.getBounds(shape)
77
 
79
 
78
     return (
80
     return (

+ 2
- 0
lib/shapes/index.tsx 查看文件

61
     bounds: Bounds,
61
     bounds: Bounds,
62
     info: {
62
     info: {
63
       type: TransformEdge | TransformCorner
63
       type: TransformEdge | TransformCorner
64
+      boundsRotation: number
64
       initialShape: K
65
       initialShape: K
65
       initialShapeBounds: BoundsSnapshot
66
       initialShapeBounds: BoundsSnapshot
66
       initialBounds: Bounds
67
       initialBounds: Bounds
67
       isFlippedX: boolean
68
       isFlippedX: boolean
68
       isFlippedY: boolean
69
       isFlippedY: boolean
70
+      isSingle: boolean
69
       anchor: TransformEdge | TransformCorner
71
       anchor: TransformEdge | TransformCorner
70
     }
72
     }
71
   ): K
73
   ): K

+ 38
- 3
lib/shapes/rectangle.tsx 查看文件

103
     return shape
103
     return shape
104
   },
104
   },
105
 
105
 
106
-  transform(shape, bounds) {
107
-    shape.point = [bounds.minX, bounds.minY]
108
-    shape.size = [bounds.width, bounds.height]
106
+  transform(
107
+    shape,
108
+    shapeBounds,
109
+    { initialShape, isSingle, initialShapeBounds, isFlippedX, isFlippedY }
110
+  ) {
111
+    // TODO: Apply rotation to single-selection items
112
+
113
+    if (shape.rotation === 0 || isSingle) {
114
+      shape.size = [shapeBounds.width, shapeBounds.height]
115
+      shape.point = [shapeBounds.minX, shapeBounds.minY]
116
+    } else {
117
+      shape.size = vec.mul(
118
+        initialShape.size,
119
+        Math.min(
120
+          shapeBounds.width / initialShapeBounds.width,
121
+          shapeBounds.height / initialShapeBounds.height
122
+        )
123
+      )
124
+
125
+      const newCenter = [
126
+        shapeBounds.minX + shapeBounds.width / 2,
127
+        shapeBounds.minY + shapeBounds.height / 2,
128
+      ]
129
+
130
+      shape.point = vec.sub(newCenter, vec.div(shape.size, 2))
131
+    }
132
+
133
+    // Rotation for flipped shapes
134
+
135
+    shape.rotation = initialShape.rotation
136
+
137
+    if (isFlippedX) {
138
+      shape.rotation *= -1
139
+    }
140
+
141
+    if (isFlippedY) {
142
+      shape.rotation *= -1
143
+    }
109
 
144
 
110
     return shape
145
     return shape
111
   },
146
   },

+ 8
- 0
state/commands/transform.ts 查看文件

22
           initialBounds,
22
           initialBounds,
23
           currentPageId,
23
           currentPageId,
24
           selectedIds,
24
           selectedIds,
25
+          isSingle,
26
+          boundsRotation,
25
         } = after
27
         } = after
26
 
28
 
27
         const { shapes } = data.document.pages[currentPageId]
29
         const { shapes } = data.document.pages[currentPageId]
35
             initialShape,
37
             initialShape,
36
             initialShapeBounds,
38
             initialShapeBounds,
37
             initialBounds,
39
             initialBounds,
40
+            boundsRotation,
38
             isFlippedX: false,
41
             isFlippedX: false,
39
             isFlippedY: false,
42
             isFlippedY: false,
43
+            isSingle,
40
             anchor,
44
             anchor,
41
           })
45
           })
42
         })
46
         })
48
           initialBounds,
52
           initialBounds,
49
           currentPageId,
53
           currentPageId,
50
           selectedIds,
54
           selectedIds,
55
+          isSingle,
56
+          boundsRotation,
51
         } = before
57
         } = before
52
 
58
 
53
         const { shapes } = data.document.pages[currentPageId]
59
         const { shapes } = data.document.pages[currentPageId]
61
             initialShape,
67
             initialShape,
62
             initialShapeBounds,
68
             initialShapeBounds,
63
             initialBounds,
69
             initialBounds,
70
+            boundsRotation,
64
             isFlippedX: false,
71
             isFlippedX: false,
65
             isFlippedY: false,
72
             isFlippedY: false,
73
+            isSingle,
66
             anchor: type,
74
             anchor: type,
67
           })
75
           })
68
         })
76
         })

+ 41
- 11
state/sessions/transform-session.ts 查看文件

32
     super(data)
32
     super(data)
33
     this.origin = point
33
     this.origin = point
34
     this.transformType = transformType
34
     this.transformType = transformType
35
+
36
+    // if (data.selectedIds.size === 1) {
37
+    //   const shape =
38
+    //     data.document.pages[data.currentPageId].shapes[
39
+    //       Array.from(data.selectedIds.values())[0]
40
+    //     ]
41
+
42
+    //   if (shape.rotation > 0) {
43
+
44
+    //   }
45
+    // }
46
+
35
     this.snapshot = getTransformSnapshot(data, transformType)
47
     this.snapshot = getTransformSnapshot(data, transformType)
36
 
48
 
37
     const { minX, minY, maxX, maxY } = this.snapshot.initialBounds
49
     const { minX, minY, maxX, maxY } = this.snapshot.initialBounds
43
   }
55
   }
44
 
56
 
45
   update(data: Data, point: number[]) {
57
   update(data: Data, point: number[]) {
46
-    const { shapeBounds, initialBounds, currentPageId, selectedIds } =
47
-      this.snapshot
48
-
49
-    const { shapes } = data.document.pages[currentPageId]
50
-
51
-    const delta = vec.vec(this.origin, point)
52
-
53
     const {
58
     const {
54
       corners: { a, b },
59
       corners: { a, b },
55
       transformType,
60
       transformType,
56
     } = this
61
     } = this
57
 
62
 
58
-    // Edge Transform
63
+    const {
64
+      boundsRotation,
65
+      shapeBounds,
66
+      initialBounds,
67
+      currentPageId,
68
+      selectedIds,
69
+      isSingle,
70
+    } = this.snapshot
71
+
72
+    const { shapes } = data.document.pages[currentPageId]
73
+
74
+    const delta = vec.vec(this.origin, point)
75
+
59
     /*
76
     /*
60
-    Edge transform
77
+    Transforms
61
     
78
     
62
     Corners a and b are the original top-left and bottom-right corners of the
79
     Corners a and b are the original top-left and bottom-right corners of the
63
     bounding box. Depending on what the user is dragging, change one or both
80
     bounding box. Depending on what the user is dragging, change one or both
153
         initialShape,
170
         initialShape,
154
         initialShapeBounds,
171
         initialShapeBounds,
155
         initialBounds,
172
         initialBounds,
173
+        boundsRotation,
156
         isFlippedX: this.isFlippedX,
174
         isFlippedX: this.isFlippedX,
157
         isFlippedY: this.isFlippedY,
175
         isFlippedY: this.isFlippedY,
176
+        isSingle,
158
         anchor: getTransformAnchor(
177
         anchor: getTransformAnchor(
159
           this.transformType,
178
           this.transformType,
160
           this.isFlippedX,
179
           this.isFlippedX,
165
   }
184
   }
166
 
185
 
167
   cancel(data: Data) {
186
   cancel(data: Data) {
168
-    const { shapeBounds, initialBounds, currentPageId, selectedIds } =
169
-      this.snapshot
187
+    const {
188
+      shapeBounds,
189
+      boundsRotation,
190
+      initialBounds,
191
+      currentPageId,
192
+      selectedIds,
193
+      isSingle,
194
+    } = this.snapshot
170
 
195
 
171
     const { shapes } = data.document.pages[currentPageId]
196
     const { shapes } = data.document.pages[currentPageId]
172
 
197
 
180
         initialShape,
205
         initialShape,
181
         initialShapeBounds,
206
         initialShapeBounds,
182
         initialBounds,
207
         initialBounds,
208
+        boundsRotation,
183
         isFlippedX: false,
209
         isFlippedX: false,
184
         isFlippedY: false,
210
         isFlippedY: false,
211
+        isSingle,
185
         anchor: getTransformAnchor(this.transformType, false, false),
212
         anchor: getTransformAnchor(this.transformType, false, false),
186
       })
213
       })
187
     })
214
     })
205
     document: { pages },
232
     document: { pages },
206
     selectedIds,
233
     selectedIds,
207
     currentPageId,
234
     currentPageId,
235
+    boundsRotation,
208
   } = current(data)
236
   } = current(data)
209
 
237
 
210
   const pageShapes = pages[currentPageId].shapes
238
   const pageShapes = pages[currentPageId].shapes
226
     currentPageId,
254
     currentPageId,
227
     type: transformType,
255
     type: transformType,
228
     initialBounds: bounds,
256
     initialBounds: bounds,
257
+    boundsRotation,
258
+    isSingle: selectedIds.size === 1,
229
     selectedIds: new Set(selectedIds),
259
     selectedIds: new Set(selectedIds),
230
     shapeBounds: Object.fromEntries(
260
     shapeBounds: Object.fromEntries(
231
       Array.from(selectedIds.values()).map((id) => {
261
       Array.from(selectedIds.values()).map((id) => {

正在加载...
取消
保存