Skip to content

Commit

Permalink
Grabbing atoms functionality implemented.
Browse files Browse the repository at this point in the history
  • Loading branch information
Smoren committed Jul 13, 2024
1 parent dbe2580 commit 8be7819
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 24 deletions.
45 changes: 40 additions & 5 deletions src/lib/drawer/2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ export class Drawer2d implements DrawerInterface {
const coords = createVector(
transposeCoordsBackward([event.offsetX, event.offsetY], this.viewConfig.offset, this.viewConfig.scale),
);
this.eventManager.triggerClick({ coords, extraKey: keyDown });
this.eventManager.triggerClick({ coords, extraKey: keyDown, ctrlKey: event.ctrlKey });
console.log(keyDown, coords);
});

Expand Down Expand Up @@ -208,22 +208,57 @@ export class Drawer2d implements DrawerInterface {
});

const mouseDownHandler = (event: MouseEvent | TouchEvent) => {
mouseDownVector = (event instanceof MouseEvent)
const coords = (event instanceof MouseEvent)
? createVector([event.offsetX, event.offsetY])
: createVector([event.touches[0].clientX, event.touches[0].clientY]);
document.body.style.cursor = 'grabbing';

try {
this.eventManager.triggerMouseDown({
coords: transposeCoordsBackward(coords, this.viewConfig.offset, this.viewConfig.scale),
extraKey: keyDown,
ctrlKey: event.ctrlKey,
});
} catch (e) {
return;
}

mouseDownVector = coords;
};
const mouseUpHandler = (event: MouseEvent | TouchEvent) => {
const coords = (event instanceof MouseEvent)
? createVector([event.offsetX, event.offsetY])
: createVector([event.touches[0].clientX, event.touches[0].clientY]);
mouseDownVector = undefined;
document.body.style.cursor = 'auto';

this.eventManager.triggerMouseUp({
coords: transposeCoordsBackward(coords, this.viewConfig.offset, this.viewConfig.scale),
extraKey: keyDown,
ctrlKey: event.ctrlKey,
});
};
const mouseMoveHandler = (event: MouseEvent | TouchEvent) => {
if (mouseDownVector === undefined) {
return;
}
const coords = (event instanceof MouseEvent)
? createVector([event.offsetX, event.offsetY])
: createVector([event.touches[0].clientX, event.touches[0].clientY]);

this.eventManager.triggerMouseMove({
coords: transposeCoordsBackward(coords, this.viewConfig.offset, this.viewConfig.scale),
extraKey: keyDown,
ctrlKey: event.ctrlKey,
});

if (mouseDownVector === undefined) {
return;
}

this.eventManager.triggerMouseGrab({
coords: transposeCoordsBackward(coords, this.viewConfig.offset, this.viewConfig.scale),
extraKey: keyDown,
ctrlKey: event.ctrlKey,
});

const diff = coords.clone().sub(mouseDownVector);

this.viewConfig.offset[0] += diff[0];
Expand Down
1 change: 1 addition & 0 deletions src/lib/drawer/3d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export class Drawer3d implements DrawerInterface {
this.eventManager.triggerClick({
coords: [pos.x, pos.y, pos.z],
extraKey: keyDown,
ctrlKey: event.ctrlKey,
});
}
};
Expand Down
48 changes: 45 additions & 3 deletions src/lib/drawer/utils.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
import type { EventManagerInterface, MouseEventData, MouseEventListenerCallback } from '../types/drawer';
import type { NumericVector } from "@/lib/math/types";

type ListenersStorage = {
onClick: MouseEventListenerCallback[];
onMouseDown: MouseEventListenerCallback[];
onMouseMove: MouseEventListenerCallback[];
onMouseGrab: MouseEventListenerCallback[];
onMouseUp: MouseEventListenerCallback[];
};

export class PreventException extends Error {
}

