feat: implements node positioning via drag and drop

This commit is contained in:
Mark Mankarious
2023-04-04 01:04:12 +01:00
parent b050d4cec4
commit a6fdbf0c00
4 changed files with 55 additions and 7 deletions

View File

@@ -6,8 +6,18 @@ import { Node } from "../renderer/elements/Node";
export class SelectNode extends ModeBase {
node?: Node;
constructor(ctx: ModeContext) {
super(ctx);
entry(mouse: Mouse) {
const tile = this.ctx.renderer.getTileFromMouse(
mouse.position.x,
mouse.position.y
);
this.ctx.renderer.sceneElements.cursor.displayAt(tile.x, tile.y);
this.ctx.renderer.sceneElements.cursor.enable();
}
exit() {
this.ctx.renderer.sceneElements.cursor.disable();
}
MOUSE_MOVE(mouse: Mouse) {
@@ -19,6 +29,7 @@ export class SelectNode extends ModeBase {
);
this.node.moveTo(tile.x, tile.y);
this.ctx.renderer.sceneElements.cursor.displayAt(tile.x, tile.y);
}
MOUSE_UP() {

View File

@@ -9,6 +9,7 @@ import {
} from "../utils/gridHelpers";
import type { Context, Coords } from "../types";
import { SceneElement } from "../SceneElement";
import { tweenPosition } from "../../utils";
export enum CURSOR_TYPES {
OUTLINE = "OUTLINE",
@@ -41,6 +42,7 @@ export class Cursor extends SceneElement {
constructor(ctx: Context) {
super(ctx);
this.displayAt = this.displayAt.bind(this);
this.renderElements.rectangle = new Shape.Rectangle({});
@@ -192,7 +194,9 @@ export class Cursor extends SceneElement {
return { ...this.position, ...this.size };
}
displayAt(x: number, y: number, options?: { animate: boolean }) {
displayAt(x: number, y: number, opts?: { skipAnimation: boolean }) {
if (x === this.position.x && y === this.position.y) return;
this.position = {
x,
y,
@@ -201,8 +205,11 @@ export class Cursor extends SceneElement {
const tileBoundsPosition =
this.currentType === CURSOR_TYPES.LASSO ? "left" : "center";
const position = getTileBounds(x, y)[tileBoundsPosition];
const tile = getTileBounds(x, y)[tileBoundsPosition];
this.container.set({ position });
tweenPosition(this.container, {
...tile,
duration: opts?.skipAnimation ? 0 : 0.05,
});
}
}

View File

@@ -1,4 +1,5 @@
import { Group } from "paper";
import gsap from "gsap";
import autobind from "auto-bind";
import { makeAutoObservable } from "mobx";
import { Context } from "../types";
@@ -6,6 +7,7 @@ import { Node, NodeOptions } from "./Node";
import cuid from "cuid";
import { SceneElement } from "../SceneElement";
import { SceneEvent } from "../SceneEvent";
import { tweenPosition } from "../../utils";
export class Nodes {
ctx: Context;
@@ -45,13 +47,17 @@ export class Nodes {
.complete();
}
onMove(x: number, y: number, node: Node) {
onMove(x: number, y: number, node: Node, opts?: { skipAnimation: boolean }) {
const tile = this.ctx.getTileBounds(x, y);
node.position = {
x,
y,
};
node.container.position.set(tile.bottom);
tweenPosition(node.container, {
...tile.bottom,
duration: opts?.skipAnimation ? 0 : 0.05,
});
}
getNodeById(id: string) {

View File

@@ -1,3 +1,5 @@
import gsap from "gsap";
export const clamp = (num: number, min: number, max: number) => {
return num <= min ? min : num >= max ? max : num;
};
@@ -5,3 +7,25 @@ export const clamp = (num: number, min: number, max: number) => {
export const getRandom = (min: number, max: number) => {
return Math.floor(Math.random() * (max - min) + min);
};
export const tweenPosition = (
item: paper.Item,
{ x, y, duration }: { x: number; y: number; duration: number }
) => {
// paperjs doesn't like it when you try to tween the position of an item directly,
// so we have to use a proxy object
const currPosition = {
x: item.position.x,
y: item.position.y,
};
gsap.to(currPosition, {
duration,
overwrite: "auto",
x,
y,
onUpdate: () => {
item.set({ position: currPosition });
},
});
};