Remove crop tool
This commit is contained in:
@@ -6,8 +6,8 @@ const defaultBrush = { color: "#111827", size: 8, hardness: 100 };
|
|||||||
|
|
||||||
describe("tool commands", () => {
|
describe("tool commands", () => {
|
||||||
test("sets active tool", () => {
|
test("sets active tool", () => {
|
||||||
const next = toolSetActiveCommand.execute({ state: createInitialAppState("Test") }, { tool: "crop" });
|
const next = toolSetActiveCommand.execute({ state: createInitialAppState("Test") }, { tool: "brush" });
|
||||||
expect(next.editor.tools).toEqual({ activeTool: "crop", interactionMode: { type: "tool", tool: "crop" }, brush: defaultBrush });
|
expect(next.editor.tools).toEqual({ activeTool: "brush", interactionMode: { type: "tool", tool: "brush" }, brush: defaultBrush });
|
||||||
});
|
});
|
||||||
|
|
||||||
test("sets brush settings", () => {
|
test("sets brush settings", () => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export const availableToolIds = ["select", "crop", "brush", "eraser", "pan"] as const;
|
export const availableToolIds = ["select", "brush", "eraser", "pan"] as const;
|
||||||
|
|
||||||
export type ToolId = (typeof availableToolIds)[number];
|
export type ToolId = (typeof availableToolIds)[number];
|
||||||
|
|
||||||
|
|||||||
@@ -39,25 +39,6 @@ describe("transform controls input", () => {
|
|||||||
expect(dispatched).toEqual([]);
|
expect(dispatched).toEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("crop tool resizes from handles but does not move body", () => {
|
|
||||||
const state = createState({
|
|
||||||
selection: { artboardId: "a1", layerIds: [] },
|
|
||||||
tools: { activeTool: "crop", interactionMode: { type: "tool", tool: "crop" } },
|
|
||||||
});
|
|
||||||
const dispatched: unknown[] = [];
|
|
||||||
const controller = createTransformControlsInputController({
|
|
||||||
getDocument: () => state.document,
|
|
||||||
getEditor: () => state.editor,
|
|
||||||
dispatch: (commandId, payload) => {
|
|
||||||
dispatched.push({ commandId, payload });
|
|
||||||
return ignoredState;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(controller.pointerDown(pointerEvent({ position: { x: 100, y: 100 }, buttons: 1 }))).toBe(false);
|
|
||||||
expect(controller.pointerDown(pointerEvent({ position: { x: 150, y: 150 }, buttons: 1 }))).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("dispatches transform lifecycle for selected artboard", () => {
|
test("dispatches transform lifecycle for selected artboard", () => {
|
||||||
let state = createState({ selection: { artboardId: "a1", layerIds: [] } });
|
let state = createState({ selection: { artboardId: "a1", layerIds: [] } });
|
||||||
const dispatched: unknown[] = [];
|
const dispatched: unknown[] = [];
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import type { PointerInputEvent } from "./pointer";
|
|||||||
|
|
||||||
type TransformHandle = "body" | "nw" | "n" | "ne" | "e" | "se" | "s" | "sw" | "w";
|
type TransformHandle = "body" | "nw" | "n" | "ne" | "e" | "se" | "s" | "sw" | "w";
|
||||||
|
|
||||||
type InputToolId = "select" | "crop" | "brush" | "eraser" | "pan";
|
type InputToolId = "select" | "brush" | "eraser" | "pan";
|
||||||
|
|
||||||
type InputInteractionMode =
|
type InputInteractionMode =
|
||||||
| { type: "tool"; tool: InputToolId }
|
| { type: "tool"; tool: InputToolId }
|
||||||
@@ -48,8 +48,7 @@ export function createTransformControlsInputController(options: {
|
|||||||
if (event.pointerType !== "mouse" || (event.buttons & 1) !== 1) return false;
|
if (event.pointerType !== "mouse" || (event.buttons & 1) !== 1) return false;
|
||||||
|
|
||||||
const editor = options.getEditor();
|
const editor = options.getEditor();
|
||||||
const cropToolActive = editor.tools.activeTool === "crop";
|
if (editor.tools.activeTool !== "select" || isPanInteractionMode(editor.tools.interactionMode)) return false;
|
||||||
if ((editor.tools.activeTool !== "select" && !cropToolActive) || isPanInteractionMode(editor.tools.interactionMode)) return false;
|
|
||||||
|
|
||||||
const document = options.getDocument();
|
const document = options.getDocument();
|
||||||
const target = selectedTransformTarget(document, editor.selection);
|
const target = selectedTransformTarget(document, editor.selection);
|
||||||
@@ -59,7 +58,7 @@ export function createTransformControlsInputController(options: {
|
|||||||
if (!bounds) return false;
|
if (!bounds) return false;
|
||||||
|
|
||||||
const handle = hitTestArtboardTransformHandle(event.position, bounds, editor.viewport);
|
const handle = hitTestArtboardTransformHandle(event.position, bounds, editor.viewport);
|
||||||
if (!handle || (cropToolActive && handle === "body")) return false;
|
if (!handle) return false;
|
||||||
|
|
||||||
options.dispatch(commandIds.transformBegin, {
|
options.dispatch(commandIds.transformBegin, {
|
||||||
target,
|
target,
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ describe("viewport pan store integration", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
type InputToolId = "select" | "crop" | "brush" | "eraser" | "pan";
|
type InputToolId = "select" | "brush" | "eraser" | "pan";
|
||||||
|
|
||||||
type InputStore = ReturnType<typeof createInputStore>;
|
type InputStore = ReturnType<typeof createInputStore>;
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ export function App({ app }: AppProps) {
|
|||||||
maskEdit={state.editor.maskEdit}
|
maskEdit={state.editor.maskEdit}
|
||||||
open={layersOpen}
|
open={layersOpen}
|
||||||
dispatch={app.store.dispatch}
|
dispatch={app.store.dispatch}
|
||||||
onClose={() => setLayersOpen(false)}
|
|
||||||
/>
|
/>
|
||||||
<div className="absolute inset-x-0 bottom-4 z-10 flex justify-center">
|
<div className="absolute inset-x-0 bottom-4 z-10 flex justify-center">
|
||||||
<BottomControlsIsland
|
<BottomControlsIsland
|
||||||
|
|||||||
@@ -16,10 +16,9 @@ export type LayersSheetProps = {
|
|||||||
maskEdit?: MaskEditState;
|
maskEdit?: MaskEditState;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
dispatch: AppStore["dispatch"];
|
dispatch: AppStore["dispatch"];
|
||||||
onClose: () => void;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function LayersSheet({ document, selection, maskEdit, open, dispatch, onClose }: LayersSheetProps) {
|
export function LayersSheet({ document, selection, maskEdit, open, dispatch }: LayersSheetProps) {
|
||||||
const selectedArtboardId = selection.artboardId ?? document.artboards[0]?.id;
|
const selectedArtboardId = selection.artboardId ?? document.artboards[0]?.id;
|
||||||
const selectedLayer = findLayerInfoInDocument(document, selection.layerIds[0]);
|
const selectedLayer = findLayerInfoInDocument(document, selection.layerIds[0]);
|
||||||
const canGroup = Boolean(selection.artboardId && selection.layerIds.length > 0);
|
const canGroup = Boolean(selection.artboardId && selection.layerIds.length > 0);
|
||||||
@@ -491,7 +490,3 @@ function createGroup(name: string): Layer {
|
|||||||
function toolbarButtonClass() {
|
function toolbarButtonClass() {
|
||||||
return "inline-flex h-8 items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 text-white/75 transition hover:border-white/20 hover:bg-white/10 hover:text-white disabled:pointer-events-none disabled:opacity-35";
|
return "inline-flex h-8 items-center gap-1.5 rounded-full border border-white/10 bg-white/[0.04] px-3 text-white/75 transition hover:border-white/20 hover:bg-white/10 hover:text-white disabled:pointer-events-none disabled:opacity-35";
|
||||||
}
|
}
|
||||||
|
|
||||||
function iconButtonClass() {
|
|
||||||
return "grid size-8 place-items-center rounded-full text-white/70 transition hover:bg-white/10 hover:text-white focus:outline-none focus-visible:outline-none";
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Crop, Cursor, Eraser, Hand, PaintBrush } from "@phosphor-icons/react";
|
import { Cursor, Eraser, Hand, PaintBrush } from "@phosphor-icons/react";
|
||||||
import { commandIds } from "@commands/ids";
|
import { commandIds } from "@commands/ids";
|
||||||
import type { AppStore } from "@editor/store";
|
import type { AppStore } from "@editor/store";
|
||||||
import type { InteractionMode, ToolId } from "@editor/tools";
|
import type { InteractionMode, ToolId } from "@editor/tools";
|
||||||
@@ -41,8 +41,6 @@ export function ToolOverlay({ activeTool, interactionMode, dispatch }: ToolOverl
|
|||||||
|
|
||||||
function iconForTool(tool: ToolId) {
|
function iconForTool(tool: ToolId) {
|
||||||
switch (tool) {
|
switch (tool) {
|
||||||
case "crop":
|
|
||||||
return Crop;
|
|
||||||
case "brush":
|
case "brush":
|
||||||
return PaintBrush;
|
return PaintBrush;
|
||||||
case "eraser":
|
case "eraser":
|
||||||
|
|||||||
@@ -6,6 +6,5 @@ export function canvasCursorClass(interactionMode: InteractionMode, input: Canva
|
|||||||
if (input.isPanning) return "cursor-grabbing";
|
if (input.isPanning) return "cursor-grabbing";
|
||||||
if (isPanInteractionMode(interactionMode)) return "cursor-grab";
|
if (isPanInteractionMode(interactionMode)) return "cursor-grab";
|
||||||
if (interactionMode.type === "tool" && (interactionMode.tool === "brush" || interactionMode.tool === "eraser")) return hasBrushPreview ? "cursor-none" : "cursor-crosshair";
|
if (interactionMode.type === "tool" && (interactionMode.tool === "brush" || interactionMode.tool === "eraser")) return hasBrushPreview ? "cursor-none" : "cursor-crosshair";
|
||||||
if (interactionMode.type === "tool" && interactionMode.tool === "crop") return "cursor-crosshair";
|
|
||||||
return "cursor-default";
|
return "cursor-default";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ export function useCanvasInput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const currentState = store.getState();
|
const currentState = store.getState();
|
||||||
const selectionToolActive = currentState.editor.tools.activeTool === "select" || currentState.editor.tools.activeTool === "crop";
|
const selectionToolActive = currentState.editor.tools.activeTool === "select";
|
||||||
const selected = selectionToolActive && handleArtboardSelection({
|
const selected = selectionToolActive && handleArtboardSelection({
|
||||||
event: inputEvent,
|
event: inputEvent,
|
||||||
document: currentState.document,
|
document: currentState.document,
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ import type { ToolId } from "@editor/tools";
|
|||||||
|
|
||||||
export function labelForTool(tool: ToolId): string {
|
export function labelForTool(tool: ToolId): string {
|
||||||
switch (tool) {
|
switch (tool) {
|
||||||
case "crop":
|
|
||||||
return "Crop";
|
|
||||||
case "brush":
|
case "brush":
|
||||||
return "Brush";
|
return "Brush";
|
||||||
case "eraser":
|
case "eraser":
|
||||||
|
|||||||
Reference in New Issue
Block a user