@judah-silva/rnacanvas 0.0.8 → 0.0.9
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 +4 -0
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +129 -107
- package/dist/index.mjs +129 -107
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -306,6 +306,7 @@ declare class RenderScene {
|
|
|
306
306
|
dispose(): void;
|
|
307
307
|
add(motif: Motif): void;
|
|
308
308
|
remove(motif: Motif): void;
|
|
309
|
+
removeAll(): void;
|
|
309
310
|
setBackgroundColor(hexColor: string): void;
|
|
310
311
|
private _reattachToScene;
|
|
311
312
|
private _handleResize;
|
|
@@ -469,8 +470,8 @@ declare class CanvasDataManager {
|
|
|
469
470
|
private static _listeners;
|
|
470
471
|
static get selectedMotifIds(): Set<string>;
|
|
471
472
|
static setSelectedMotifIds(selectedMotifIds: Set<string>): void;
|
|
472
|
-
static get lockedMotifIds(): string
|
|
473
|
-
static setLockedMotifIds(lockedMotifIds: string
|
|
473
|
+
static get lockedMotifIds(): Set<string>;
|
|
474
|
+
static setLockedMotifIds(lockedMotifIds: Set<string>): void;
|
|
474
475
|
static get hardLockedMotifIds(): string[];
|
|
475
476
|
static setHardLockedMotifIds(hardLockedMotifIds: string[]): void;
|
|
476
477
|
static get scoreRMSD(): ScoreInfo[][];
|
package/dist/index.d.ts
CHANGED
|
@@ -306,6 +306,7 @@ declare class RenderScene {
|
|
|
306
306
|
dispose(): void;
|
|
307
307
|
add(motif: Motif): void;
|
|
308
308
|
remove(motif: Motif): void;
|
|
309
|
+
removeAll(): void;
|
|
309
310
|
setBackgroundColor(hexColor: string): void;
|
|
310
311
|
private _reattachToScene;
|
|
311
312
|
private _handleResize;
|
|
@@ -469,8 +470,8 @@ declare class CanvasDataManager {
|
|
|
469
470
|
private static _listeners;
|
|
470
471
|
static get selectedMotifIds(): Set<string>;
|
|
471
472
|
static setSelectedMotifIds(selectedMotifIds: Set<string>): void;
|
|
472
|
-
static get lockedMotifIds(): string
|
|
473
|
-
static setLockedMotifIds(lockedMotifIds: string
|
|
473
|
+
static get lockedMotifIds(): Set<string>;
|
|
474
|
+
static setLockedMotifIds(lockedMotifIds: Set<string>): void;
|
|
474
475
|
static get hardLockedMotifIds(): string[];
|
|
475
476
|
static setHardLockedMotifIds(hardLockedMotifIds: string[]): void;
|
|
476
477
|
static get scoreRMSD(): ScoreInfo[][];
|
package/dist/index.js
CHANGED
|
@@ -378,6 +378,7 @@ var MeshObject = class {
|
|
|
378
378
|
const color3 = import_core7.Color3.FromHexString(`#${color.replace(/^0x/, "")}`);
|
|
379
379
|
mat.diffuseColor = color3;
|
|
380
380
|
mat.specularColor = color3;
|
|
381
|
+
mat.backFaceCulling = false;
|
|
381
382
|
this._mesh.material = mat;
|
|
382
383
|
}
|
|
383
384
|
setNewMesh(mesh) {
|
|
@@ -603,9 +604,19 @@ var EventManager = class {
|
|
|
603
604
|
canceled: false,
|
|
604
605
|
timestamp: performance.now()
|
|
605
606
|
};
|
|
606
|
-
if (keyboardInfo.type === import_core8.KeyboardEventTypes.KEYDOWN) {
|
|
607
|
+
if (keyboardInfo.type === import_core8.KeyboardEventTypes.KEYDOWN && /^[wasdqeWASD]$/.test(event.key)) {
|
|
608
|
+
if (event.key.charCodeAt(0) >= 97) {
|
|
609
|
+
this._activeKeys.delete(event.key.toUpperCase());
|
|
610
|
+
} else {
|
|
611
|
+
this._activeKeys.delete(event.key.toLowerCase());
|
|
612
|
+
}
|
|
607
613
|
this._activeKeys.add(event.key);
|
|
608
614
|
} else if (keyboardInfo.type === import_core8.KeyboardEventTypes.KEYUP) {
|
|
615
|
+
if (event.key.charCodeAt(0) >= 97) {
|
|
616
|
+
this._activeKeys.delete(event.key.toUpperCase());
|
|
617
|
+
} else {
|
|
618
|
+
this._activeKeys.delete(event.key.toLowerCase());
|
|
619
|
+
}
|
|
609
620
|
this._activeKeys.delete(event.key);
|
|
610
621
|
}
|
|
611
622
|
if (this._activeKeys.has("w")) keyboardEvent.rotationAxis.add(new Vec3(-1, 0, 0));
|
|
@@ -745,7 +756,15 @@ var RenderScene = class {
|
|
|
745
756
|
return;
|
|
746
757
|
}
|
|
747
758
|
this._children.delete(motif.uuid);
|
|
748
|
-
|
|
759
|
+
motif.node.dispose(false, true);
|
|
760
|
+
}
|
|
761
|
+
removeAll() {
|
|
762
|
+
this._scene.meshes.slice().forEach((mesh) => {
|
|
763
|
+
if (mesh && this._scene.getMeshById(mesh.id)) {
|
|
764
|
+
this._scene.removeMesh(mesh);
|
|
765
|
+
}
|
|
766
|
+
});
|
|
767
|
+
this._children.clear();
|
|
749
768
|
}
|
|
750
769
|
setBackgroundColor(hexColor) {
|
|
751
770
|
this._scene.clearColor = import_core9.Color4.FromHexString(`${hexColor.replace(/^0x/, "")}`);
|
|
@@ -762,7 +781,7 @@ var RenderScene = class {
|
|
|
762
781
|
geo?.applyToMesh(mesh);
|
|
763
782
|
mesh.material = mat;
|
|
764
783
|
currObj.setNewMesh(mesh);
|
|
765
|
-
node.dispose();
|
|
784
|
+
node.dispose(false, true);
|
|
766
785
|
}
|
|
767
786
|
if (!(currObj instanceof MeshObject)) {
|
|
768
787
|
currObj.children.forEach((childObj) => {
|
|
@@ -895,7 +914,7 @@ var CanvasAttributeTypes = /* @__PURE__ */ ((CanvasAttributeTypes2) => {
|
|
|
895
914
|
})(CanvasAttributeTypes || {});
|
|
896
915
|
var CanvasDataManager = class {
|
|
897
916
|
static _selectedMotifIds = /* @__PURE__ */ new Set();
|
|
898
|
-
static _lockedMotifIds =
|
|
917
|
+
static _lockedMotifIds = /* @__PURE__ */ new Set();
|
|
899
918
|
static _hardLockedMotifIds = [];
|
|
900
919
|
static _scoreRMSD = [];
|
|
901
920
|
static _kabschRMSD = [];
|
|
@@ -1152,28 +1171,27 @@ function Canvas({
|
|
|
1152
1171
|
}) {
|
|
1153
1172
|
const canvasRef = (0, import_react.useRef)(null);
|
|
1154
1173
|
const scene = (0, import_react.useRef)(null);
|
|
1155
|
-
const motifs = [];
|
|
1174
|
+
const motifs = (0, import_react.useRef)([]);
|
|
1156
1175
|
let hardLockedMotifIds = [];
|
|
1157
1176
|
motifProps.forEach((motifProp) => {
|
|
1158
|
-
motifs.push(motifProp.motif);
|
|
1159
1177
|
if (motifProp.locked) hardLockedMotifIds.push(motifProp.motif.uuid);
|
|
1160
1178
|
});
|
|
1161
1179
|
CanvasDataManager.setHardLockedMotifIds(hardLockedMotifIds);
|
|
1162
1180
|
const selectedMotifMeshState = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
1163
|
-
const lockedMotifIdState = (0, import_react.useRef)(
|
|
1181
|
+
const lockedMotifIdState = (0, import_react.useRef)(/* @__PURE__ */ new Set());
|
|
1164
1182
|
const [cursorStyle, setCursorStyle] = (0, import_react.useState)("auto");
|
|
1165
1183
|
const [selectedMotifIds, setSelectedmotifIds] = (0, import_react.useState)(/* @__PURE__ */ new Set());
|
|
1166
1184
|
const [scoreRMSD, setScoreRMSD] = (0, import_react.useState)([]);
|
|
1167
1185
|
const [kabschRMSD, setKabschRMSD] = (0, import_react.useState)([]);
|
|
1168
|
-
const [lockedMotifIds, setLockedMotifIds] = (0, import_react.useState)(
|
|
1186
|
+
const [lockedMotifIds, setLockedMotifIds] = (0, import_react.useState)(/* @__PURE__ */ new Set());
|
|
1169
1187
|
const addMotif = (motif) => {
|
|
1170
1188
|
if (selectedMotifMeshState.current.has(motif)) {
|
|
1171
1189
|
return;
|
|
1172
1190
|
}
|
|
1173
1191
|
const newSet = /* @__PURE__ */ new Set();
|
|
1174
|
-
for (let i = 0; i < motifs.length; i += 1) {
|
|
1175
|
-
if (selectedMotifMeshState.current.has(motifs[i]) || motifs[i].uuid === motif.uuid) {
|
|
1176
|
-
newSet.add(motifs[i].uuid);
|
|
1192
|
+
for (let i = 0; i < motifs.current.length; i += 1) {
|
|
1193
|
+
if (selectedMotifMeshState.current.has(motifs.current[i]) || motifs.current[i].uuid === motif.uuid) {
|
|
1194
|
+
newSet.add(motifs.current[i].uuid);
|
|
1177
1195
|
}
|
|
1178
1196
|
}
|
|
1179
1197
|
setSelectedmotifIds(newSet);
|
|
@@ -1191,7 +1209,7 @@ function Canvas({
|
|
|
1191
1209
|
});
|
|
1192
1210
|
};
|
|
1193
1211
|
function updateGlow() {
|
|
1194
|
-
motifs.forEach((motif) => {
|
|
1212
|
+
motifs.current.forEach((motif) => {
|
|
1195
1213
|
motif.children.forEach((residue) => {
|
|
1196
1214
|
residue.children.forEach((childMesh) => {
|
|
1197
1215
|
if (selectedMotifIds.has(motif.uuid)) {
|
|
@@ -1208,7 +1226,7 @@ function Canvas({
|
|
|
1208
1226
|
return;
|
|
1209
1227
|
}
|
|
1210
1228
|
const { motif } = event;
|
|
1211
|
-
if (!motif || selectedMotifMeshState.current.has(motif)
|
|
1229
|
+
if (!motif || selectedMotifMeshState.current.has(motif)) {
|
|
1212
1230
|
return;
|
|
1213
1231
|
}
|
|
1214
1232
|
if (event.multiSelect && motif) {
|
|
@@ -1240,7 +1258,7 @@ function Canvas({
|
|
|
1240
1258
|
const deltaX = rawDeltaX / renderWidth * canvasRef.current.width;
|
|
1241
1259
|
const deltaY = rawDeltaY / renderHeight * canvasRef.current.height;
|
|
1242
1260
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1243
|
-
if (!lockedMotifIdState.current.
|
|
1261
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1244
1262
|
element.translate(-deltaX, -deltaY, 0);
|
|
1245
1263
|
}
|
|
1246
1264
|
});
|
|
@@ -1253,11 +1271,11 @@ function Canvas({
|
|
|
1253
1271
|
if (scene.current) {
|
|
1254
1272
|
const angle = directionVec.length() / scene.current.renderWidth * (3 * Math.PI);
|
|
1255
1273
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1256
|
-
if (!lockedMotifIdState.current.
|
|
1274
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1257
1275
|
element.rotate(axisVec, angle);
|
|
1258
1276
|
}
|
|
1259
1277
|
});
|
|
1260
|
-
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs));
|
|
1278
|
+
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs.current));
|
|
1261
1279
|
}
|
|
1262
1280
|
}
|
|
1263
1281
|
}
|
|
@@ -1270,7 +1288,7 @@ function Canvas({
|
|
|
1270
1288
|
const zoomSpeed = 0.1;
|
|
1271
1289
|
const zoomDirection = event.originalEvent.deltaY > 0 ? -1 : 1;
|
|
1272
1290
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1273
|
-
if (!lockedMotifIdState.current.
|
|
1291
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid) && !(element.scale <= 1 && zoomDirection === -1) && !(element.scale >= 30 && zoomDirection === 1)) {
|
|
1274
1292
|
const scaleFactor = 1 + zoomDirection * zoomSpeed;
|
|
1275
1293
|
element.multiplyScalar(scaleFactor);
|
|
1276
1294
|
}
|
|
@@ -1298,19 +1316,19 @@ function Canvas({
|
|
|
1298
1316
|
}
|
|
1299
1317
|
const angle = event.rotationAxis.length() / 500 * (6 * Math.PI);
|
|
1300
1318
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1301
|
-
if (!lockedMotifIdState.current.
|
|
1319
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1302
1320
|
element.rotate(event.rotationAxis, angle);
|
|
1303
1321
|
}
|
|
1304
1322
|
});
|
|
1305
|
-
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs));
|
|
1323
|
+
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs.current));
|
|
1306
1324
|
}
|
|
1307
1325
|
function onKeyboardTranslate(event) {
|
|
1308
1326
|
if (event.translationDirection.equals(Vec3.Zero)) {
|
|
1309
1327
|
return;
|
|
1310
1328
|
}
|
|
1311
|
-
event.translationDirection.multiplyScalar(
|
|
1329
|
+
event.translationDirection.multiplyScalar(4.5);
|
|
1312
1330
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1313
|
-
if (!lockedMotifIdState.current.
|
|
1331
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1314
1332
|
element.translate(
|
|
1315
1333
|
event.translationDirection.x,
|
|
1316
1334
|
event.translationDirection.y,
|
|
@@ -1323,10 +1341,10 @@ function Canvas({
|
|
|
1323
1341
|
if (!event.rotationAxis.equals(Vec3.Zero) || !event.translationDirection.equals(Vec3.Zero)) {
|
|
1324
1342
|
return;
|
|
1325
1343
|
}
|
|
1326
|
-
if (!/^[1-9]$/.test(event.key) || Number(event.key) > motifs.length) {
|
|
1344
|
+
if (!/^[1-9]$/.test(event.key) || Number(event.key) > motifs.current.length) {
|
|
1327
1345
|
return;
|
|
1328
1346
|
}
|
|
1329
|
-
const motif = motifs[Number(event.key) - 1];
|
|
1347
|
+
const motif = motifs.current[Number(event.key) - 1];
|
|
1330
1348
|
if (selectedMotifMeshState.current.has(motif)) {
|
|
1331
1349
|
removeMotif(motif);
|
|
1332
1350
|
} else {
|
|
@@ -1349,8 +1367,8 @@ function Canvas({
|
|
|
1349
1367
|
return positions;
|
|
1350
1368
|
};
|
|
1351
1369
|
const updateMotifs = () => {
|
|
1352
|
-
const positions = calculatePositions(motifs.length);
|
|
1353
|
-
motifs.forEach((motifMesh, index) => {
|
|
1370
|
+
const positions = calculatePositions(motifs.current.length);
|
|
1371
|
+
motifs.current.forEach((motifMesh, index) => {
|
|
1354
1372
|
if (!scene.current?.children.has(motifMesh.uuid)) return;
|
|
1355
1373
|
if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
|
|
1356
1374
|
motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
|
|
@@ -1360,9 +1378,6 @@ function Canvas({
|
|
|
1360
1378
|
motifMesh.setScale(scale);
|
|
1361
1379
|
});
|
|
1362
1380
|
};
|
|
1363
|
-
(0, import_react.useEffect)(() => {
|
|
1364
|
-
updateMotifs();
|
|
1365
|
-
}, [motifProps]);
|
|
1366
1381
|
(0, import_react.useEffect)(() => {
|
|
1367
1382
|
const unsubscribe = CanvasDataManager.subscribe("selectedMotifs" /* SELECTED_MOTIFS */, () => {
|
|
1368
1383
|
setSelectedmotifIds(CanvasDataManager.selectedMotifIds);
|
|
@@ -1374,13 +1389,13 @@ function Canvas({
|
|
|
1374
1389
|
CanvasDataManager.setSelectedMotifIds(selectedMotifIds);
|
|
1375
1390
|
}
|
|
1376
1391
|
selectedMotifMeshState.current.clear();
|
|
1377
|
-
motifs.forEach((motif) => {
|
|
1392
|
+
motifs.current.forEach((motif) => {
|
|
1378
1393
|
if (selectedMotifIds.has(motif.uuid)) {
|
|
1379
1394
|
selectedMotifMeshState.current.add(motif);
|
|
1380
1395
|
}
|
|
1381
1396
|
});
|
|
1382
1397
|
updateGlow();
|
|
1383
|
-
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs));
|
|
1398
|
+
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs.current));
|
|
1384
1399
|
}, [selectedMotifIds]);
|
|
1385
1400
|
(0, import_react.useEffect)(() => {
|
|
1386
1401
|
const unsubscribe = CanvasDataManager.subscribe("lockedMotifIds" /* LOCKED_MOTIF_IDS */, () => {
|
|
@@ -1421,8 +1436,8 @@ function Canvas({
|
|
|
1421
1436
|
if (!showRMSD) return;
|
|
1422
1437
|
if (CanvasDataManager.kabschRMSD !== kabschRMSD) {
|
|
1423
1438
|
CanvasDataManager.setKabschRMSD(kabschRMSD);
|
|
1424
|
-
} else if (CanvasDataManager.kabschRMSD.length !== motifs.length) {
|
|
1425
|
-
CanvasDataManager.setKabschRMSD(calculateAllKabschRMSD(motifs));
|
|
1439
|
+
} else if (CanvasDataManager.kabschRMSD.length !== motifs.current.length) {
|
|
1440
|
+
CanvasDataManager.setKabschRMSD(calculateAllKabschRMSD(motifs.current));
|
|
1426
1441
|
}
|
|
1427
1442
|
}, [kabschRMSD]);
|
|
1428
1443
|
(0, import_react.useEffect)(() => {
|
|
@@ -1441,84 +1456,91 @@ function Canvas({
|
|
|
1441
1456
|
rendererSizeIsWindow ? window.innerWidth : rendererWidth,
|
|
1442
1457
|
rendererSizeIsWindow ? window.innerHeight : rendererHeight
|
|
1443
1458
|
);
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1459
|
+
const eventManager = scene.current?.eventManager;
|
|
1460
|
+
eventManager.on(Events.EventType.OBJECT_SELECTED, onSelectMotif);
|
|
1461
|
+
eventManager.on(Events.EventType.OBJECT_DESELECTED, onDeselectMotif);
|
|
1462
|
+
eventManager.on(Events.EventType.POINTER_MOVE, onMouseMove);
|
|
1463
|
+
eventManager.on(Events.EventType.POINTER_WHEEL, onMouseScroll);
|
|
1464
|
+
eventManager.on(Events.EventType.POINTER_DOWN, onMouseDown);
|
|
1465
|
+
eventManager.on(Events.EventType.POINTER_UP, onMouseUp);
|
|
1466
|
+
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardRotate);
|
|
1467
|
+
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardTranslate);
|
|
1468
|
+
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardSelect);
|
|
1469
|
+
if (customEventProps) {
|
|
1470
|
+
customEventProps.forEach((customEventProp) => {
|
|
1471
|
+
switch (customEventProp.eventType) {
|
|
1472
|
+
// Handle Pointer Events
|
|
1473
|
+
case Events.EventType.POINTER_DOWN:
|
|
1474
|
+
case Events.EventType.POINTER_UP:
|
|
1475
|
+
case Events.EventType.POINTER_MOVE:
|
|
1476
|
+
case Events.EventType.POINTER_WHEEL:
|
|
1477
|
+
case Events.EventType.TOUCH_END:
|
|
1478
|
+
case Events.EventType.TOUCH_MOVE:
|
|
1479
|
+
case Events.EventType.TOUCH_START:
|
|
1480
|
+
eventManager.on(
|
|
1481
|
+
customEventProp.eventType,
|
|
1482
|
+
customEventProp.callback
|
|
1483
|
+
);
|
|
1484
|
+
break;
|
|
1485
|
+
// Handle Keyboard Events
|
|
1486
|
+
case Events.EventType.KEY_DOWN:
|
|
1487
|
+
case Events.EventType.KEY_UP:
|
|
1488
|
+
eventManager.on(
|
|
1489
|
+
customEventProp.eventType,
|
|
1490
|
+
customEventProp.callback
|
|
1491
|
+
);
|
|
1492
|
+
break;
|
|
1493
|
+
// Handle Pinch Events
|
|
1494
|
+
case Events.EventType.PINCH:
|
|
1495
|
+
case Events.EventType.PINCH_END:
|
|
1496
|
+
case Events.EventType.PINCH_START:
|
|
1497
|
+
eventManager.on(
|
|
1498
|
+
customEventProp.eventType,
|
|
1499
|
+
customEventProp.callback
|
|
1500
|
+
);
|
|
1501
|
+
break;
|
|
1502
|
+
// Handle Selection Events
|
|
1503
|
+
case Events.EventType.OBJECT_SELECTED:
|
|
1504
|
+
case Events.EventType.OBJECT_DESELECTED:
|
|
1505
|
+
eventManager.on(
|
|
1506
|
+
customEventProp.eventType,
|
|
1507
|
+
customEventProp.callback
|
|
1508
|
+
);
|
|
1509
|
+
break;
|
|
1510
|
+
// Handle Events
|
|
1511
|
+
default:
|
|
1512
|
+
eventManager.on(
|
|
1513
|
+
customEventProp.eventType,
|
|
1514
|
+
customEventProp.callback
|
|
1515
|
+
);
|
|
1516
|
+
break;
|
|
1517
|
+
}
|
|
1457
1518
|
});
|
|
1458
|
-
const eventManager = scene.current?.eventManager;
|
|
1459
|
-
eventManager.on(Events.EventType.OBJECT_SELECTED, onSelectMotif);
|
|
1460
|
-
eventManager.on(Events.EventType.OBJECT_DESELECTED, onDeselectMotif);
|
|
1461
|
-
eventManager.on(Events.EventType.POINTER_MOVE, onMouseMove);
|
|
1462
|
-
eventManager.on(Events.EventType.POINTER_WHEEL, onMouseScroll);
|
|
1463
|
-
eventManager.on(Events.EventType.POINTER_DOWN, onMouseDown);
|
|
1464
|
-
eventManager.on(Events.EventType.POINTER_UP, onMouseUp);
|
|
1465
|
-
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardRotate);
|
|
1466
|
-
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardTranslate);
|
|
1467
|
-
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardSelect);
|
|
1468
|
-
if (customEventProps) {
|
|
1469
|
-
customEventProps.forEach((customEventProp) => {
|
|
1470
|
-
switch (customEventProp.eventType) {
|
|
1471
|
-
// Handle Pointer Events
|
|
1472
|
-
case Events.EventType.POINTER_DOWN:
|
|
1473
|
-
case Events.EventType.POINTER_UP:
|
|
1474
|
-
case Events.EventType.POINTER_MOVE:
|
|
1475
|
-
case Events.EventType.POINTER_WHEEL:
|
|
1476
|
-
case Events.EventType.TOUCH_END:
|
|
1477
|
-
case Events.EventType.TOUCH_MOVE:
|
|
1478
|
-
case Events.EventType.TOUCH_START:
|
|
1479
|
-
eventManager.on(
|
|
1480
|
-
customEventProp.eventType,
|
|
1481
|
-
customEventProp.callback
|
|
1482
|
-
);
|
|
1483
|
-
break;
|
|
1484
|
-
// Handle Keyboard Events
|
|
1485
|
-
case Events.EventType.KEY_DOWN:
|
|
1486
|
-
case Events.EventType.KEY_UP:
|
|
1487
|
-
eventManager.on(
|
|
1488
|
-
customEventProp.eventType,
|
|
1489
|
-
customEventProp.callback
|
|
1490
|
-
);
|
|
1491
|
-
break;
|
|
1492
|
-
// Handle Pinch Events
|
|
1493
|
-
case Events.EventType.PINCH:
|
|
1494
|
-
case Events.EventType.PINCH_END:
|
|
1495
|
-
case Events.EventType.PINCH_START:
|
|
1496
|
-
eventManager.on(
|
|
1497
|
-
customEventProp.eventType,
|
|
1498
|
-
customEventProp.callback
|
|
1499
|
-
);
|
|
1500
|
-
break;
|
|
1501
|
-
// Handle Selection Events
|
|
1502
|
-
case Events.EventType.OBJECT_SELECTED:
|
|
1503
|
-
case Events.EventType.OBJECT_DESELECTED:
|
|
1504
|
-
eventManager.on(
|
|
1505
|
-
customEventProp.eventType,
|
|
1506
|
-
customEventProp.callback
|
|
1507
|
-
);
|
|
1508
|
-
break;
|
|
1509
|
-
// Handle Events
|
|
1510
|
-
default:
|
|
1511
|
-
eventManager.on(
|
|
1512
|
-
customEventProp.eventType,
|
|
1513
|
-
customEventProp.callback
|
|
1514
|
-
);
|
|
1515
|
-
break;
|
|
1516
|
-
}
|
|
1517
|
-
});
|
|
1518
|
-
}
|
|
1519
1519
|
}
|
|
1520
|
+
scene.current.start();
|
|
1521
|
+
}
|
|
1522
|
+
}, []);
|
|
1523
|
+
(0, import_react.useEffect)(() => {
|
|
1524
|
+
if (!scene.current || !canvasRef.current) return;
|
|
1525
|
+
motifs.current.length = 0;
|
|
1526
|
+
motifProps.forEach((motifProp) => {
|
|
1527
|
+
motifs.current.push(motifProp.motif);
|
|
1528
|
+
});
|
|
1529
|
+
if (motifs.current.length > 0) {
|
|
1530
|
+
if (showRMSD) setKabschRMSD(calculateAllKabschRMSD(motifs.current));
|
|
1531
|
+
scene.current.removeAll();
|
|
1532
|
+
const positions = calculatePositions(motifs.current.length);
|
|
1533
|
+
motifs.current.forEach((motifMesh, index) => {
|
|
1534
|
+
scene.current?.add(motifMesh);
|
|
1535
|
+
if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
|
|
1536
|
+
motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
|
|
1537
|
+
if (motifProps[index].rotation) motifMesh.setQuaternion(motifProps[index].rotation);
|
|
1538
|
+
let scale = canvasRef.current.width / 250;
|
|
1539
|
+
if (motifProps[index].scale) scale = motifProps[index].scale;
|
|
1540
|
+
motifMesh.setScale(scale);
|
|
1541
|
+
if (motifProps[index].locked) lockedMotifIdState.current.add(motifMesh.uuid);
|
|
1542
|
+
});
|
|
1520
1543
|
}
|
|
1521
|
-
scene.current?.start();
|
|
1522
1544
|
}, [rendererWidth, rendererHeight, rendererSizeIsWindow, motifProps]);
|
|
1523
1545
|
return /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("canvas", { ref: canvasRef }));
|
|
1524
1546
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -321,6 +321,7 @@ var MeshObject = class {
|
|
|
321
321
|
const color3 = Color3.FromHexString(`#${color.replace(/^0x/, "")}`);
|
|
322
322
|
mat.diffuseColor = color3;
|
|
323
323
|
mat.specularColor = color3;
|
|
324
|
+
mat.backFaceCulling = false;
|
|
324
325
|
this._mesh.material = mat;
|
|
325
326
|
}
|
|
326
327
|
setNewMesh(mesh) {
|
|
@@ -546,9 +547,19 @@ var EventManager = class {
|
|
|
546
547
|
canceled: false,
|
|
547
548
|
timestamp: performance.now()
|
|
548
549
|
};
|
|
549
|
-
if (keyboardInfo.type === KeyboardEventTypes.KEYDOWN) {
|
|
550
|
+
if (keyboardInfo.type === KeyboardEventTypes.KEYDOWN && /^[wasdqeWASD]$/.test(event.key)) {
|
|
551
|
+
if (event.key.charCodeAt(0) >= 97) {
|
|
552
|
+
this._activeKeys.delete(event.key.toUpperCase());
|
|
553
|
+
} else {
|
|
554
|
+
this._activeKeys.delete(event.key.toLowerCase());
|
|
555
|
+
}
|
|
550
556
|
this._activeKeys.add(event.key);
|
|
551
557
|
} else if (keyboardInfo.type === KeyboardEventTypes.KEYUP) {
|
|
558
|
+
if (event.key.charCodeAt(0) >= 97) {
|
|
559
|
+
this._activeKeys.delete(event.key.toUpperCase());
|
|
560
|
+
} else {
|
|
561
|
+
this._activeKeys.delete(event.key.toLowerCase());
|
|
562
|
+
}
|
|
552
563
|
this._activeKeys.delete(event.key);
|
|
553
564
|
}
|
|
554
565
|
if (this._activeKeys.has("w")) keyboardEvent.rotationAxis.add(new Vec3(-1, 0, 0));
|
|
@@ -688,7 +699,15 @@ var RenderScene = class {
|
|
|
688
699
|
return;
|
|
689
700
|
}
|
|
690
701
|
this._children.delete(motif.uuid);
|
|
691
|
-
|
|
702
|
+
motif.node.dispose(false, true);
|
|
703
|
+
}
|
|
704
|
+
removeAll() {
|
|
705
|
+
this._scene.meshes.slice().forEach((mesh) => {
|
|
706
|
+
if (mesh && this._scene.getMeshById(mesh.id)) {
|
|
707
|
+
this._scene.removeMesh(mesh);
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
this._children.clear();
|
|
692
711
|
}
|
|
693
712
|
setBackgroundColor(hexColor) {
|
|
694
713
|
this._scene.clearColor = Color4.FromHexString(`${hexColor.replace(/^0x/, "")}`);
|
|
@@ -705,7 +724,7 @@ var RenderScene = class {
|
|
|
705
724
|
geo?.applyToMesh(mesh);
|
|
706
725
|
mesh.material = mat;
|
|
707
726
|
currObj.setNewMesh(mesh);
|
|
708
|
-
node.dispose();
|
|
727
|
+
node.dispose(false, true);
|
|
709
728
|
}
|
|
710
729
|
if (!(currObj instanceof MeshObject)) {
|
|
711
730
|
currObj.children.forEach((childObj) => {
|
|
@@ -838,7 +857,7 @@ var CanvasAttributeTypes = /* @__PURE__ */ ((CanvasAttributeTypes2) => {
|
|
|
838
857
|
})(CanvasAttributeTypes || {});
|
|
839
858
|
var CanvasDataManager = class {
|
|
840
859
|
static _selectedMotifIds = /* @__PURE__ */ new Set();
|
|
841
|
-
static _lockedMotifIds =
|
|
860
|
+
static _lockedMotifIds = /* @__PURE__ */ new Set();
|
|
842
861
|
static _hardLockedMotifIds = [];
|
|
843
862
|
static _scoreRMSD = [];
|
|
844
863
|
static _kabschRMSD = [];
|
|
@@ -1095,28 +1114,27 @@ function Canvas({
|
|
|
1095
1114
|
}) {
|
|
1096
1115
|
const canvasRef = useRef(null);
|
|
1097
1116
|
const scene = useRef(null);
|
|
1098
|
-
const motifs = [];
|
|
1117
|
+
const motifs = useRef([]);
|
|
1099
1118
|
let hardLockedMotifIds = [];
|
|
1100
1119
|
motifProps.forEach((motifProp) => {
|
|
1101
|
-
motifs.push(motifProp.motif);
|
|
1102
1120
|
if (motifProp.locked) hardLockedMotifIds.push(motifProp.motif.uuid);
|
|
1103
1121
|
});
|
|
1104
1122
|
CanvasDataManager.setHardLockedMotifIds(hardLockedMotifIds);
|
|
1105
1123
|
const selectedMotifMeshState = useRef(/* @__PURE__ */ new Set());
|
|
1106
|
-
const lockedMotifIdState = useRef(
|
|
1124
|
+
const lockedMotifIdState = useRef(/* @__PURE__ */ new Set());
|
|
1107
1125
|
const [cursorStyle, setCursorStyle] = useState("auto");
|
|
1108
1126
|
const [selectedMotifIds, setSelectedmotifIds] = useState(/* @__PURE__ */ new Set());
|
|
1109
1127
|
const [scoreRMSD, setScoreRMSD] = useState([]);
|
|
1110
1128
|
const [kabschRMSD, setKabschRMSD] = useState([]);
|
|
1111
|
-
const [lockedMotifIds, setLockedMotifIds] = useState(
|
|
1129
|
+
const [lockedMotifIds, setLockedMotifIds] = useState(/* @__PURE__ */ new Set());
|
|
1112
1130
|
const addMotif = (motif) => {
|
|
1113
1131
|
if (selectedMotifMeshState.current.has(motif)) {
|
|
1114
1132
|
return;
|
|
1115
1133
|
}
|
|
1116
1134
|
const newSet = /* @__PURE__ */ new Set();
|
|
1117
|
-
for (let i = 0; i < motifs.length; i += 1) {
|
|
1118
|
-
if (selectedMotifMeshState.current.has(motifs[i]) || motifs[i].uuid === motif.uuid) {
|
|
1119
|
-
newSet.add(motifs[i].uuid);
|
|
1135
|
+
for (let i = 0; i < motifs.current.length; i += 1) {
|
|
1136
|
+
if (selectedMotifMeshState.current.has(motifs.current[i]) || motifs.current[i].uuid === motif.uuid) {
|
|
1137
|
+
newSet.add(motifs.current[i].uuid);
|
|
1120
1138
|
}
|
|
1121
1139
|
}
|
|
1122
1140
|
setSelectedmotifIds(newSet);
|
|
@@ -1134,7 +1152,7 @@ function Canvas({
|
|
|
1134
1152
|
});
|
|
1135
1153
|
};
|
|
1136
1154
|
function updateGlow() {
|
|
1137
|
-
motifs.forEach((motif) => {
|
|
1155
|
+
motifs.current.forEach((motif) => {
|
|
1138
1156
|
motif.children.forEach((residue) => {
|
|
1139
1157
|
residue.children.forEach((childMesh) => {
|
|
1140
1158
|
if (selectedMotifIds.has(motif.uuid)) {
|
|
@@ -1151,7 +1169,7 @@ function Canvas({
|
|
|
1151
1169
|
return;
|
|
1152
1170
|
}
|
|
1153
1171
|
const { motif } = event;
|
|
1154
|
-
if (!motif || selectedMotifMeshState.current.has(motif)
|
|
1172
|
+
if (!motif || selectedMotifMeshState.current.has(motif)) {
|
|
1155
1173
|
return;
|
|
1156
1174
|
}
|
|
1157
1175
|
if (event.multiSelect && motif) {
|
|
@@ -1183,7 +1201,7 @@ function Canvas({
|
|
|
1183
1201
|
const deltaX = rawDeltaX / renderWidth * canvasRef.current.width;
|
|
1184
1202
|
const deltaY = rawDeltaY / renderHeight * canvasRef.current.height;
|
|
1185
1203
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1186
|
-
if (!lockedMotifIdState.current.
|
|
1204
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1187
1205
|
element.translate(-deltaX, -deltaY, 0);
|
|
1188
1206
|
}
|
|
1189
1207
|
});
|
|
@@ -1196,11 +1214,11 @@ function Canvas({
|
|
|
1196
1214
|
if (scene.current) {
|
|
1197
1215
|
const angle = directionVec.length() / scene.current.renderWidth * (3 * Math.PI);
|
|
1198
1216
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1199
|
-
if (!lockedMotifIdState.current.
|
|
1217
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1200
1218
|
element.rotate(axisVec, angle);
|
|
1201
1219
|
}
|
|
1202
1220
|
});
|
|
1203
|
-
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs));
|
|
1221
|
+
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs.current));
|
|
1204
1222
|
}
|
|
1205
1223
|
}
|
|
1206
1224
|
}
|
|
@@ -1213,7 +1231,7 @@ function Canvas({
|
|
|
1213
1231
|
const zoomSpeed = 0.1;
|
|
1214
1232
|
const zoomDirection = event.originalEvent.deltaY > 0 ? -1 : 1;
|
|
1215
1233
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1216
|
-
if (!lockedMotifIdState.current.
|
|
1234
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid) && !(element.scale <= 1 && zoomDirection === -1) && !(element.scale >= 30 && zoomDirection === 1)) {
|
|
1217
1235
|
const scaleFactor = 1 + zoomDirection * zoomSpeed;
|
|
1218
1236
|
element.multiplyScalar(scaleFactor);
|
|
1219
1237
|
}
|
|
@@ -1241,19 +1259,19 @@ function Canvas({
|
|
|
1241
1259
|
}
|
|
1242
1260
|
const angle = event.rotationAxis.length() / 500 * (6 * Math.PI);
|
|
1243
1261
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1244
|
-
if (!lockedMotifIdState.current.
|
|
1262
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1245
1263
|
element.rotate(event.rotationAxis, angle);
|
|
1246
1264
|
}
|
|
1247
1265
|
});
|
|
1248
|
-
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs));
|
|
1266
|
+
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs.current));
|
|
1249
1267
|
}
|
|
1250
1268
|
function onKeyboardTranslate(event) {
|
|
1251
1269
|
if (event.translationDirection.equals(Vec3.Zero)) {
|
|
1252
1270
|
return;
|
|
1253
1271
|
}
|
|
1254
|
-
event.translationDirection.multiplyScalar(
|
|
1272
|
+
event.translationDirection.multiplyScalar(4.5);
|
|
1255
1273
|
selectedMotifMeshState.current.forEach((element) => {
|
|
1256
|
-
if (!lockedMotifIdState.current.
|
|
1274
|
+
if (!lockedMotifIdState.current.has(element.uuid) && !hardLockedMotifIds.includes(element.uuid)) {
|
|
1257
1275
|
element.translate(
|
|
1258
1276
|
event.translationDirection.x,
|
|
1259
1277
|
event.translationDirection.y,
|
|
@@ -1266,10 +1284,10 @@ function Canvas({
|
|
|
1266
1284
|
if (!event.rotationAxis.equals(Vec3.Zero) || !event.translationDirection.equals(Vec3.Zero)) {
|
|
1267
1285
|
return;
|
|
1268
1286
|
}
|
|
1269
|
-
if (!/^[1-9]$/.test(event.key) || Number(event.key) > motifs.length) {
|
|
1287
|
+
if (!/^[1-9]$/.test(event.key) || Number(event.key) > motifs.current.length) {
|
|
1270
1288
|
return;
|
|
1271
1289
|
}
|
|
1272
|
-
const motif = motifs[Number(event.key) - 1];
|
|
1290
|
+
const motif = motifs.current[Number(event.key) - 1];
|
|
1273
1291
|
if (selectedMotifMeshState.current.has(motif)) {
|
|
1274
1292
|
removeMotif(motif);
|
|
1275
1293
|
} else {
|
|
@@ -1292,8 +1310,8 @@ function Canvas({
|
|
|
1292
1310
|
return positions;
|
|
1293
1311
|
};
|
|
1294
1312
|
const updateMotifs = () => {
|
|
1295
|
-
const positions = calculatePositions(motifs.length);
|
|
1296
|
-
motifs.forEach((motifMesh, index) => {
|
|
1313
|
+
const positions = calculatePositions(motifs.current.length);
|
|
1314
|
+
motifs.current.forEach((motifMesh, index) => {
|
|
1297
1315
|
if (!scene.current?.children.has(motifMesh.uuid)) return;
|
|
1298
1316
|
if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
|
|
1299
1317
|
motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
|
|
@@ -1303,9 +1321,6 @@ function Canvas({
|
|
|
1303
1321
|
motifMesh.setScale(scale);
|
|
1304
1322
|
});
|
|
1305
1323
|
};
|
|
1306
|
-
useEffect(() => {
|
|
1307
|
-
updateMotifs();
|
|
1308
|
-
}, [motifProps]);
|
|
1309
1324
|
useEffect(() => {
|
|
1310
1325
|
const unsubscribe = CanvasDataManager.subscribe("selectedMotifs" /* SELECTED_MOTIFS */, () => {
|
|
1311
1326
|
setSelectedmotifIds(CanvasDataManager.selectedMotifIds);
|
|
@@ -1317,13 +1332,13 @@ function Canvas({
|
|
|
1317
1332
|
CanvasDataManager.setSelectedMotifIds(selectedMotifIds);
|
|
1318
1333
|
}
|
|
1319
1334
|
selectedMotifMeshState.current.clear();
|
|
1320
|
-
motifs.forEach((motif) => {
|
|
1335
|
+
motifs.current.forEach((motif) => {
|
|
1321
1336
|
if (selectedMotifIds.has(motif.uuid)) {
|
|
1322
1337
|
selectedMotifMeshState.current.add(motif);
|
|
1323
1338
|
}
|
|
1324
1339
|
});
|
|
1325
1340
|
updateGlow();
|
|
1326
|
-
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs));
|
|
1341
|
+
if (showRMSD) setScoreRMSD(calculateRMSD(Array.from(selectedMotifMeshState.current), motifs.current));
|
|
1327
1342
|
}, [selectedMotifIds]);
|
|
1328
1343
|
useEffect(() => {
|
|
1329
1344
|
const unsubscribe = CanvasDataManager.subscribe("lockedMotifIds" /* LOCKED_MOTIF_IDS */, () => {
|
|
@@ -1364,8 +1379,8 @@ function Canvas({
|
|
|
1364
1379
|
if (!showRMSD) return;
|
|
1365
1380
|
if (CanvasDataManager.kabschRMSD !== kabschRMSD) {
|
|
1366
1381
|
CanvasDataManager.setKabschRMSD(kabschRMSD);
|
|
1367
|
-
} else if (CanvasDataManager.kabschRMSD.length !== motifs.length) {
|
|
1368
|
-
CanvasDataManager.setKabschRMSD(calculateAllKabschRMSD(motifs));
|
|
1382
|
+
} else if (CanvasDataManager.kabschRMSD.length !== motifs.current.length) {
|
|
1383
|
+
CanvasDataManager.setKabschRMSD(calculateAllKabschRMSD(motifs.current));
|
|
1369
1384
|
}
|
|
1370
1385
|
}, [kabschRMSD]);
|
|
1371
1386
|
useEffect(() => {
|
|
@@ -1384,84 +1399,91 @@ function Canvas({
|
|
|
1384
1399
|
rendererSizeIsWindow ? window.innerWidth : rendererWidth,
|
|
1385
1400
|
rendererSizeIsWindow ? window.innerHeight : rendererHeight
|
|
1386
1401
|
);
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1402
|
+
const eventManager = scene.current?.eventManager;
|
|
1403
|
+
eventManager.on(Events.EventType.OBJECT_SELECTED, onSelectMotif);
|
|
1404
|
+
eventManager.on(Events.EventType.OBJECT_DESELECTED, onDeselectMotif);
|
|
1405
|
+
eventManager.on(Events.EventType.POINTER_MOVE, onMouseMove);
|
|
1406
|
+
eventManager.on(Events.EventType.POINTER_WHEEL, onMouseScroll);
|
|
1407
|
+
eventManager.on(Events.EventType.POINTER_DOWN, onMouseDown);
|
|
1408
|
+
eventManager.on(Events.EventType.POINTER_UP, onMouseUp);
|
|
1409
|
+
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardRotate);
|
|
1410
|
+
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardTranslate);
|
|
1411
|
+
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardSelect);
|
|
1412
|
+
if (customEventProps) {
|
|
1413
|
+
customEventProps.forEach((customEventProp) => {
|
|
1414
|
+
switch (customEventProp.eventType) {
|
|
1415
|
+
// Handle Pointer Events
|
|
1416
|
+
case Events.EventType.POINTER_DOWN:
|
|
1417
|
+
case Events.EventType.POINTER_UP:
|
|
1418
|
+
case Events.EventType.POINTER_MOVE:
|
|
1419
|
+
case Events.EventType.POINTER_WHEEL:
|
|
1420
|
+
case Events.EventType.TOUCH_END:
|
|
1421
|
+
case Events.EventType.TOUCH_MOVE:
|
|
1422
|
+
case Events.EventType.TOUCH_START:
|
|
1423
|
+
eventManager.on(
|
|
1424
|
+
customEventProp.eventType,
|
|
1425
|
+
customEventProp.callback
|
|
1426
|
+
);
|
|
1427
|
+
break;
|
|
1428
|
+
// Handle Keyboard Events
|
|
1429
|
+
case Events.EventType.KEY_DOWN:
|
|
1430
|
+
case Events.EventType.KEY_UP:
|
|
1431
|
+
eventManager.on(
|
|
1432
|
+
customEventProp.eventType,
|
|
1433
|
+
customEventProp.callback
|
|
1434
|
+
);
|
|
1435
|
+
break;
|
|
1436
|
+
// Handle Pinch Events
|
|
1437
|
+
case Events.EventType.PINCH:
|
|
1438
|
+
case Events.EventType.PINCH_END:
|
|
1439
|
+
case Events.EventType.PINCH_START:
|
|
1440
|
+
eventManager.on(
|
|
1441
|
+
customEventProp.eventType,
|
|
1442
|
+
customEventProp.callback
|
|
1443
|
+
);
|
|
1444
|
+
break;
|
|
1445
|
+
// Handle Selection Events
|
|
1446
|
+
case Events.EventType.OBJECT_SELECTED:
|
|
1447
|
+
case Events.EventType.OBJECT_DESELECTED:
|
|
1448
|
+
eventManager.on(
|
|
1449
|
+
customEventProp.eventType,
|
|
1450
|
+
customEventProp.callback
|
|
1451
|
+
);
|
|
1452
|
+
break;
|
|
1453
|
+
// Handle Events
|
|
1454
|
+
default:
|
|
1455
|
+
eventManager.on(
|
|
1456
|
+
customEventProp.eventType,
|
|
1457
|
+
customEventProp.callback
|
|
1458
|
+
);
|
|
1459
|
+
break;
|
|
1460
|
+
}
|
|
1400
1461
|
});
|
|
1401
|
-
const eventManager = scene.current?.eventManager;
|
|
1402
|
-
eventManager.on(Events.EventType.OBJECT_SELECTED, onSelectMotif);
|
|
1403
|
-
eventManager.on(Events.EventType.OBJECT_DESELECTED, onDeselectMotif);
|
|
1404
|
-
eventManager.on(Events.EventType.POINTER_MOVE, onMouseMove);
|
|
1405
|
-
eventManager.on(Events.EventType.POINTER_WHEEL, onMouseScroll);
|
|
1406
|
-
eventManager.on(Events.EventType.POINTER_DOWN, onMouseDown);
|
|
1407
|
-
eventManager.on(Events.EventType.POINTER_UP, onMouseUp);
|
|
1408
|
-
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardRotate);
|
|
1409
|
-
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardTranslate);
|
|
1410
|
-
eventManager.on(Events.EventType.KEY_DOWN, onKeyboardSelect);
|
|
1411
|
-
if (customEventProps) {
|
|
1412
|
-
customEventProps.forEach((customEventProp) => {
|
|
1413
|
-
switch (customEventProp.eventType) {
|
|
1414
|
-
// Handle Pointer Events
|
|
1415
|
-
case Events.EventType.POINTER_DOWN:
|
|
1416
|
-
case Events.EventType.POINTER_UP:
|
|
1417
|
-
case Events.EventType.POINTER_MOVE:
|
|
1418
|
-
case Events.EventType.POINTER_WHEEL:
|
|
1419
|
-
case Events.EventType.TOUCH_END:
|
|
1420
|
-
case Events.EventType.TOUCH_MOVE:
|
|
1421
|
-
case Events.EventType.TOUCH_START:
|
|
1422
|
-
eventManager.on(
|
|
1423
|
-
customEventProp.eventType,
|
|
1424
|
-
customEventProp.callback
|
|
1425
|
-
);
|
|
1426
|
-
break;
|
|
1427
|
-
// Handle Keyboard Events
|
|
1428
|
-
case Events.EventType.KEY_DOWN:
|
|
1429
|
-
case Events.EventType.KEY_UP:
|
|
1430
|
-
eventManager.on(
|
|
1431
|
-
customEventProp.eventType,
|
|
1432
|
-
customEventProp.callback
|
|
1433
|
-
);
|
|
1434
|
-
break;
|
|
1435
|
-
// Handle Pinch Events
|
|
1436
|
-
case Events.EventType.PINCH:
|
|
1437
|
-
case Events.EventType.PINCH_END:
|
|
1438
|
-
case Events.EventType.PINCH_START:
|
|
1439
|
-
eventManager.on(
|
|
1440
|
-
customEventProp.eventType,
|
|
1441
|
-
customEventProp.callback
|
|
1442
|
-
);
|
|
1443
|
-
break;
|
|
1444
|
-
// Handle Selection Events
|
|
1445
|
-
case Events.EventType.OBJECT_SELECTED:
|
|
1446
|
-
case Events.EventType.OBJECT_DESELECTED:
|
|
1447
|
-
eventManager.on(
|
|
1448
|
-
customEventProp.eventType,
|
|
1449
|
-
customEventProp.callback
|
|
1450
|
-
);
|
|
1451
|
-
break;
|
|
1452
|
-
// Handle Events
|
|
1453
|
-
default:
|
|
1454
|
-
eventManager.on(
|
|
1455
|
-
customEventProp.eventType,
|
|
1456
|
-
customEventProp.callback
|
|
1457
|
-
);
|
|
1458
|
-
break;
|
|
1459
|
-
}
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
1462
|
}
|
|
1463
|
+
scene.current.start();
|
|
1464
|
+
}
|
|
1465
|
+
}, []);
|
|
1466
|
+
useEffect(() => {
|
|
1467
|
+
if (!scene.current || !canvasRef.current) return;
|
|
1468
|
+
motifs.current.length = 0;
|
|
1469
|
+
motifProps.forEach((motifProp) => {
|
|
1470
|
+
motifs.current.push(motifProp.motif);
|
|
1471
|
+
});
|
|
1472
|
+
if (motifs.current.length > 0) {
|
|
1473
|
+
if (showRMSD) setKabschRMSD(calculateAllKabschRMSD(motifs.current));
|
|
1474
|
+
scene.current.removeAll();
|
|
1475
|
+
const positions = calculatePositions(motifs.current.length);
|
|
1476
|
+
motifs.current.forEach((motifMesh, index) => {
|
|
1477
|
+
scene.current?.add(motifMesh);
|
|
1478
|
+
if (motifProps[index].position) positions[index] = motifProps[index].position.clone();
|
|
1479
|
+
motifMesh.setPosition(positions[index].x, positions[index].y, positions[index].z);
|
|
1480
|
+
if (motifProps[index].rotation) motifMesh.setQuaternion(motifProps[index].rotation);
|
|
1481
|
+
let scale = canvasRef.current.width / 250;
|
|
1482
|
+
if (motifProps[index].scale) scale = motifProps[index].scale;
|
|
1483
|
+
motifMesh.setScale(scale);
|
|
1484
|
+
if (motifProps[index].locked) lockedMotifIdState.current.add(motifMesh.uuid);
|
|
1485
|
+
});
|
|
1463
1486
|
}
|
|
1464
|
-
scene.current?.start();
|
|
1465
1487
|
}, [rendererWidth, rendererHeight, rendererSizeIsWindow, motifProps]);
|
|
1466
1488
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("canvas", { ref: canvasRef }));
|
|
1467
1489
|
}
|
package/package.json
CHANGED