feat(input): select image layers on canvas
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { commandIds } from "@commands/ids";
|
||||
import type { Dispatch } from "@commands/dispatcher";
|
||||
import type { ImageDocument } from "@core/document";
|
||||
import type { Layer } from "@core/layer";
|
||||
import { resolveTransformTargetBounds } from "@editor/transform-targets";
|
||||
import type { ViewportState } from "@editor/state";
|
||||
import type { PointerInputEvent } from "./pointer";
|
||||
|
||||
@@ -13,6 +15,12 @@ export function handleArtboardSelection(options: {
|
||||
if (options.event.pointerType !== "mouse" || (options.event.buttons & 1) !== 1) return false;
|
||||
|
||||
const point = viewportPointToDocumentPoint(options.event.position, options.viewport);
|
||||
const layerHit = findTopmostLayerAtPoint(options.document, point);
|
||||
if (layerHit) {
|
||||
options.dispatch(commandIds.selectionSet, { artboardId: layerHit.artboardId, layerIds: [layerHit.layerId] });
|
||||
return true;
|
||||
}
|
||||
|
||||
const artboard = [...options.document.artboards].reverse().find((candidate) => {
|
||||
const bounds = candidate.bounds;
|
||||
return point.x >= bounds.x && point.x <= bounds.x + bounds.w && point.y >= bounds.y && point.y <= bounds.y + bounds.h;
|
||||
@@ -27,6 +35,31 @@ export function handleArtboardSelection(options: {
|
||||
return true;
|
||||
}
|
||||
|
||||
function findTopmostLayerAtPoint(document: ImageDocument, point: { x: number; y: number }) {
|
||||
for (const artboard of [...document.artboards].reverse()) {
|
||||
const layerId = findTopmostLayerInTreeAtPoint(document, [...artboard.layers].reverse(), point);
|
||||
if (layerId) return { artboardId: artboard.id, layerId };
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function findTopmostLayerInTreeAtPoint(document: ImageDocument, layers: Layer[], point: { x: number; y: number }): string | undefined {
|
||||
for (const layer of layers) {
|
||||
if (layer.type === "group") {
|
||||
const childId = findTopmostLayerInTreeAtPoint(document, [...layer.children].reverse(), point);
|
||||
if (childId) return childId;
|
||||
}
|
||||
|
||||
const bounds = resolveTransformTargetBounds(document, { type: "layer", id: layer.id });
|
||||
if (bounds && point.x >= bounds.x && point.x <= bounds.x + bounds.w && point.y >= bounds.y && point.y <= bounds.y + bounds.h) {
|
||||
return layer.id;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function viewportPointToDocumentPoint(point: PointerInputEvent["position"], viewport: ViewportState) {
|
||||
return {
|
||||
x: viewport.center.x + (point.x - viewport.size.w / 2) / viewport.zoom,
|
||||
|
||||
Reference in New Issue
Block a user