feat(tools): add brush raster painting
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useState, type RefObject } from "react";
|
||||
import { useEffect, useRef, useState, type RefObject } from "react";
|
||||
import type { AppStore } from "@editor/store";
|
||||
import { isPanInteractionMode } from "@editor/tools";
|
||||
import type { GlobalKeybindConsumer, GlobalPointerConsumer, GlobalWheelConsumer } from "@input/index";
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
pointerInputEventFromPointerEvent,
|
||||
wheelInputEventFromWheelEvent,
|
||||
} from "@input/index";
|
||||
import { beginBrushSession, updateBrushSession, type BrushSession } from "./brush";
|
||||
|
||||
export type CanvasInputOptions = {
|
||||
globalKeybindConsumer: GlobalKeybindConsumer;
|
||||
@@ -28,6 +29,7 @@ export function useCanvasInput(
|
||||
options: CanvasInputOptions,
|
||||
): CanvasInputState {
|
||||
const [isPanning, setIsPanning] = useState(false);
|
||||
const brushSession = useRef<BrushSession>();
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = canvasRef.current;
|
||||
@@ -59,6 +61,15 @@ export function useCanvasInput(
|
||||
|
||||
const handlePointerDown = (event: PointerEvent) => {
|
||||
const inputEvent = pointerInputEventFromPointerEvent(event);
|
||||
const state = store.getState();
|
||||
const brush = beginBrushSession(state.document, state.editor, viewportPointToDocumentPoint(inputEvent.position, state.editor.viewport));
|
||||
if (brush) {
|
||||
brushSession.current = brush;
|
||||
canvas.setPointerCapture(event.pointerId);
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
const transformed = transformHandler.pointerDown(inputEvent);
|
||||
if (transformed) {
|
||||
canvas.setPointerCapture(event.pointerId);
|
||||
@@ -74,12 +85,12 @@ export function useCanvasInput(
|
||||
return;
|
||||
}
|
||||
|
||||
const state = store.getState();
|
||||
const selectionToolActive = state.editor.tools.activeTool === "select" || state.editor.tools.activeTool === "crop";
|
||||
const currentState = store.getState();
|
||||
const selectionToolActive = currentState.editor.tools.activeTool === "select" || currentState.editor.tools.activeTool === "crop";
|
||||
const selected = selectionToolActive && handleArtboardSelection({
|
||||
event: inputEvent,
|
||||
document: state.document,
|
||||
viewport: state.editor.viewport,
|
||||
document: currentState.document,
|
||||
viewport: currentState.editor.viewport,
|
||||
dispatch: store.dispatch,
|
||||
});
|
||||
if (selected) event.preventDefault();
|
||||
@@ -87,6 +98,15 @@ export function useCanvasInput(
|
||||
|
||||
const handlePointerMove = (event: PointerEvent) => {
|
||||
const inputEvent = pointerInputEventFromPointerEvent(event);
|
||||
if (brushSession.current) {
|
||||
const point = viewportPointToDocumentPoint(inputEvent.position, store.getState().editor.viewport);
|
||||
void updateBrushSession({ store, session: brushSession.current, point }).then((nextSession) => {
|
||||
brushSession.current = nextSession;
|
||||
});
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
const transformed = transformHandler.pointerMove(inputEvent);
|
||||
if (transformed) {
|
||||
event.preventDefault();
|
||||
@@ -99,6 +119,12 @@ export function useCanvasInput(
|
||||
|
||||
const handlePointerUp = (event: PointerEvent) => {
|
||||
const inputEvent = pointerInputEventFromPointerEvent(event);
|
||||
if (brushSession.current) {
|
||||
brushSession.current = undefined;
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
const transformed = transformHandler.pointerUp(inputEvent);
|
||||
if (transformed) {
|
||||
event.preventDefault();
|
||||
@@ -144,3 +170,10 @@ export function useCanvasInput(
|
||||
|
||||
return { isPanning };
|
||||
}
|
||||
|
||||
function viewportPointToDocumentPoint(point: { x: number; y: number }, viewport: { center: { x: number; y: number }; size: { w: number; h: number }; zoom: number }) {
|
||||
return {
|
||||
x: viewport.center.x + (point.x - viewport.size.w / 2) / viewport.zoom,
|
||||
y: viewport.center.y + (point.y - viewport.size.h / 2) / viewport.zoom,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user