Adds stretch
This commit is contained in:
parent
f0afe62073
commit
e9d46a70e4
3 changed files with 65 additions and 26 deletions
|
@ -1,10 +1,8 @@
|
|||
import Command from "./command"
|
||||
import history from "../history"
|
||||
import { AlignType, Data, DistributeType } from "types"
|
||||
import * as vec from "utils/vec"
|
||||
import { Data, DistributeType } from "types"
|
||||
import {
|
||||
getBoundsCenter,
|
||||
getBoundsFromPoints,
|
||||
getCommonBounds,
|
||||
getPage,
|
||||
getSelectedShapes,
|
||||
|
@ -19,17 +17,11 @@ export default function distributeCommand(data: Data, type: DistributeType) {
|
|||
const entries = selectedShapes.map(
|
||||
(shape) => [shape.id, getShapeUtils(shape).getBounds(shape)] as const
|
||||
)
|
||||
|
||||
const boundsForShapes = Object.fromEntries(entries)
|
||||
|
||||
const commonBounds = getCommonBounds(...entries.map((entry) => entry[1]))
|
||||
|
||||
const innerBounds = getBoundsFromPoints(
|
||||
entries.map((entry) => getBoundsCenter(entry[1]))
|
||||
)
|
||||
|
||||
const midX = commonBounds.minX + commonBounds.width / 2
|
||||
const midY = commonBounds.minY + commonBounds.height / 2
|
||||
|
||||
const centers = Object.fromEntries(
|
||||
selectedShapes.map((shape) => [
|
||||
shape.id,
|
||||
|
@ -73,15 +65,15 @@ export default function distributeCommand(data: Data, type: DistributeType) {
|
|||
])
|
||||
}
|
||||
} else {
|
||||
const sortedByCenter = entries.sort(
|
||||
const entriesToMove = entries.sort(
|
||||
(a, b) => centers[a[0]][0] - centers[b[0]][0]
|
||||
)
|
||||
|
||||
let x = commonBounds.minX
|
||||
const step = (commonBounds.width - span) / (len - 1)
|
||||
|
||||
for (let i = 0; i < sortedByCenter.length - 1; i++) {
|
||||
const [id, bounds] = sortedByCenter[i]
|
||||
for (let i = 0; i < entriesToMove.length - 1; i++) {
|
||||
const [id, bounds] = entriesToMove[i]
|
||||
const shape = shapes[id]
|
||||
getShapeUtils(shape).translateTo(shape, [x, bounds.minY])
|
||||
x += bounds.width + step
|
||||
|
@ -115,15 +107,15 @@ export default function distributeCommand(data: Data, type: DistributeType) {
|
|||
])
|
||||
}
|
||||
} else {
|
||||
const sortedByCenter = entries.sort(
|
||||
const entriesToMove = entries.sort(
|
||||
(a, b) => centers[a[0]][1] - centers[b[0]][1]
|
||||
)
|
||||
|
||||
let y = commonBounds.minY
|
||||
const step = (commonBounds.height - span) / (len - 1)
|
||||
|
||||
for (let i = 0; i < sortedByCenter.length - 1; i++) {
|
||||
const [id, bounds] = sortedByCenter[i]
|
||||
for (let i = 0; i < entriesToMove.length - 1; i++) {
|
||||
const [id, bounds] = entriesToMove[i]
|
||||
const shape = shapes[id]
|
||||
getShapeUtils(shape).translateTo(shape, [bounds.minX, y])
|
||||
y += bounds.height + step
|
||||
|
|
|
@ -1,36 +1,82 @@
|
|||
import Command from "./command"
|
||||
import history from "../history"
|
||||
import { StretchType, Data } from "types"
|
||||
import { getPage } from "utils/utils"
|
||||
import { StretchType, Data, Edge, Corner } from "types"
|
||||
import { getCommonBounds, getPage, getSelectedShapes } from "utils/utils"
|
||||
import { getShapeUtils } from "lib/shape-utils"
|
||||
import { current } from "immer"
|
||||
|
||||
export default function stretchCommand(data: Data, type: StretchType) {
|
||||
const { currentPageId } = data
|
||||
|
||||
const initialPoints = Object.fromEntries(
|
||||
Object.entries(getPage(data).shapes).map(([id, shape]) => [id, shape.point])
|
||||
const initialShapes = getSelectedShapes(current(data))
|
||||
const entries = initialShapes.map(
|
||||
(shape) => [shape.id, getShapeUtils(shape).getBounds(shape)] as const
|
||||
)
|
||||
const boundsForShapes = Object.fromEntries(entries)
|
||||
const commonBounds = getCommonBounds(...entries.map((entry) => entry[1]))
|
||||
|
||||
history.execute(
|
||||
data,
|
||||
new Command({
|
||||
name: "distributed",
|
||||
name: "stretched",
|
||||
category: "canvas",
|
||||
do(data) {
|
||||
const { shapes } = getPage(data, currentPageId)
|
||||
|
||||
switch (type) {
|
||||
case StretchType.Horizontal: {
|
||||
for (let id in boundsForShapes) {
|
||||
const initialShape = initialShapes[id]
|
||||
const shape = shapes[id]
|
||||
const oldBounds = boundsForShapes[id]
|
||||
const newBounds = { ...oldBounds }
|
||||
newBounds.minX = commonBounds.minX
|
||||
newBounds.width = commonBounds.width
|
||||
newBounds.maxX = commonBounds.maxX
|
||||
|
||||
getShapeUtils(shape).transform(shape, newBounds, {
|
||||
type: Corner.TopLeft,
|
||||
scaleX: newBounds.width / oldBounds.width,
|
||||
scaleY: 1,
|
||||
initialShape,
|
||||
transformOrigin: [0.5, 0.5],
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
case StretchType.Vertical: {
|
||||
for (let id in boundsForShapes) {
|
||||
const initialShape = initialShapes[id]
|
||||
const shape = shapes[id]
|
||||
const oldBounds = boundsForShapes[id]
|
||||
const newBounds = { ...oldBounds }
|
||||
newBounds.minY = commonBounds.minY
|
||||
newBounds.height = commonBounds.height
|
||||
newBounds.maxY = commonBounds.maxY
|
||||
|
||||
getShapeUtils(shape).transform(shape, newBounds, {
|
||||
type: Corner.TopLeft,
|
||||
scaleX: 1,
|
||||
scaleY: newBounds.height / oldBounds.height,
|
||||
initialShape,
|
||||
transformOrigin: [0.5, 0.5],
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
undo(data) {
|
||||
const { shapes } = getPage(data, currentPageId)
|
||||
for (let id in initialPoints) {
|
||||
for (let id in boundsForShapes) {
|
||||
const shape = shapes[id]
|
||||
getShapeUtils(shape).translateTo(shape, initialPoints[id])
|
||||
const initialShape = initialShapes[id]
|
||||
const initialBounds = boundsForShapes[id]
|
||||
getShapeUtils(shape).transform(shape, initialBounds, {
|
||||
type: Corner.BottomRight,
|
||||
scaleX: 1,
|
||||
scaleY: 1,
|
||||
initialShape,
|
||||
transformOrigin: [0.5, 0.5],
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
|
@ -81,8 +81,6 @@ const state = createState({
|
|||
TOGGLED_STYLE_PANEL_OPEN: "toggleStylePanel",
|
||||
CHANGED_STYLE: ["updateStyles", "applyStylesToSelection"],
|
||||
RESET_CAMERA: "resetCamera",
|
||||
ALIGNED: "alignSelection",
|
||||
DISTRIBUTED: "distributeSelection",
|
||||
ZOOMED_TO_FIT: "zoomCameraToFit",
|
||||
ZOOMED_TO_SELECTION: {
|
||||
if: "hasSelection",
|
||||
|
@ -125,6 +123,9 @@ const state = createState({
|
|||
INCREASED_CODE_FONT_SIZE: "increaseCodeFontSize",
|
||||
DECREASED_CODE_FONT_SIZE: "decreaseCodeFontSize",
|
||||
CHANGED_CODE_CONTROL: "updateControls",
|
||||
ALIGNED: "alignSelection",
|
||||
STRETCHED: "stretchSelection",
|
||||
DISTRIBUTED: "distributeSelection",
|
||||
MOVED: "moveSelection",
|
||||
},
|
||||
initial: "notPointing",
|
||||
|
|
Loading…
Reference in a new issue