@judah-silva/rnacanvas 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 RNA3DS Lab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,10 +1,136 @@
1
1
  # 🧬 RNA Canvas
2
2
 
3
- A reusable, customizable 3D canvas component built with **Babylon.js** and **React**, designed for interactive molecular visualization and selection tools.
3
+ A reusable, modular 3D canvas component, built with **Babylon.js** and **React**. Designed for the interactive visualization of RNA models.
4
+
5
+ Disclaimer: This component only renders from a custom JSON format for 3D representation of RNA Molecules. Does not currently support standard 3D geometry file formats.
4
6
 
5
7
  ## 📦 Installation
6
8
 
7
9
  ```bash
8
- npm install @judah-silva/rnacanvas @babylonjs/core
10
+ npm install @judah-silva/rnacanvas
9
11
  # or
10
- yarn add @judah-silva/rnacanvas @babylonjs/core
12
+ yarn add @judah-silva/rnacanvas
13
+ ```
14
+
15
+ ## Canvas Description
16
+
17
+ The canvas is an importable **React** component, with an extensive Event Management system for interaction with 3D models.\
18
+ Made using **Babylon.js**, the canvas is designed with a stationary camera, where 3D Motif models are displayed to be rotated, translated, scaled, and compared with RMSD scoring.
19
+
20
+ RNACanvas supports interaction through the mouse, keyboard, and touch screen inputs.
21
+
22
+ ## Canvas Usage
23
+
24
+
25
+ ### Canvas Component
26
+
27
+ To use it in your project, import it from the package:
28
+ ```typescript
29
+ import { Canvas } from '@judah-silva/rnacanvas'
30
+ ```
31
+
32
+ Then, return an instance of the component like you would with any other **React** component:
33
+ ```typescript
34
+ import { Canvas } from '@judah-silva/rnacanvas'
35
+
36
+ export default function Component() {
37
+ // Component code...
38
+
39
+ return (
40
+ <>
41
+ <Canvas
42
+ // ...
43
+ // CanvasProps
44
+ // ...
45
+ />
46
+ </>
47
+ )
48
+ }
49
+ ```
50
+
51
+ ### Canvas Props
52
+
53
+ An interface defining the arguments taken by the Canvas component.
54
+
55
+ ```typescript
56
+ export interface CanvasProps {
57
+ title?: string, // Abitrary name for the Canvas
58
+ rendererWidth?: number, // Width of the rendered Canvas
59
+ rendererHeight?: number, // Height of the rendered Canvas
60
+ rendererSizeIsWindow?: boolean, // Boolean determining if Canvas will be window size
61
+ rendererBackgroundColor?: string, // #RRGGBB format color string
62
+ cameraPositionZ?: number, // Number determining Z position of the camera
63
+ motifProps: MotifProps[], // Array of MotifProps objects for Motifs to be displayed
64
+ customEventProps?: AnyEventProps[], // Array of any typed CustomEventProps for custom event listeners
65
+ }
66
+ ```
67
+
68
+ Here, we can pass in multiple attributes of the Canvas including size and color. All arguments are optional besides ```motifProps```.
69
+
70
+ ### Motif Props
71
+
72
+ An interface defining the properties of Motif objects that will be displayed.
73
+
74
+ ```typescript
75
+ export interface MotifProps {
76
+ motif: Motif, // Custom Motif object with Babylon.js meshes
77
+ locked: boolean, // Whether or not this Motif will be permanently locked (no interactions allowed) on the canvas
78
+ position?: Vec3, // Custom Vector 3 object
79
+ rotation?: Quat, // Custom Quaternion object
80
+ }
81
+ ```
82
+
83
+ ### Custom Event Props
84
+
85
+ An interface defining the properties of custom event listeners that the scene will trigger.
86
+
87
+ ```typescript
88
+ export interface CustomEventProps<T extends Events.Event = Events.Event> {
89
+ eventType: Events.EventType, // Type of Event to listen for.
90
+ callback: (event: T) => void; // Callback function to execute on trigger
91
+ }
92
+ ```
93
+
94
+ When creating the CustomEventProps for the CanvasProps:
95
+
96
+ ```typescript
97
+ <Canvas
98
+ // ...
99
+ customEventProps = [
100
+ {
101
+ eventType: Events.EventType.KEY_DOWN,
102
+ callback: (e: Events.KeyboardEvent) => {/* code to execute on trigger */},
103
+ } as CustomEventProps<Events.KeyboardEvent>,
104
+ ]
105
+ />
106
+ ```
107
+
108
+ ## Motif Model Creation
109
+
110
+ ### Motif Object
111
+
112
+ There are two wrapper classes made to represent different molecular components of an RNA strand: Motif and Residue. Motif is the primary object that the canvas works with, and it is a collection of Residues. Each Residue is a collection of Babylon Mesh objects.
113
+
114
+ ### Motif Creation
115
+
116
+ Use the getMotif function to pass in a custom JSON file, with a specified color, and receive a Motif object.
117
+
118
+ ```typescript
119
+ import { getMotif, Motif, MotifProps } from '@judah-silva/rnacanvas'
120
+
121
+ const motif1: Motif = await getMotif(
122
+ 'path_to_json',
123
+ '#RRGGBB_color',
124
+ );
125
+
126
+ // Create a MotifProps object for this motif
127
+ const props: MotifProps = {
128
+ motif: motif1,
129
+ locked: false,
130
+ };
131
+ ```
132
+
133
+ TALK ABOUT THE DATAMANAGER NEXT, AND THEN THAT SHOULD BE GOOD
134
+
135
+ ACTUALLY, I NEED TO TALK ABOUT RMSD AND ITS INTERFACES AND STUFF TOO :(
136
+
package/dist/index.d.mts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { Mesh, TransformNode, Scene, Matrix, Nullable, Quaternion, Observer, Engine, UniversalCamera } from '@babylonjs/core';
2
2
 
3
3
  /**
4
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
5
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
6
- * No code shall be distributed or modified without the permission of the PI.
4
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
7
5
  * @author Judah Silva <silva.judah7@outlook.com>
8
6
  */
9
7
 
@@ -14,9 +12,7 @@ declare class Residue extends Group<MeshObject> {
14
12
  }
15
13
 
16
14
  /**
17
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
18
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
19
- * No code shall be distributed or modified without the permission of the PI.
15
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
20
16
  * @author Judah Silva <silva.judah7@outlook.com>
21
17
  */
22
18
 
@@ -39,9 +35,7 @@ declare class MeshObject {
39
35
  }
40
36
 
41
37
  /**
42
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
43
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
44
- * No code shall be distributed or modified without the permission of the PI.
38
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
45
39
  * @author Judah Silva <silva.judah7@outlook.com>
46
40
  */
47
41
 
@@ -66,10 +60,16 @@ declare class Quat {
66
60
  private _quaternion;
67
61
  constructor();
68
62
  rotateByQuaternion(quaternion: Quat): void;
69
- setToQuaternion(quaternion: Nullable<Quaternion>): void;
63
+ setToQuaternion(quaternion: Nullable<Quaternion>): this;
70
64
  setFromMatrix(matrix: Matrix4): this;
71
65
  setFromEuler(eulerAngle: Vec3): this;
66
+ setFromValues(w: number, x: number, y: number, z: number): this;
67
+ toArray(): number[];
72
68
  get quaternion(): Quaternion;
69
+ get w(): number;
70
+ get x(): number;
71
+ get y(): number;
72
+ get z(): number;
73
73
  }
74
74
 
75
75
  declare class Vec3 {
@@ -90,9 +90,7 @@ declare class Vec3 {
90
90
  }
91
91
 
92
92
  /**
93
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
94
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
95
- * No code shall be distributed or modified without the permission of the PI.
93
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
96
94
  * @author Judah Silva <silva.judah7@outlook.com>
97
95
  */
98
96
 
@@ -118,17 +116,37 @@ declare class Motif extends Group<Residue> {
118
116
  private _nanCheck;
119
117
  get uuid(): string;
120
118
  get quat(): Quat;
119
+ get scale(): number;
121
120
  get position(): Vec3;
122
121
  }
123
122
 
124
123
  /**
125
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
126
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
127
- * No code shall be distributed or modified without the permission of the PI.
124
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
128
125
  * @author Judah Silva <silva.judah7@outlook.com>
129
126
  */
130
127
 
131
128
  declare namespace Events {
129
+ interface EventMap {
130
+ [EventType.POINTER_DOWN]: PointerEvent;
131
+ [EventType.POINTER_UP]: PointerEvent;
132
+ [EventType.POINTER_MOVE]: PointerEvent;
133
+ [EventType.POINTER_WHEEL]: PointerEvent;
134
+ [EventType.KEY_DOWN]: KeyboardEvent;
135
+ [EventType.KEY_UP]: KeyboardEvent;
136
+ [EventType.TOUCH_START]: PointerEvent;
137
+ [EventType.TOUCH_END]: PointerEvent;
138
+ [EventType.TOUCH_MOVE]: PointerEvent;
139
+ [EventType.PINCH_START]: PinchEvent;
140
+ [EventType.PINCH]: PinchEvent;
141
+ [EventType.PINCH_END]: PinchEvent;
142
+ [EventType.OBJECT_SELECTED]: SelectionEvent;
143
+ [EventType.OBJECT_DESELECTED]: SelectionEvent;
144
+ [EventType.RESIZE]: Event;
145
+ [EventType.RENDER]: Event;
146
+ [EventType.ENGINE_STARTED]: Event;
147
+ [EventType.ENGINE_STOPPED]: Event;
148
+ [key: string]: Event;
149
+ }
132
150
  enum EventType {
133
151
  POINTER_DOWN = "pointerDown",
134
152
  POINTER_UP = "pointerUp",
@@ -196,9 +214,7 @@ declare namespace Events {
196
214
  }
197
215
 
198
216
  /**
199
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
200
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
201
- * No code shall be distributed or modified without the permission of the PI.
217
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
202
218
  * @author Judah Silva <silva.judah7@outlook.com>
203
219
  */
204
220
 
@@ -224,7 +240,7 @@ declare class EventManager {
224
240
  * @param callback Callback function to run when the event is triggered
225
241
  * @returns Babylon Observer instance for later removal
226
242
  */
227
- on<T extends Events.Event>(eventType: Events.EventType | string, callback: (event: T) => void): Observer<Events.Event>;
243
+ on<K extends keyof Events.EventMap>(eventType: K, callback: (event: Events.EventMap[K]) => void): Observer<Events.Event>;
228
244
  /**
229
245
  * Remove a registered event observer
230
246
  * @param observer Babylon Observer with the registered callback
@@ -263,9 +279,7 @@ declare class EventManager {
263
279
  }
264
280
 
265
281
  /**
266
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
267
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
268
- * No code shall be distributed or modified without the permission of the PI.
282
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
269
283
  * @author Judah Silva <silva.judah7@outlook.com>
270
284
  */
271
285
 
@@ -318,18 +332,14 @@ declare class RenderScene {
318
332
  }
319
333
 
320
334
  /**
321
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
322
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
323
- * No code shall be distributed or modified without the permission of the PI.
335
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
324
336
  * @author Judah Silva <jusilva@csumb.edu>
325
337
  */
326
338
 
327
339
  declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
328
340
 
329
341
  /**
330
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
331
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
332
- * No code shall be distributed or modified without the permission of the PI.
342
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
333
343
  * @author Sameer Dingore <sdingore@csumb.edu>
334
344
  * @author Judah Silva
335
345
  */
@@ -351,9 +361,7 @@ declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
351
361
  declare function getMotif(motifJSONFileName: string, motifColorHex?: string): Promise<Motif>;
352
362
 
353
363
  /**
354
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
355
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
356
- * No code shall be distributed or modified without the permission of the PI.
364
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
357
365
  * @author Judah Silva
358
366
  */
359
367
  /**
@@ -370,9 +378,7 @@ declare function getPoints(nucleotideData: number[][]): {
370
378
  };
371
379
 
372
380
  /**
373
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
374
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
375
- * No code shall be distributed or modified without the permission of the PI.
381
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
376
382
  * @author Sameer Dingore <sdingore@csumb.edu>
377
383
  */
378
384
 
@@ -384,15 +390,19 @@ interface MotifProps {
384
390
  locked: boolean;
385
391
  position?: Vec3;
386
392
  rotation?: Quat;
393
+ scale?: number;
387
394
  }
388
395
  /**
389
396
  * ________________________________________________________________________________________________
390
- */
391
- interface CustomEventProps {
392
- event: Events.Event;
397
+ */
398
+ interface CustomEventProps<T extends Events.Event = Events.Event> {
393
399
  eventType: Events.EventType;
394
- callback: (event: Events.Event) => void;
400
+ callback: (event: T) => void;
395
401
  }
402
+ /**
403
+ * ________________________________________________________________________________________________
404
+ */
405
+ type AnyEventProps = CustomEventProps<Events.Event> | CustomEventProps<Events.KeyboardEvent> | CustomEventProps<Events.PinchEvent> | CustomEventProps<Events.PointerEvent> | CustomEventProps<Events.SelectionEvent>;
396
406
  /**
397
407
  * ________________________________________________________________________________________________
398
408
  */
@@ -404,13 +414,11 @@ interface CanvasProps {
404
414
  rendererSizeIsWindow?: boolean;
405
415
  cameraPositionZ?: number;
406
416
  motifProps: MotifProps[];
407
- customEventProps?: CustomEventProps[];
417
+ customEventProps?: AnyEventProps[];
408
418
  }
409
419
 
410
420
  /**
411
421
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
412
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
413
- * No code shall be distributed or modified without the permission of the PI.
414
422
  * @author Sameer Dingore <sdingore@csumb.edu>
415
423
  * @author Judah Silva <silva.judah7@outlook.com>
416
424
  */
@@ -428,8 +436,6 @@ declare function Canvas({ rendererHeight, rendererWidth, rendererBackgroundColor
428
436
 
429
437
  /**
430
438
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
431
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
432
- * No code shall be distributed or modified without the permission of the PI.
433
439
  * @author Judah Silva <silva.judah7@outlook.com>
434
440
  */
435
441
  interface ScoreInfo {
@@ -465,9 +471,7 @@ declare class CanvasDataManager {
465
471
  }
466
472
 
467
473
  /**
468
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
469
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
470
- * No code shall be distributed or modified without the permission of the PI.
474
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
471
475
  * @author Sameer Dingore <sdingore@csumb.edu>
472
476
  * @author Judah Silva <jusilva@csumb.edu>
473
477
  */
@@ -484,18 +488,14 @@ declare function kabschSlidingWindow(motif1: Motif, motif2: Motif): {
484
488
  declare function calculateAllKabschRMSD(motifMeshArray: Motif[]): number[][];
485
489
 
486
490
  /**
487
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
488
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
489
- * No code shall be distributed or modified without the permission of the PI.
491
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
490
492
  * @author Judah Silva <jusilva@csumb.edu>
491
493
  */
492
494
 
493
495
  declare function calculateRMSD(selectedMotifMeshArray: Motif[], motifMeshArray: Motif[]): ScoreInfo[][];
494
496
 
495
497
  /**
496
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
497
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
498
- * No code shall be distributed or modified without the permission of the PI.
498
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
499
499
  * @author Sameer Dingore <sdingore@csumb.edu>
500
500
  * @author Shahidul Islam <sislam@csumb.edu>
501
501
  */
@@ -517,9 +517,7 @@ declare function getRMSD(motif1: Motif, motif2: Motif): number;
517
517
  declare function calculateRMSDSlide(coordinates1: Vec3[], coordinates2: Vec3[]): number;
518
518
 
519
519
  /**
520
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
521
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
522
- * No code shall be distributed or modified without the permission of the PI.
520
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
523
521
  * @author Judah Silva <jusilva@csumb.edu>
524
522
  */
525
523
 
package/dist/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { Mesh, TransformNode, Scene, Matrix, Nullable, Quaternion, Observer, Engine, UniversalCamera } from '@babylonjs/core';
2
2
 
3
3
  /**
4
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
5
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
6
- * No code shall be distributed or modified without the permission of the PI.
4
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
7
5
  * @author Judah Silva <silva.judah7@outlook.com>
8
6
  */
9
7
 
@@ -14,9 +12,7 @@ declare class Residue extends Group<MeshObject> {
14
12
  }
15
13
 
16
14
  /**
17
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
18
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
19
- * No code shall be distributed or modified without the permission of the PI.
15
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
20
16
  * @author Judah Silva <silva.judah7@outlook.com>
21
17
  */
22
18
 
@@ -39,9 +35,7 @@ declare class MeshObject {
39
35
  }
40
36
 
41
37
  /**
42
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
43
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
44
- * No code shall be distributed or modified without the permission of the PI.
38
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
45
39
  * @author Judah Silva <silva.judah7@outlook.com>
46
40
  */
47
41
 
@@ -66,10 +60,16 @@ declare class Quat {
66
60
  private _quaternion;
67
61
  constructor();
68
62
  rotateByQuaternion(quaternion: Quat): void;
69
- setToQuaternion(quaternion: Nullable<Quaternion>): void;
63
+ setToQuaternion(quaternion: Nullable<Quaternion>): this;
70
64
  setFromMatrix(matrix: Matrix4): this;
71
65
  setFromEuler(eulerAngle: Vec3): this;
66
+ setFromValues(w: number, x: number, y: number, z: number): this;
67
+ toArray(): number[];
72
68
  get quaternion(): Quaternion;
69
+ get w(): number;
70
+ get x(): number;
71
+ get y(): number;
72
+ get z(): number;
73
73
  }
74
74
 
75
75
  declare class Vec3 {
@@ -90,9 +90,7 @@ declare class Vec3 {
90
90
  }
91
91
 
92
92
  /**
93
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
94
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
95
- * No code shall be distributed or modified without the permission of the PI.
93
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
96
94
  * @author Judah Silva <silva.judah7@outlook.com>
97
95
  */
98
96
 
@@ -118,17 +116,37 @@ declare class Motif extends Group<Residue> {
118
116
  private _nanCheck;
119
117
  get uuid(): string;
120
118
  get quat(): Quat;
119
+ get scale(): number;
121
120
  get position(): Vec3;
122
121
  }
123
122
 
124
123
  /**
125
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
126
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
127
- * No code shall be distributed or modified without the permission of the PI.
124
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
128
125
  * @author Judah Silva <silva.judah7@outlook.com>
129
126
  */
130
127
 
131
128
  declare namespace Events {
129
+ interface EventMap {
130
+ [EventType.POINTER_DOWN]: PointerEvent;
131
+ [EventType.POINTER_UP]: PointerEvent;
132
+ [EventType.POINTER_MOVE]: PointerEvent;
133
+ [EventType.POINTER_WHEEL]: PointerEvent;
134
+ [EventType.KEY_DOWN]: KeyboardEvent;
135
+ [EventType.KEY_UP]: KeyboardEvent;
136
+ [EventType.TOUCH_START]: PointerEvent;
137
+ [EventType.TOUCH_END]: PointerEvent;
138
+ [EventType.TOUCH_MOVE]: PointerEvent;
139
+ [EventType.PINCH_START]: PinchEvent;
140
+ [EventType.PINCH]: PinchEvent;
141
+ [EventType.PINCH_END]: PinchEvent;
142
+ [EventType.OBJECT_SELECTED]: SelectionEvent;
143
+ [EventType.OBJECT_DESELECTED]: SelectionEvent;
144
+ [EventType.RESIZE]: Event;
145
+ [EventType.RENDER]: Event;
146
+ [EventType.ENGINE_STARTED]: Event;
147
+ [EventType.ENGINE_STOPPED]: Event;
148
+ [key: string]: Event;
149
+ }
132
150
  enum EventType {
133
151
  POINTER_DOWN = "pointerDown",
134
152
  POINTER_UP = "pointerUp",
@@ -196,9 +214,7 @@ declare namespace Events {
196
214
  }
197
215
 
198
216
  /**
199
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
200
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
201
- * No code shall be distributed or modified without the permission of the PI.
217
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
202
218
  * @author Judah Silva <silva.judah7@outlook.com>
203
219
  */
204
220
 
@@ -224,7 +240,7 @@ declare class EventManager {
224
240
  * @param callback Callback function to run when the event is triggered
225
241
  * @returns Babylon Observer instance for later removal
226
242
  */
227
- on<T extends Events.Event>(eventType: Events.EventType | string, callback: (event: T) => void): Observer<Events.Event>;
243
+ on<K extends keyof Events.EventMap>(eventType: K, callback: (event: Events.EventMap[K]) => void): Observer<Events.Event>;
228
244
  /**
229
245
  * Remove a registered event observer
230
246
  * @param observer Babylon Observer with the registered callback
@@ -263,9 +279,7 @@ declare class EventManager {
263
279
  }
264
280
 
265
281
  /**
266
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
267
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
268
- * No code shall be distributed or modified without the permission of the PI.
282
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
269
283
  * @author Judah Silva <silva.judah7@outlook.com>
270
284
  */
271
285
 
@@ -318,18 +332,14 @@ declare class RenderScene {
318
332
  }
319
333
 
320
334
  /**
321
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
322
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
323
- * No code shall be distributed or modified without the permission of the PI.
335
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
324
336
  * @author Judah Silva <jusilva@csumb.edu>
325
337
  */
326
338
 
327
339
  declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
328
340
 
329
341
  /**
330
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
331
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
332
- * No code shall be distributed or modified without the permission of the PI.
342
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
333
343
  * @author Sameer Dingore <sdingore@csumb.edu>
334
344
  * @author Judah Silva
335
345
  */
@@ -351,9 +361,7 @@ declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
351
361
  declare function getMotif(motifJSONFileName: string, motifColorHex?: string): Promise<Motif>;
352
362
 
353
363
  /**
354
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
355
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
356
- * No code shall be distributed or modified without the permission of the PI.
364
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
357
365
  * @author Judah Silva
358
366
  */
359
367
  /**
@@ -370,9 +378,7 @@ declare function getPoints(nucleotideData: number[][]): {
370
378
  };
371
379
 
372
380
  /**
373
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
374
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
375
- * No code shall be distributed or modified without the permission of the PI.
381
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
376
382
  * @author Sameer Dingore <sdingore@csumb.edu>
377
383
  */
378
384
 
@@ -384,15 +390,19 @@ interface MotifProps {
384
390
  locked: boolean;
385
391
  position?: Vec3;
386
392
  rotation?: Quat;
393
+ scale?: number;
387
394
  }
388
395
  /**
389
396
  * ________________________________________________________________________________________________
390
- */
391
- interface CustomEventProps {
392
- event: Events.Event;
397
+ */
398
+ interface CustomEventProps<T extends Events.Event = Events.Event> {
393
399
  eventType: Events.EventType;
394
- callback: (event: Events.Event) => void;
400
+ callback: (event: T) => void;
395
401
  }
402
+ /**
403
+ * ________________________________________________________________________________________________
404
+ */
405
+ type AnyEventProps = CustomEventProps<Events.Event> | CustomEventProps<Events.KeyboardEvent> | CustomEventProps<Events.PinchEvent> | CustomEventProps<Events.PointerEvent> | CustomEventProps<Events.SelectionEvent>;
396
406
  /**
397
407
  * ________________________________________________________________________________________________
398
408
  */
@@ -404,13 +414,11 @@ interface CanvasProps {
404
414
  rendererSizeIsWindow?: boolean;
405
415
  cameraPositionZ?: number;
406
416
  motifProps: MotifProps[];
407
- customEventProps?: CustomEventProps[];
417
+ customEventProps?: AnyEventProps[];
408
418
  }
409
419
 
410
420
  /**
411
421
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
412
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
413
- * No code shall be distributed or modified without the permission of the PI.
414
422
  * @author Sameer Dingore <sdingore@csumb.edu>
415
423
  * @author Judah Silva <silva.judah7@outlook.com>
416
424
  */
@@ -428,8 +436,6 @@ declare function Canvas({ rendererHeight, rendererWidth, rendererBackgroundColor
428
436
 
429
437
  /**
430
438
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
431
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
432
- * No code shall be distributed or modified without the permission of the PI.
433
439
  * @author Judah Silva <silva.judah7@outlook.com>
434
440
  */
435
441
  interface ScoreInfo {
@@ -465,9 +471,7 @@ declare class CanvasDataManager {
465
471
  }
466
472
 
467
473
  /**
468
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
469
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
470
- * No code shall be distributed or modified without the permission of the PI.
474
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
471
475
  * @author Sameer Dingore <sdingore@csumb.edu>
472
476
  * @author Judah Silva <jusilva@csumb.edu>
473
477
  */
@@ -484,18 +488,14 @@ declare function kabschSlidingWindow(motif1: Motif, motif2: Motif): {
484
488
  declare function calculateAllKabschRMSD(motifMeshArray: Motif[]): number[][];
485
489
 
486
490
  /**
487
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
488
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
489
- * No code shall be distributed or modified without the permission of the PI.
491
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
490
492
  * @author Judah Silva <jusilva@csumb.edu>
491
493
  */
492
494
 
493
495
  declare function calculateRMSD(selectedMotifMeshArray: Motif[], motifMeshArray: Motif[]): ScoreInfo[][];
494
496
 
495
497
  /**
496
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
497
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
498
- * No code shall be distributed or modified without the permission of the PI.
498
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
499
499
  * @author Sameer Dingore <sdingore@csumb.edu>
500
500
  * @author Shahidul Islam <sislam@csumb.edu>
501
501
  */
@@ -517,9 +517,7 @@ declare function getRMSD(motif1: Motif, motif2: Motif): number;
517
517
  declare function calculateRMSDSlide(coordinates1: Vec3[], coordinates2: Vec3[]): number;
518
518
 
519
519
  /**
520
- * Copyright (c) 2024 RNA3DS Lab CSUMB.
521
- * All code written for RNA3DS Lab is protected under the terms of the NDA.
522
- * No code shall be distributed or modified without the permission of the PI.
520
+ * Copyright (c) 2025 RNA3DS Lab CSUMB.
523
521
  * @author Judah Silva <jusilva@csumb.edu>
524
522
  */
525
523
 
package/dist/index.js CHANGED
@@ -145,7 +145,8 @@ var Quat = class {
145
145
  if (quaternion === null) {
146
146
  throw new Error("Cannot set to null quaternion");
147
147
  }
148
- this._quaternion = quaternion;
148
+ this.setFromValues(quaternion.w, quaternion.x, quaternion.y, quaternion.z);
149
+ return this;
149
150
  }
150
151
  setFromMatrix(matrix) {
151
152
  this._quaternion = import_core3.Quaternion.FromRotationMatrix(matrix.matrix);
@@ -155,9 +156,30 @@ var Quat = class {
155
156
  this._quaternion = import_core3.Quaternion.FromEulerAngles(eulerAngle.x, eulerAngle.y, eulerAngle.z);
156
157
  return this;
157
158
  }
159
+ setFromValues(w, x, y, z) {
160
+ this._quaternion.set(x, y, z, w);
161
+ return this;
162
+ }
163
+ toArray() {
164
+ const quatArr = [];
165
+ this._quaternion.toArray(quatArr);
166
+ return quatArr;
167
+ }
158
168
  get quaternion() {
159
169
  return this._quaternion;
160
170
  }
171
+ get w() {
172
+ return this._quaternion.w;
173
+ }
174
+ get x() {
175
+ return this._quaternion.x;
176
+ }
177
+ get y() {
178
+ return this._quaternion.y;
179
+ }
180
+ get z() {
181
+ return this._quaternion.z;
182
+ }
161
183
  };
162
184
 
163
185
  // src/Math/Matrix4.ts
@@ -261,9 +283,15 @@ var Motif = class extends Group {
261
283
  return this._node.uniqueId.toString();
262
284
  }
263
285
  get quat() {
286
+ if (this._node.rotationQuaternion === null) {
287
+ this._node.rotationQuaternion = this._node.rotation.toQuaternion();
288
+ }
264
289
  this._quat.setToQuaternion(this._node.rotationQuaternion);
265
290
  return this._quat;
266
291
  }
292
+ get scale() {
293
+ return this._node.scaling.x;
294
+ }
267
295
  get position() {
268
296
  return new Vec3(
269
297
  this._node.absolutePosition.x,
@@ -1405,11 +1433,11 @@ function Canvas({
1405
1433
  });
1406
1434
  if (scene.current.children.size !== motifs.length) {
1407
1435
  motifs.forEach((motifMesh, index) => {
1408
- if (motifProps[index].position) positions[index] = motifProps[index].position;
1436
+ scene.current?.add(motifMesh);
1437
+ if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
1409
1438
  motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
1410
- if (motifProps[index].rotation) motifMesh.setQuaternion(motifProps[index].rotation);
1439
+ if (motifProps[index].rotation) motifMesh.quat.setToQuaternion(motifProps[index].rotation.quaternion);
1411
1440
  motifMesh.multiplyScalar(canvasRef.current.width / 250);
1412
- scene.current?.add(motifMesh);
1413
1441
  });
1414
1442
  const eventManager = scene.current?.eventManager;
1415
1443
  eventManager.on(Events.EventType.OBJECT_SELECTED, onSelectMotif);
@@ -1423,10 +1451,53 @@ function Canvas({
1423
1451
  eventManager.on(Events.EventType.KEY_DOWN, onKeyboardSelect);
1424
1452
  if (customEventProps) {
1425
1453
  customEventProps.forEach((customEventProp) => {
1426
- eventManager.on(
1427
- customEventProp.eventType,
1428
- customEventProp.callback
1429
- );
1454
+ switch (customEventProp.eventType) {
1455
+ // Handle Pointer Events
1456
+ case Events.EventType.POINTER_DOWN:
1457
+ case Events.EventType.POINTER_UP:
1458
+ case Events.EventType.POINTER_MOVE:
1459
+ case Events.EventType.POINTER_WHEEL:
1460
+ case Events.EventType.TOUCH_END:
1461
+ case Events.EventType.TOUCH_MOVE:
1462
+ case Events.EventType.TOUCH_START:
1463
+ eventManager.on(
1464
+ customEventProp.eventType,
1465
+ customEventProp.callback
1466
+ );
1467
+ break;
1468
+ // Handle Keyboard Events
1469
+ case Events.EventType.KEY_DOWN:
1470
+ case Events.EventType.KEY_UP:
1471
+ eventManager.on(
1472
+ customEventProp.eventType,
1473
+ customEventProp.callback
1474
+ );
1475
+ break;
1476
+ // Handle Pinch Events
1477
+ case Events.EventType.PINCH:
1478
+ case Events.EventType.PINCH_END:
1479
+ case Events.EventType.PINCH_START:
1480
+ eventManager.on(
1481
+ customEventProp.eventType,
1482
+ customEventProp.callback
1483
+ );
1484
+ break;
1485
+ // Handle Selection Events
1486
+ case Events.EventType.OBJECT_SELECTED:
1487
+ case Events.EventType.OBJECT_DESELECTED:
1488
+ eventManager.on(
1489
+ customEventProp.eventType,
1490
+ customEventProp.callback
1491
+ );
1492
+ break;
1493
+ // Handle Events
1494
+ default:
1495
+ eventManager.on(
1496
+ customEventProp.eventType,
1497
+ customEventProp.callback
1498
+ );
1499
+ break;
1500
+ }
1430
1501
  });
1431
1502
  }
1432
1503
  } else {
package/dist/index.mjs CHANGED
@@ -88,7 +88,8 @@ var Quat = class {
88
88
  if (quaternion === null) {
89
89
  throw new Error("Cannot set to null quaternion");
90
90
  }
91
- this._quaternion = quaternion;
91
+ this.setFromValues(quaternion.w, quaternion.x, quaternion.y, quaternion.z);
92
+ return this;
92
93
  }
93
94
  setFromMatrix(matrix) {
94
95
  this._quaternion = Quaternion2.FromRotationMatrix(matrix.matrix);
@@ -98,9 +99,30 @@ var Quat = class {
98
99
  this._quaternion = Quaternion2.FromEulerAngles(eulerAngle.x, eulerAngle.y, eulerAngle.z);
99
100
  return this;
100
101
  }
102
+ setFromValues(w, x, y, z) {
103
+ this._quaternion.set(x, y, z, w);
104
+ return this;
105
+ }
106
+ toArray() {
107
+ const quatArr = [];
108
+ this._quaternion.toArray(quatArr);
109
+ return quatArr;
110
+ }
101
111
  get quaternion() {
102
112
  return this._quaternion;
103
113
  }
114
+ get w() {
115
+ return this._quaternion.w;
116
+ }
117
+ get x() {
118
+ return this._quaternion.x;
119
+ }
120
+ get y() {
121
+ return this._quaternion.y;
122
+ }
123
+ get z() {
124
+ return this._quaternion.z;
125
+ }
104
126
  };
105
127
 
106
128
  // src/Math/Matrix4.ts
@@ -204,9 +226,15 @@ var Motif = class extends Group {
204
226
  return this._node.uniqueId.toString();
205
227
  }
206
228
  get quat() {
229
+ if (this._node.rotationQuaternion === null) {
230
+ this._node.rotationQuaternion = this._node.rotation.toQuaternion();
231
+ }
207
232
  this._quat.setToQuaternion(this._node.rotationQuaternion);
208
233
  return this._quat;
209
234
  }
235
+ get scale() {
236
+ return this._node.scaling.x;
237
+ }
210
238
  get position() {
211
239
  return new Vec3(
212
240
  this._node.absolutePosition.x,
@@ -1348,11 +1376,11 @@ function Canvas({
1348
1376
  });
1349
1377
  if (scene.current.children.size !== motifs.length) {
1350
1378
  motifs.forEach((motifMesh, index) => {
1351
- if (motifProps[index].position) positions[index] = motifProps[index].position;
1379
+ scene.current?.add(motifMesh);
1380
+ if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
1352
1381
  motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
1353
- if (motifProps[index].rotation) motifMesh.setQuaternion(motifProps[index].rotation);
1382
+ if (motifProps[index].rotation) motifMesh.quat.setToQuaternion(motifProps[index].rotation.quaternion);
1354
1383
  motifMesh.multiplyScalar(canvasRef.current.width / 250);
1355
- scene.current?.add(motifMesh);
1356
1384
  });
1357
1385
  const eventManager = scene.current?.eventManager;
1358
1386
  eventManager.on(Events.EventType.OBJECT_SELECTED, onSelectMotif);
@@ -1366,10 +1394,53 @@ function Canvas({
1366
1394
  eventManager.on(Events.EventType.KEY_DOWN, onKeyboardSelect);
1367
1395
  if (customEventProps) {
1368
1396
  customEventProps.forEach((customEventProp) => {
1369
- eventManager.on(
1370
- customEventProp.eventType,
1371
- customEventProp.callback
1372
- );
1397
+ switch (customEventProp.eventType) {
1398
+ // Handle Pointer Events
1399
+ case Events.EventType.POINTER_DOWN:
1400
+ case Events.EventType.POINTER_UP:
1401
+ case Events.EventType.POINTER_MOVE:
1402
+ case Events.EventType.POINTER_WHEEL:
1403
+ case Events.EventType.TOUCH_END:
1404
+ case Events.EventType.TOUCH_MOVE:
1405
+ case Events.EventType.TOUCH_START:
1406
+ eventManager.on(
1407
+ customEventProp.eventType,
1408
+ customEventProp.callback
1409
+ );
1410
+ break;
1411
+ // Handle Keyboard Events
1412
+ case Events.EventType.KEY_DOWN:
1413
+ case Events.EventType.KEY_UP:
1414
+ eventManager.on(
1415
+ customEventProp.eventType,
1416
+ customEventProp.callback
1417
+ );
1418
+ break;
1419
+ // Handle Pinch Events
1420
+ case Events.EventType.PINCH:
1421
+ case Events.EventType.PINCH_END:
1422
+ case Events.EventType.PINCH_START:
1423
+ eventManager.on(
1424
+ customEventProp.eventType,
1425
+ customEventProp.callback
1426
+ );
1427
+ break;
1428
+ // Handle Selection Events
1429
+ case Events.EventType.OBJECT_SELECTED:
1430
+ case Events.EventType.OBJECT_DESELECTED:
1431
+ eventManager.on(
1432
+ customEventProp.eventType,
1433
+ customEventProp.callback
1434
+ );
1435
+ break;
1436
+ // Handle Events
1437
+ default:
1438
+ eventManager.on(
1439
+ customEventProp.eventType,
1440
+ customEventProp.callback
1441
+ );
1442
+ break;
1443
+ }
1373
1444
  });
1374
1445
  }
1375
1446
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@judah-silva/rnacanvas",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "A 3D Canvas for displaying and interacting with custom RNA models. Powered by BabylonJS.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -21,9 +21,10 @@
21
21
  "react": "18.2.0"
22
22
  },
23
23
  "devDependencies": {
24
- "tsup": "^8.4.0",
25
- "typescript": "^5.8.3",
24
+ "@types/estree": "^1.0.7",
26
25
  "@types/numeric": "1.2.6",
27
- "@types/react": "18.2.35"
26
+ "@types/react": "18.2.35",
27
+ "tsup": "^8.4.0",
28
+ "typescript": "^5.8.3"
28
29
  }
29
30
  }
Binary file