export class EventManager implements EventManagerInterface {
private listeners: ListenersStorage = {
onClick: [],
onMouseDown: [],
onMouseMove: [],
onMouseGrab: [],
onMouseUp: [],
};
private lastPoint: NumericVector | undefined;
private mouseGrabTick: ReturnType<typeof setInterval> | undefined;

onClick(callback: MouseEventListenerCallback): EventManagerInterface {
return this.add('onClick', callback);
}
Expand All @@ -26,6 +35,10 @@ export class EventManager implements EventManagerInterface {
return this.add('onMouseMove', callback);
}

onMouseGrab(callback: MouseEventListenerCallback): EventManagerInterface {
return this.add('onMouseGrab', callback);
}

onMouseUp(callback: MouseEventListenerCallback): EventManagerInterface {
return this.add('onMouseUp', callback);
}
Expand All @@ -35,14 +48,20 @@ export class EventManager implements EventManagerInterface {
}

triggerMouseDown(event: MouseEventData): void {
this.startMouseGrabTick();
this.trigger('onMouseDown', event);
}

triggerMouseMove(event: MouseEventData): void {
this.trigger('onMouseMove', event);
}

triggerMouseGrab(event: MouseEventData): void {
this.trigger('onMouseGrab', event);
}

triggerMouseUp(event: MouseEventData): void {
this.stopMouseGrabTick();
this.trigger('onMouseUp', event);
}

Expand All @@ -51,9 +70,32 @@ export class EventManager implements EventManagerInterface {
return this;
}

private trigger(type: keyof ListenersStorage, event: MouseEventData): void {
for (const callback of this.listeners[type]) {
callback(event);
private trigger(type: keyof ListenersStorage, event: MouseEventData, throwException: boolean = true): void {
this.lastPoint = event.coords;
try {
for (const callback of this.listeners[type]) {
callback(event);
}
} catch (e) {
if (throwException) {
throw e;
}
}
}

private startMouseGrabTick() {
this.mouseGrabTick = setInterval(() => {
this.trigger('onMouseGrab', {
coords: this.lastPoint as NumericVector,
extraKey: undefined,
ctrlKey: false,
}, false);
}, 30);
}

private stopMouseGrabTick() {
if (this.mouseGrabTick) {
clearInterval(this.mouseGrabTick);
}
}
}
57 changes: 41 additions & 16 deletions src/lib/simulation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { SummaryManager } from './analysis/summary';
import type { NumericVector } from './math/types';
import type { Compound } from './types/analysis';
import { CompoundsCollector } from './analysis/compounds';
import { PreventException } from "@/lib/drawer/utils";
import { toVector } from "@/lib/math";

export class Simulation implements SimulationInterface {
readonly config: SimulationConfig;
Expand Down Expand Up @@ -42,22 +44,7 @@ export class Simulation implements SimulationInterface {
this.clusterManager = new ClusterManager(this.config.worldConfig.MAX_INTERACTION_RADIUS);
this.runningState = new RunningState();

this.drawer.eventManager.onClick((event) => {
const foundAtom = this.clusterManager.findAtomByCoords(
event.coords,
this.config.typesConfig.RADIUS,
this.config.worldConfig.ATOM_RADIUS,
);
if (foundAtom) {
console.log('ATOM FOUND', foundAtom);
}

if (event.extraKey === undefined || event.extraKey > this.config.typesConfig.FREQUENCIES.length) {
return;
}
console.log('atom added');
this._atoms.push(createAtom(event.extraKey-1, event.coords));
});
this.initEventHandlers();
}

get atoms(): AtomInterface[] {
Expand Down Expand Up @@ -217,4 +204,42 @@ export class Simulation implements SimulationInterface {
this.runningState.confirmStop();
}
}

private initEventHandlers(): void {
let grabbedAtom: AtomInterface | undefined = undefined;

this.drawer.eventManager.onClick((event) => {
if (event.extraKey === undefined || event.extraKey > this.config.typesConfig.FREQUENCIES.length) {
return;
}
console.log('atom added');
this._atoms.push(createAtom(event.extraKey-1, event.coords));
});

this.drawer.eventManager.onMouseDown((event) => {
if (!event.ctrlKey) {
return;
}
grabbedAtom = this.clusterManager.findAtomByCoords(
event.coords,
this.config.typesConfig.RADIUS,
this.config.worldConfig.ATOM_RADIUS*2,
);
if (grabbedAtom) {
console.log('ATOM FOUND', grabbedAtom);
}
throw new PreventException();
});

this.drawer.eventManager.onMouseGrab((event) => {
if (grabbedAtom) {
const speed = toVector(event.coords).sub(grabbedAtom.position).mul(0.2);
grabbedAtom.speed.set(speed);
}
});

this.drawer.eventManager.onMouseUp((event) => {
grabbedAtom = undefined;
});
}
}
4 changes: 4 additions & 0 deletions src/lib/types/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export interface ViewConfigInterface {
export type MouseEventData = {
coords: NumericVector;
extraKey: number | undefined;
ctrlKey: boolean;
}

export type MouseEventListenerCallback = (event: MouseEventData) => void;

export interface DrawerInterface {
Expand All @@ -24,11 +26,13 @@ export interface EventManagerInterface {
onClick(callback: MouseEventListenerCallback): EventManagerInterface;
onMouseDown(callback: MouseEventListenerCallback): EventManagerInterface;
onMouseMove(callback: MouseEventListenerCallback): EventManagerInterface;
onMouseGrab(callback: MouseEventListenerCallback): EventManagerInterface;
onMouseUp(callback: MouseEventListenerCallback): EventManagerInterface;

triggerClick(event: MouseEventData): void;
triggerMouseDown(event: MouseEventData): void;
triggerMouseMove(event: MouseEventData): void;
triggerMouseGrab(event: MouseEventData): void;
triggerMouseUp(event: MouseEventData): void;
}

Expand Down

0 comments on commit 8be7819

Please sign in to comment.