Skip to content

Commit da6c4e1

Browse files
add marquee
1 parent a21a45b commit da6c4e1

5 files changed

Lines changed: 92 additions & 2 deletions

File tree

editor-packages/editor-canvas/canvas-event-target/canvas-event-target.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export type OnZoomingHandler = Handler<
1616

1717
export type OnPointerMoveHandler = Handler<"move">;
1818

19+
export type OnDragHandler = Handler<"drag">;
20+
1921
export type OnPointerDownHandler = (
2022
e: { event: React.MouseEvent<EventTarget, MouseEvent> } & SharedGestureState
2123
) => void;
@@ -33,6 +35,9 @@ export function CanvasEventTarget({
3335
onPointerMoveStart,
3436
onPointerMoveEnd,
3537
onPointerDown,
38+
onDrag,
39+
onDragStart,
40+
onDragEnd,
3641
children,
3742
}: {
3843
onPanning: OnPanningHandler;
@@ -45,6 +50,9 @@ export function CanvasEventTarget({
4550
onPointerMoveStart: OnPointerMoveHandler;
4651
onPointerMoveEnd: OnPointerMoveHandler;
4752
onPointerDown: OnPointerDownHandler;
53+
onDrag: OnDragHandler;
54+
onDragStart: OnDragHandler;
55+
onDragEnd: OnDragHandler;
4856
children?: React.ReactNode;
4957
}) {
5058
const interactionEventTargetRef = useRef();
@@ -139,20 +147,29 @@ export function CanvasEventTarget({
139147
onDragStart: (s) => {
140148
if (isSpacebarPressed) {
141149
onPanningStart(s as any);
150+
return;
142151
}
152+
153+
onDragStart(s);
143154
},
144155
onDrag: (s) => {
145156
if (isSpacebarPressed) {
146157
onPanning({
147158
...s,
148159
delta: [-s.delta[0], -s.delta[1]],
149160
} as any);
161+
return;
150162
}
163+
164+
onDrag(s);
151165
},
152166
onDragEnd: (s) => {
153167
if (isSpacebarPressed) {
154168
onPanningEnd(s as any);
169+
return;
155170
}
171+
172+
onDragEnd(s);
156173
},
157174
onMouseDown: onPointerDown,
158175
onMoveStart: onPointerMoveStart,

editor-packages/editor-canvas/canvas/canvas.tsx

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import {
77
OnZoomingHandler,
88
OnPointerMoveHandler,
99
OnPointerDownHandler,
10+
OnDragHandler,
1011
} from "../canvas-event-target";
1112
import { get_hovering_target, centerOf } from "../math";
1213
import { utils } from "@design-sdk/core";
1314
import { LazyFrame } from "@code-editor/canvas/lazy-frame";
1415
import { HudCustomRenderers, HudSurface } from "./hud-surface";
15-
import type { Box, XY, CanvasTransform } from "../types";
16+
import type { Box, XY, CanvasTransform, XYWH } from "../types";
1617
import type { FrameOptimizationFactors } from "../frame";
1718
const designq = utils.query;
1819

@@ -117,6 +118,8 @@ export function Canvas({
117118
? [offset[0] / zoom, offset[1] / zoom]
118119
: [0, 0];
119120
const [isPanning, setIsPanning] = useState(false);
121+
const [marquee, setMarquee] = useState<XYWH>(null);
122+
120123
const cvtransform: CanvasTransform = {
121124
scale: zoom,
122125
xy: offset,
@@ -207,6 +210,29 @@ export function Canvas({
207210
setOffset([newx, newy]);
208211
};
209212

213+
const onDrag: OnDragHandler = (s) => {
214+
const [x1, y1] = s.initial;
215+
const [x2, y2] = [
216+
// @ts-ignore
217+
s.event.clientX,
218+
// @ts-ignore
219+
s.event.clientY,
220+
];
221+
222+
const [ox, oy] = offset;
223+
const [x, y, w, h] = [
224+
x1 - ox,
225+
y1 - oy,
226+
x2 - x1, // w
227+
y2 - y1, // h
228+
];
229+
setMarquee([x, y, w, h]);
230+
};
231+
232+
const onDragEnd: OnDragHandler = (s) => {
233+
setMarquee(null);
234+
};
235+
210236
const is_canvas_transforming = isPanning || isZooming;
211237
const selected_nodes = selectedNodes
212238
?.map((id) => designq.find_node_by_id_under_inpage_nodes(id, nodes))
@@ -257,12 +283,16 @@ export function Canvas({
257283
onPointerMoveStart={() => {}}
258284
onPointerMoveEnd={() => {}}
259285
onPointerDown={onPointerDown}
286+
onDrag={onDrag}
287+
onDragStart={() => {}} // TODO:
288+
onDragEnd={onDragEnd}
260289
>
261290
<HudSurface
262291
offset={nonscaled_offset}
263292
zoom={zoom}
264293
hide={is_canvas_transforming}
265294
readonly={readonly}
295+
marquee={marquee}
266296
labelDisplayNodes={nodes}
267297
selectedNodes={selected_nodes}
268298
highlights={

editor-packages/editor-canvas/canvas/hud-surface.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from "react";
22
import { HoverOutlineHighlight, ReadonlySelectHightlight } from "../overlay";
33
import { FrameTitle, FrameTitleProps } from "../frame-title";
44
import type { XY, XYWH } from "../types";
5-
5+
import { Marquee } from "../marquee";
66
interface HudControls {
77
onSelectNode: (node: string) => void;
88
onHoverNode: (node: string) => void;
@@ -34,6 +34,7 @@ export function HudSurface({
3434
readonly,
3535
onSelectNode,
3636
onHoverNode,
37+
marquee,
3738
//
3839
renderFrameTitle = frame_title_default_renderer,
3940
}: {
@@ -43,6 +44,7 @@ export function HudSurface({
4344
labelDisplayNodes: DisplayNodeMeta[];
4445
selectedNodes: DisplayNodeMeta[];
4546
hide: boolean;
47+
marquee?: XYWH;
4648
readonly: boolean;
4749
} & HudControls &
4850
HudCustomRenderers) {
@@ -63,6 +65,7 @@ export function HudSurface({
6365
}}
6466
id="hud-surface"
6567
>
68+
{marquee && <Marquee rect={marquee} />}
6669
{!hide && (
6770
<>
6871
{labelDisplayNodes &&
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Marquee } from "./marquee";
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React from "react";
2+
import type { XYWH } from "../types";
3+
4+
const canvasSelectionRectBackgroundColor = "rgba(0, 87, 255, 0.15)";
5+
const canvasSelectionRectBorderColor = "rgb(0, 87, 255)";
6+
7+
export function Marquee({ rect }: { rect: XYWH }) {
8+
const [x, y, ow, oh] = rect;
9+
10+
let [w, h, r] = [ow, oh, 0];
11+
if (w < 0 && h >= 0) {
12+
w = oh;
13+
h = ow;
14+
r = 90;
15+
} else if (h < 0 && w >= 0) {
16+
r = -90;
17+
w = oh;
18+
h = ow;
19+
} else if (w < 0 && h < 0) {
20+
r = 180;
21+
} else {
22+
r = 0;
23+
}
24+
25+
return (
26+
<div
27+
style={{
28+
position: "absolute",
29+
backgroundColor: canvasSelectionRectBackgroundColor,
30+
width: Math.abs(w),
31+
height: Math.abs(h),
32+
willChange: "transform, opacity",
33+
transformOrigin: "0px 0px",
34+
transform: `translateX(${x}px) translateY(${y}px) rotate(${r}deg)`,
35+
border: `${canvasSelectionRectBorderColor} 1px solid`,
36+
}}
37+
></div>
38+
);
39+
}

0 commit comments

Comments
 (0)