@judah-silva/rnacanvas 0.0.4 → 0.0.6

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/README.md CHANGED
@@ -129,8 +129,3 @@ const props: MotifProps = {
129
129
  locked: false,
130
130
  };
131
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
@@ -112,6 +112,7 @@ declare class Motif extends Group<Residue> {
112
112
  rotateByQuaternion(quat: Quat): void;
113
113
  setQuaternion(quat: Quat): void;
114
114
  multiplyScalar(scalar: number): void;
115
+ setScale(scale: number): void;
115
116
  get uuid(): string;
116
117
  get quat(): Quat;
117
118
  get scale(): number;
@@ -334,7 +335,7 @@ declare class RenderScene {
334
335
  * @author Judah Silva <jusilva@csumb.edu>
335
336
  */
336
337
 
337
- declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
338
+ declare function parseAtomCoords(meshObject: MotifMesh): Promise<Vec3[]>;
338
339
 
339
340
  /**
340
341
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
@@ -342,6 +343,7 @@ declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
342
343
  * @author Judah Silva
343
344
  */
344
345
 
346
+ type MotifMesh = Record<string, any>;
345
347
  /**
346
348
  * ________________________________________________________________________________________________
347
349
  */
@@ -356,7 +358,7 @@ declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
356
358
  * @returns {Promise<Motif>}
357
359
  * @async
358
360
  */
359
- declare function getMotif(motifJSONFileName: string, motifColorHex?: string): Promise<Motif>;
361
+ declare function getMotif(motifName: string, motifMesh: MotifMesh, motifColorHex?: string): Promise<Motif>;
360
362
 
361
363
  /**
362
364
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
@@ -521,4 +523,4 @@ declare function calculateRMSDSlide(coordinates1: Vec3[], coordinates2: Vec3[]):
521
523
 
522
524
  declare function rotateAllPoints(atomCoords: Vec3[], quat: Quat): Vec3[];
523
525
 
524
- export { Canvas, CanvasAttributeTypes, CanvasDataManager, type CanvasProps, type CustomEventProps, EventManager, Events, Group, Matrix4, MeshObject, Motif, type MotifProps, Quat, RenderScene, Residue, type ScoreInfo, Vec3, calculateAllKabschRMSD, calculateRMSD, calculateRMSDSlide, getMotif, getPoints, getRMSD, kabschSlidingWindow, rotateAllPoints, updateAllMotifs };
526
+ export { Canvas, CanvasAttributeTypes, CanvasDataManager, type CanvasProps, type CustomEventProps, EventManager, Events, Group, Matrix4, MeshObject, Motif, type MotifMesh, type MotifProps, Quat, RenderScene, Residue, type ScoreInfo, Vec3, calculateAllKabschRMSD, calculateRMSD, calculateRMSDSlide, getMotif, getPoints, getRMSD, kabschSlidingWindow, parseAtomCoords, rotateAllPoints };
package/dist/index.d.ts CHANGED
@@ -112,6 +112,7 @@ declare class Motif extends Group<Residue> {
112
112
  rotateByQuaternion(quat: Quat): void;
113
113
  setQuaternion(quat: Quat): void;
114
114
  multiplyScalar(scalar: number): void;
115
+ setScale(scale: number): void;
115
116
  get uuid(): string;
116
117
  get quat(): Quat;
117
118
  get scale(): number;
@@ -334,7 +335,7 @@ declare class RenderScene {
334
335
  * @author Judah Silva <jusilva@csumb.edu>
335
336
  */
336
337
 
337
- declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
338
+ declare function parseAtomCoords(meshObject: MotifMesh): Promise<Vec3[]>;
338
339
 
339
340
  /**
340
341
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
@@ -342,6 +343,7 @@ declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
342
343
  * @author Judah Silva
343
344
  */
344
345
 
346
+ type MotifMesh = Record<string, any>;
345
347
  /**
346
348
  * ________________________________________________________________________________________________
347
349
  */
@@ -356,7 +358,7 @@ declare function updateAllMotifs(motifMeshArray: Motif[]): Promise<void>;
356
358
  * @returns {Promise<Motif>}
357
359
  * @async
358
360
  */
359
- declare function getMotif(motifJSONFileName: string, motifColorHex?: string): Promise<Motif>;
361
+ declare function getMotif(motifName: string, motifMesh: MotifMesh, motifColorHex?: string): Promise<Motif>;
360
362
 
361
363
  /**
362
364
  * Copyright (c) 2025 RNA3DS Lab CSUMB.
@@ -521,4 +523,4 @@ declare function calculateRMSDSlide(coordinates1: Vec3[], coordinates2: Vec3[]):
521
523
 
522
524
  declare function rotateAllPoints(atomCoords: Vec3[], quat: Quat): Vec3[];
523
525
 
524
- export { Canvas, CanvasAttributeTypes, CanvasDataManager, type CanvasProps, type CustomEventProps, EventManager, Events, Group, Matrix4, MeshObject, Motif, type MotifProps, Quat, RenderScene, Residue, type ScoreInfo, Vec3, calculateAllKabschRMSD, calculateRMSD, calculateRMSDSlide, getMotif, getPoints, getRMSD, kabschSlidingWindow, rotateAllPoints, updateAllMotifs };
526
+ export { Canvas, CanvasAttributeTypes, CanvasDataManager, type CanvasProps, type CustomEventProps, EventManager, Events, Group, Matrix4, MeshObject, Motif, type MotifMesh, type MotifProps, Quat, RenderScene, Residue, type ScoreInfo, Vec3, calculateAllKabschRMSD, calculateRMSD, calculateRMSDSlide, getMotif, getPoints, getRMSD, kabschSlidingWindow, parseAtomCoords, rotateAllPoints };
package/dist/index.js CHANGED
@@ -50,8 +50,8 @@ __export(index_exports, {
50
50
  getPoints: () => getPoints,
51
51
  getRMSD: () => getRMSD,
52
52
  kabschSlidingWindow: () => kabschSlidingWindow,
53
- rotateAllPoints: () => rotateAllPoints,
54
- updateAllMotifs: () => updateAllMotifs
53
+ parseAtomCoords: () => parseAtomCoords,
54
+ rotateAllPoints: () => rotateAllPoints
55
55
  });
56
56
  module.exports = __toCommonJS(index_exports);
57
57
 
@@ -269,6 +269,13 @@ var Motif = class extends Group {
269
269
  this._node.scaling.z * scalar
270
270
  );
271
271
  }
272
+ setScale(scale) {
273
+ this._node.scaling = new import_core5.Vector3(
274
+ scale,
275
+ scale,
276
+ scale
277
+ );
278
+ }
272
279
  get uuid() {
273
280
  return this._node.uniqueId.toString();
274
281
  }
@@ -813,12 +820,10 @@ var RenderScene = class {
813
820
  };
814
821
 
815
822
  // src/3D/utils/GetAtomInfo.ts
816
- async function parseAtomCoords(fileName) {
817
- const response = await fetch(`/${fileName}`);
818
- const jsonData = await response.json();
823
+ async function parseAtomCoords(meshObject) {
819
824
  const coordinates = [];
820
- for (const [key] of Object.entries(jsonData)) {
821
- const atomMap = jsonData[key][0];
825
+ for (const [key] of Object.entries(meshObject)) {
826
+ const atomMap = meshObject[key][0];
822
827
  if (atomMap[`"C1'"`]) {
823
828
  coordinates.push(
824
829
  new Vec3(
@@ -831,20 +836,6 @@ async function parseAtomCoords(fileName) {
831
836
  }
832
837
  return coordinates;
833
838
  }
834
- async function getAtomCoords(fileName) {
835
- const coordinates = await parseAtomCoords(fileName);
836
- return coordinates;
837
- }
838
- async function updateAllMotifs(motifMeshArray) {
839
- const fileNames = [];
840
- for (const motif of motifMeshArray) {
841
- fileNames.push(motif.userData.fileName);
842
- }
843
- const atomInfoLists = await Promise.all(fileNames.map((o) => getAtomCoords(o)));
844
- for (let i = 0; i < motifMeshArray.length; i += 1) {
845
- motifMeshArray[i].userData.atomInfo = atomInfoLists[i];
846
- }
847
- }
848
839
 
849
840
  // src/3D/utils/GetPoints.ts
850
841
  function getPoints(nucleotideData) {
@@ -858,12 +849,10 @@ function getPoints(nucleotideData) {
858
849
  }
859
850
 
860
851
  // src/3D/utils/GetMotif.ts
861
- async function getMotif(motifJSONFileName, motifColorHex = "0xcc2900") {
862
- const motif = new Motif(`${motifJSONFileName}_motif`);
863
- const motifJSONFileData = await fetch(`/${motifJSONFileName}`);
864
- const jsonObject = await motifJSONFileData.json();
865
- for (const [key] of Object.entries(jsonObject)) {
866
- const { vertices, indices } = getPoints(jsonObject[key]);
852
+ async function getMotif(motifName, motifMesh, motifColorHex = "0xcc2900") {
853
+ const motif = new Motif(`${motifName}_motif`);
854
+ for (const [key] of Object.entries(motifMesh)) {
855
+ const { vertices, indices } = getPoints(motifMesh[key]);
867
856
  const residue = new Residue("residue");
868
857
  const backboneMesh = new MeshObject(`backbone_${key}`);
869
858
  backboneMesh.applyVertexData(vertices[0], indices[0]);
@@ -875,7 +864,8 @@ async function getMotif(motifJSONFileName, motifColorHex = "0xcc2900") {
875
864
  residue.addChild(ringMesh);
876
865
  motif.addChild(residue);
877
866
  }
878
- motif.userData.fileName = motifJSONFileName;
867
+ motif.userData.fileName = motifName;
868
+ motif.userData.atomInfo = await parseAtomCoords(motifMesh);
879
869
  return motif;
880
870
  }
881
871
 
@@ -970,6 +960,7 @@ function getRMSD(a, b) {
970
960
  if (a instanceof Motif && b instanceof Motif) {
971
961
  newCoords1 = rotateAllPoints(a.userData.atomInfo, a.quat);
972
962
  newCoords2 = rotateAllPoints(b.userData.atomInfo, b.quat);
963
+ return calculateRMSDSlide(newCoords1, newCoords2);
973
964
  } else {
974
965
  return -1;
975
966
  }
@@ -1163,7 +1154,7 @@ function Canvas({
1163
1154
  const [kabschRMSD, setKabschRMSD] = (0, import_react.useState)([]);
1164
1155
  const [lockedMotifIds, setLockedMotifIds] = (0, import_react.useState)([]);
1165
1156
  const addMotif = (motif) => {
1166
- if (selectedMotifIds.has(motif.uuid)) {
1157
+ if (selectedMotifMeshState.current.has(motif)) {
1167
1158
  return;
1168
1159
  }
1169
1160
  const newSet = /* @__PURE__ */ new Set();
@@ -1176,12 +1167,12 @@ function Canvas({
1176
1167
  selectedMotifMeshState.current.add(motif);
1177
1168
  };
1178
1169
  const removeMotif = (motif) => {
1179
- if (!selectedMotifIds.has(motif.uuid)) {
1170
+ if (!selectedMotifMeshState.current.has(motif)) {
1180
1171
  return;
1181
1172
  }
1182
1173
  selectedMotifMeshState.current.delete(motif);
1183
1174
  setSelectedmotifIds((prevState) => {
1184
- const newState = prevState;
1175
+ const newState = new Set(prevState);
1185
1176
  newState.delete(motif.uuid);
1186
1177
  return newState;
1187
1178
  });
@@ -1266,10 +1257,12 @@ function Canvas({
1266
1257
  const zoomSpeed = 0.1;
1267
1258
  const zoomDirection = event.originalEvent.deltaY > 0 ? -1 : 1;
1268
1259
  selectedMotifMeshState.current.forEach((element) => {
1269
- if (!lockedMotifIdState.current.includes(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
1260
+ if (!lockedMotifIdState.current.includes(element.uuid) && !hardLockedMotifIds.includes(element.uuid) && !(element.scale <= 1 && zoomDirection === -1) && !(element.scale >= 30 && zoomDirection === 1)) {
1270
1261
  const scaleFactor = 1 + zoomDirection * zoomSpeed;
1271
1262
  element.multiplyScalar(scaleFactor);
1272
1263
  }
1264
+ if (element.scale < 1) element.setScale(1);
1265
+ if (element.scale > 30) element.setScale(30);
1273
1266
  });
1274
1267
  }
1275
1268
  }
@@ -1317,7 +1310,7 @@ function Canvas({
1317
1310
  if (!event.rotationAxis.equals(Vec3.Zero) || !event.translationDirection.equals(Vec3.Zero)) {
1318
1311
  return;
1319
1312
  }
1320
- if (!/^[0-9]$/.test(event.key)) {
1313
+ if (!/^[1-9]$/.test(event.key) || Number(event.key) > motifs.length) {
1321
1314
  return;
1322
1315
  }
1323
1316
  const motif = motifs[Number(event.key) - 1];
@@ -1342,6 +1335,21 @@ function Canvas({
1342
1335
  }
1343
1336
  return positions;
1344
1337
  };
1338
+ const updateMotifs = () => {
1339
+ const positions = calculatePositions(motifs.length);
1340
+ motifs.forEach((motifMesh, index) => {
1341
+ if (!scene.current?.children.has(motifMesh.uuid)) return;
1342
+ if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
1343
+ motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
1344
+ if (motifProps[index].rotation) motifMesh.setQuaternion(motifProps[index].rotation);
1345
+ let scale = canvasRef.current.width / 250;
1346
+ if (motifProps[index].scale) scale = motifProps[index].scale;
1347
+ motifMesh.setScale(scale);
1348
+ });
1349
+ };
1350
+ (0, import_react.useEffect)(() => {
1351
+ updateMotifs();
1352
+ }, [motifProps]);
1345
1353
  (0, import_react.useEffect)(() => {
1346
1354
  const unsubscribe = CanvasDataManager.subscribe("selectedMotifs" /* SELECTED_MOTIFS */, () => {
1347
1355
  setSelectedmotifIds(CanvasDataManager.selectedMotifIds);
@@ -1396,6 +1404,8 @@ function Canvas({
1396
1404
  (0, import_react.useEffect)(() => {
1397
1405
  if (CanvasDataManager.kabschRMSD !== kabschRMSD) {
1398
1406
  CanvasDataManager.setKabschRMSD(kabschRMSD);
1407
+ } else if (CanvasDataManager.kabschRMSD.length !== motifs.length) {
1408
+ CanvasDataManager.setKabschRMSD(calculateAllKabschRMSD(motifs));
1399
1409
  }
1400
1410
  }, [kabschRMSD]);
1401
1411
  (0, import_react.useEffect)(() => {
@@ -1415,12 +1425,10 @@ function Canvas({
1415
1425
  rendererSizeIsWindow ? window.innerHeight : rendererHeight
1416
1426
  );
1417
1427
  }
1418
- const positions = calculatePositions(motifs.length);
1419
1428
  if (motifs.length > 0) {
1420
- updateAllMotifs(motifs).then(() => {
1421
- setKabschRMSD(calculateAllKabschRMSD(motifs));
1422
- });
1429
+ setKabschRMSD(calculateAllKabschRMSD(motifs));
1423
1430
  if (scene.current.children.size !== motifs.length) {
1431
+ const positions = calculatePositions(motifs.length);
1424
1432
  motifs.forEach((motifMesh, index) => {
1425
1433
  scene.current?.add(motifMesh);
1426
1434
  if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
@@ -1491,10 +1499,6 @@ function Canvas({
1491
1499
  }
1492
1500
  });
1493
1501
  }
1494
- } else {
1495
- motifs.forEach((motifMesh) => {
1496
- scene.current?.add(motifMesh);
1497
- });
1498
1502
  }
1499
1503
  }
1500
1504
  scene.current?.start();
@@ -1523,6 +1527,6 @@ function Canvas({
1523
1527
  getPoints,
1524
1528
  getRMSD,
1525
1529
  kabschSlidingWindow,
1526
- rotateAllPoints,
1527
- updateAllMotifs
1530
+ parseAtomCoords,
1531
+ rotateAllPoints
1528
1532
  });
package/dist/index.mjs CHANGED
@@ -212,6 +212,13 @@ var Motif = class extends Group {
212
212
  this._node.scaling.z * scalar
213
213
  );
214
214
  }
215
+ setScale(scale) {
216
+ this._node.scaling = new Vector32(
217
+ scale,
218
+ scale,
219
+ scale
220
+ );
221
+ }
215
222
  get uuid() {
216
223
  return this._node.uniqueId.toString();
217
224
  }
@@ -756,12 +763,10 @@ var RenderScene = class {
756
763
  };
757
764
 
758
765
  // src/3D/utils/GetAtomInfo.ts
759
- async function parseAtomCoords(fileName) {
760
- const response = await fetch(`/${fileName}`);
761
- const jsonData = await response.json();
766
+ async function parseAtomCoords(meshObject) {
762
767
  const coordinates = [];
763
- for (const [key] of Object.entries(jsonData)) {
764
- const atomMap = jsonData[key][0];
768
+ for (const [key] of Object.entries(meshObject)) {
769
+ const atomMap = meshObject[key][0];
765
770
  if (atomMap[`"C1'"`]) {
766
771
  coordinates.push(
767
772
  new Vec3(
@@ -774,20 +779,6 @@ async function parseAtomCoords(fileName) {
774
779
  }
775
780
  return coordinates;
776
781
  }
777
- async function getAtomCoords(fileName) {
778
- const coordinates = await parseAtomCoords(fileName);
779
- return coordinates;
780
- }
781
- async function updateAllMotifs(motifMeshArray) {
782
- const fileNames = [];
783
- for (const motif of motifMeshArray) {
784
- fileNames.push(motif.userData.fileName);
785
- }
786
- const atomInfoLists = await Promise.all(fileNames.map((o) => getAtomCoords(o)));
787
- for (let i = 0; i < motifMeshArray.length; i += 1) {
788
- motifMeshArray[i].userData.atomInfo = atomInfoLists[i];
789
- }
790
- }
791
782
 
792
783
  // src/3D/utils/GetPoints.ts
793
784
  function getPoints(nucleotideData) {
@@ -801,12 +792,10 @@ function getPoints(nucleotideData) {
801
792
  }
802
793
 
803
794
  // src/3D/utils/GetMotif.ts
804
- async function getMotif(motifJSONFileName, motifColorHex = "0xcc2900") {
805
- const motif = new Motif(`${motifJSONFileName}_motif`);
806
- const motifJSONFileData = await fetch(`/${motifJSONFileName}`);
807
- const jsonObject = await motifJSONFileData.json();
808
- for (const [key] of Object.entries(jsonObject)) {
809
- const { vertices, indices } = getPoints(jsonObject[key]);
795
+ async function getMotif(motifName, motifMesh, motifColorHex = "0xcc2900") {
796
+ const motif = new Motif(`${motifName}_motif`);
797
+ for (const [key] of Object.entries(motifMesh)) {
798
+ const { vertices, indices } = getPoints(motifMesh[key]);
810
799
  const residue = new Residue("residue");
811
800
  const backboneMesh = new MeshObject(`backbone_${key}`);
812
801
  backboneMesh.applyVertexData(vertices[0], indices[0]);
@@ -818,7 +807,8 @@ async function getMotif(motifJSONFileName, motifColorHex = "0xcc2900") {
818
807
  residue.addChild(ringMesh);
819
808
  motif.addChild(residue);
820
809
  }
821
- motif.userData.fileName = motifJSONFileName;
810
+ motif.userData.fileName = motifName;
811
+ motif.userData.atomInfo = await parseAtomCoords(motifMesh);
822
812
  return motif;
823
813
  }
824
814
 
@@ -913,6 +903,7 @@ function getRMSD(a, b) {
913
903
  if (a instanceof Motif && b instanceof Motif) {
914
904
  newCoords1 = rotateAllPoints(a.userData.atomInfo, a.quat);
915
905
  newCoords2 = rotateAllPoints(b.userData.atomInfo, b.quat);
906
+ return calculateRMSDSlide(newCoords1, newCoords2);
916
907
  } else {
917
908
  return -1;
918
909
  }
@@ -1106,7 +1097,7 @@ function Canvas({
1106
1097
  const [kabschRMSD, setKabschRMSD] = useState([]);
1107
1098
  const [lockedMotifIds, setLockedMotifIds] = useState([]);
1108
1099
  const addMotif = (motif) => {
1109
- if (selectedMotifIds.has(motif.uuid)) {
1100
+ if (selectedMotifMeshState.current.has(motif)) {
1110
1101
  return;
1111
1102
  }
1112
1103
  const newSet = /* @__PURE__ */ new Set();
@@ -1119,12 +1110,12 @@ function Canvas({
1119
1110
  selectedMotifMeshState.current.add(motif);
1120
1111
  };
1121
1112
  const removeMotif = (motif) => {
1122
- if (!selectedMotifIds.has(motif.uuid)) {
1113
+ if (!selectedMotifMeshState.current.has(motif)) {
1123
1114
  return;
1124
1115
  }
1125
1116
  selectedMotifMeshState.current.delete(motif);
1126
1117
  setSelectedmotifIds((prevState) => {
1127
- const newState = prevState;
1118
+ const newState = new Set(prevState);
1128
1119
  newState.delete(motif.uuid);
1129
1120
  return newState;
1130
1121
  });
@@ -1209,10 +1200,12 @@ function Canvas({
1209
1200
  const zoomSpeed = 0.1;
1210
1201
  const zoomDirection = event.originalEvent.deltaY > 0 ? -1 : 1;
1211
1202
  selectedMotifMeshState.current.forEach((element) => {
1212
- if (!lockedMotifIdState.current.includes(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
1203
+ if (!lockedMotifIdState.current.includes(element.uuid) && !hardLockedMotifIds.includes(element.uuid) && !(element.scale <= 1 && zoomDirection === -1) && !(element.scale >= 30 && zoomDirection === 1)) {
1213
1204
  const scaleFactor = 1 + zoomDirection * zoomSpeed;
1214
1205
  element.multiplyScalar(scaleFactor);
1215
1206
  }
1207
+ if (element.scale < 1) element.setScale(1);
1208
+ if (element.scale > 30) element.setScale(30);
1216
1209
  });
1217
1210
  }
1218
1211
  }
@@ -1260,7 +1253,7 @@ function Canvas({
1260
1253
  if (!event.rotationAxis.equals(Vec3.Zero) || !event.translationDirection.equals(Vec3.Zero)) {
1261
1254
  return;
1262
1255
  }
1263
- if (!/^[0-9]$/.test(event.key)) {
1256
+ if (!/^[1-9]$/.test(event.key) || Number(event.key) > motifs.length) {
1264
1257
  return;
1265
1258
  }
1266
1259
  const motif = motifs[Number(event.key) - 1];
@@ -1285,6 +1278,21 @@ function Canvas({
1285
1278
  }
1286
1279
  return positions;
1287
1280
  };
1281
+ const updateMotifs = () => {
1282
+ const positions = calculatePositions(motifs.length);
1283
+ motifs.forEach((motifMesh, index) => {
1284
+ if (!scene.current?.children.has(motifMesh.uuid)) return;
1285
+ if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
1286
+ motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
1287
+ if (motifProps[index].rotation) motifMesh.setQuaternion(motifProps[index].rotation);
1288
+ let scale = canvasRef.current.width / 250;
1289
+ if (motifProps[index].scale) scale = motifProps[index].scale;
1290
+ motifMesh.setScale(scale);
1291
+ });
1292
+ };
1293
+ useEffect(() => {
1294
+ updateMotifs();
1295
+ }, [motifProps]);
1288
1296
  useEffect(() => {
1289
1297
  const unsubscribe = CanvasDataManager.subscribe("selectedMotifs" /* SELECTED_MOTIFS */, () => {
1290
1298
  setSelectedmotifIds(CanvasDataManager.selectedMotifIds);
@@ -1339,6 +1347,8 @@ function Canvas({
1339
1347
  useEffect(() => {
1340
1348
  if (CanvasDataManager.kabschRMSD !== kabschRMSD) {
1341
1349
  CanvasDataManager.setKabschRMSD(kabschRMSD);
1350
+ } else if (CanvasDataManager.kabschRMSD.length !== motifs.length) {
1351
+ CanvasDataManager.setKabschRMSD(calculateAllKabschRMSD(motifs));
1342
1352
  }
1343
1353
  }, [kabschRMSD]);
1344
1354
  useEffect(() => {
@@ -1358,12 +1368,10 @@ function Canvas({
1358
1368
  rendererSizeIsWindow ? window.innerHeight : rendererHeight
1359
1369
  );
1360
1370
  }
1361
- const positions = calculatePositions(motifs.length);
1362
1371
  if (motifs.length > 0) {
1363
- updateAllMotifs(motifs).then(() => {
1364
- setKabschRMSD(calculateAllKabschRMSD(motifs));
1365
- });
1372
+ setKabschRMSD(calculateAllKabschRMSD(motifs));
1366
1373
  if (scene.current.children.size !== motifs.length) {
1374
+ const positions = calculatePositions(motifs.length);
1367
1375
  motifs.forEach((motifMesh, index) => {
1368
1376
  scene.current?.add(motifMesh);
1369
1377
  if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
@@ -1434,10 +1442,6 @@ function Canvas({
1434
1442
  }
1435
1443
  });
1436
1444
  }
1437
- } else {
1438
- motifs.forEach((motifMesh) => {
1439
- scene.current?.add(motifMesh);
1440
- });
1441
1445
  }
1442
1446
  }
1443
1447
  scene.current?.start();
@@ -1465,6 +1469,6 @@ export {
1465
1469
  getPoints,
1466
1470
  getRMSD,
1467
1471
  kabschSlidingWindow,
1468
- rotateAllPoints,
1469
- updateAllMotifs
1472
+ parseAtomCoords,
1473
+ rotateAllPoints
1470
1474
  };
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@judah-silva/rnacanvas",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "A 3D Canvas for displaying and interacting with custom RNA models. Powered by BabylonJS.",
5
+ "license": "MIT",
5
6
  "main": "./dist/index.js",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/RNAStructureAnalysisLab/RNACanvas"
10
+ },
6
11
  "module": "./dist/index.mjs",
7
12
  "scripts": {
8
13
  "build": "tsup"
@@ -14,7 +19,6 @@
14
19
  "test"
15
20
  ],
16
21
  "author": "Judah Silva",
17
- "license": "MIT",
18
22
  "dependencies": {
19
23
  "@babylonjs/core": "^7.50.0",
20
24
  "numeric": "^1.2.6",
Binary file