diff --git a/package.json b/package.json index 5e535e4..6cb32a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kateter-platform/graphica-gemini", - "version": "1.0.5", + "version": "1.0.6", "source": "./src/index.ts", "description": "A tool for advanced graphing and visualization", "license": "MIT", diff --git a/src/Components/Point.ts b/src/Components/Point.ts index 8834a35..4719b1f 100644 --- a/src/Components/Point.ts +++ b/src/Components/Point.ts @@ -8,13 +8,14 @@ import { Vector3, } from "three"; import Text from "./Text"; -import { Collider, Component, Draggable } from "./interfaces"; +import { Collider, Component, DragListener, Draggable } from "./interfaces"; type PointOptions = { label?: boolean; decimals?: number; color?: string; draggable?: Draggable; + dragListeners?: ((point: Point) => void)[]; }; const defaultPointOptions = { @@ -22,12 +23,15 @@ const defaultPointOptions = { draggable: undefined, decimals: 1, label: false, + dragListeners: [], }; -class Point extends Component implements Collider { +class Point extends Component implements Collider, DragListener { + dragListeners: ((point: Point) => void)[]; + constructor(x = 0, y = 0, options?: PointOptions) { super(); - const { color, draggable, decimals, label } = { + const { color, draggable, decimals, label, dragListeners } = { ...defaultPointOptions, ...options, }; @@ -48,6 +52,7 @@ class Point extends Component implements Collider { this.add(strokeMesh); // set position of the mesh this.position.set(x, y, 2); + this.dragListeners = dragListeners ?? []; if (label) { const text = new Text( @@ -65,6 +70,10 @@ class Point extends Component implements Collider { } } + addDragListener(listener: (point: Point) => void) { + this.dragListeners.push(listener); + } + collidesWith(other: Object3D): boolean { const box1 = new Box3().setFromObject(this); const box2 = new Box3().setFromObject(other); @@ -100,6 +109,7 @@ class Point extends Component implements Collider { message: "Point has been moved", position: this.position, }); // Dispatch the drag event + this.dragListeners.forEach((fn) => fn(this)); } update(camera: THREE.OrthographicCamera) { diff --git a/src/Components/Shape.ts b/src/Components/Shape.ts index 7faea6c..f24a732 100644 --- a/src/Components/Shape.ts +++ b/src/Components/Shape.ts @@ -11,18 +11,22 @@ import { } from "three"; import { toVector2 } from "../utils"; import Line from "./Line"; -import { Collider, Component } from "./interfaces"; +import { Collider, Component, DragListener, Draggable } from "./interfaces"; import { InputPosition } from "./types"; export type PolygonOptions = { color?: number; fill?: boolean; opacity?: number; + draggable?: Draggable; + dragListeners?: ((point: Polygon) => void)[]; }; export const defaultShapeOptions: PolygonOptions = { color: 0xfaa307, opacity: 0.6, + draggable: undefined, + dragListeners: [], }; type PolygonVertices = [ @@ -32,16 +36,19 @@ type PolygonVertices = [ ...InputPosition[] ]; -class Polygon extends Component implements Collider { - draggable = undefined; +class Polygon extends Component implements Collider, DragListener { vertices: PolygonVertices; color: number; object: Object3D; + dragListeners: ((value: Polygon) => void)[]; constructor(vertices: PolygonVertices, options?: PolygonOptions) { super(); - const { color, opacity } = { ...defaultShapeOptions, ...options }; + const { color, opacity, draggable, dragListeners } = { + ...defaultShapeOptions, + ...options, + }; const shape = new Shape(vertices.map((e) => toVector2(e))); const material = new MeshBasicMaterial({ @@ -53,8 +60,9 @@ class Polygon extends Component implements Collider { const mesh = new Mesh(geometry, material); mesh.scale.set(1, 1, 1); - this.add(mesh); - this.object = mesh; + this.geometry = mesh.geometry; + this.material = mesh.material; + this.position.setZ(1.5); const group = new Group(); const lines = []; @@ -74,7 +82,18 @@ class Polygon extends Component implements Collider { this.object = group; this.vertices = vertices; this.color = color ?? 0xfaa307; + this.draggable = draggable; + this.dragListeners = dragListeners ?? []; } + + addDragListener(listener: (value: Polygon) => void) { + this.dragListeners.push(listener); + } + + dragUpdate(): void { + this.dragListeners.forEach((fn) => fn(this)); + } + collidesWith(other: Object3D): boolean { const box1 = new Box3().setFromObject(this); const box2 = new Box3().setFromObject(other); diff --git a/src/Components/interfaces.ts b/src/Components/interfaces.ts index b74c12e..50cddc2 100644 --- a/src/Components/interfaces.ts +++ b/src/Components/interfaces.ts @@ -21,6 +21,12 @@ export interface Collider extends Object3D { distanceTo(other: Object3D): number; } +export interface DragListener { + dragListeners: ((value: T) => void)[]; + dragUpdate(): void; + addDragListener: (listener: (value: T) => void) => void; +} + export type ConstrainFunction = (x: number, y: number) => [number, number]; export type Draggable = diff --git a/src/Controls/DragControls.ts b/src/Controls/DragControls.ts index 8fe9915..eb456b1 100644 --- a/src/Controls/DragControls.ts +++ b/src/Controls/DragControls.ts @@ -84,7 +84,6 @@ class DragControls extends EventDispatcher { } this.dispatchEvent({ type: "drag", object: _selected }); - return; } diff --git a/src/Graphica.ts b/src/Graphica.ts index 6349428..9abe74d 100644 --- a/src/Graphica.ts +++ b/src/Graphica.ts @@ -137,7 +137,6 @@ class Graphica { dragControls.addEventListener("dragstart", function (event) { controls.enabled = false; - const draggedObject = event.object; draggedObject.is_dragged = true; draggedObject.userData.initialPosition = draggedObject.position.clone(); @@ -170,7 +169,6 @@ class Graphica { dragControls.addEventListener("dragend", function (event) { controls.enabled = true; - const draggedObject = event.object; draggedObject.is_dragged = false; });