react-cheminfo 0.64.0 → 0.64.1
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/lib/molecule3d/core/highlight.d.ts.map +1 -1
- package/lib/molecule3d/core/highlight.js +2 -8
- package/lib/molecule3d/core/highlight.js.map +1 -1
- package/lib/molecule3d/core/index.d.ts +1 -1
- package/lib/molecule3d/core/index.d.ts.map +1 -1
- package/lib/molecule3d/core/index.js +1 -1
- package/lib/molecule3d/core/index.js.map +1 -1
- package/lib/molecule3d/core/measurement.d.ts +17 -0
- package/lib/molecule3d/core/measurement.d.ts.map +1 -1
- package/lib/molecule3d/core/measurement.js +43 -0
- package/lib/molecule3d/core/measurement.js.map +1 -1
- package/lib/molecule3d/ui/drawScene.d.ts +4 -2
- package/lib/molecule3d/ui/drawScene.d.ts.map +1 -1
- package/lib/molecule3d/ui/drawScene.js +1 -1
- package/lib/molecule3d/ui/drawScene.js.map +1 -1
- package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts +3 -1
- package/lib/molecule3d/ui/moleculeViewer3DProps.d.ts.map +1 -1
- package/lib/molecule3d/ui/sceneDrawer.d.ts +47 -0
- package/lib/molecule3d/ui/sceneDrawer.d.ts.map +1 -0
- package/lib/molecule3d/ui/sceneDrawer.js +103 -0
- package/lib/molecule3d/ui/sceneDrawer.js.map +1 -0
- package/lib/molecule3d/ui/useMoleculeScene.d.ts +2 -1
- package/lib/molecule3d/ui/useMoleculeScene.d.ts.map +1 -1
- package/lib/molecule3d/ui/useMoleculeScene.js +13 -22
- package/lib/molecule3d/ui/useMoleculeScene.js.map +1 -1
- package/lib/molecule3d/ui/useSharedCamera.d.ts +1 -3
- package/lib/molecule3d/ui/useSharedCamera.d.ts.map +1 -1
- package/lib/molecule3d/ui/useSharedCamera.js.map +1 -1
- package/package.json +1 -1
- package/src/molecule3d/core/highlight.ts +2 -8
- package/src/molecule3d/core/index.ts +1 -0
- package/src/molecule3d/core/measurement.ts +47 -0
- package/src/molecule3d/ui/drawScene.ts +13 -2
- package/src/molecule3d/ui/moleculeViewer3DProps.ts +3 -1
- package/src/molecule3d/ui/sceneDrawer.ts +132 -0
- package/src/molecule3d/ui/useMoleculeScene.ts +16 -26
- package/src/molecule3d/ui/useSharedCamera.ts +1 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/core/highlight.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"highlight.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/core/highlight.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,0DAA0D;AAC1D,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CACjC;AAED,wEAAwE;AACxE,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;AAEtE,2EAA2E;AAC3E,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IAChC,+EAA+E;IAC/E,KAAK,EAAE,SAAS,eAAe,EAAE,CAAC;CACnC;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,SAAS,mBAAmB,EAAE,EAC1C,OAAO,GAAE,CAAC,IAAI,EAAE,aAAa,KAAK,OAAmB,GACpD,gBAAgB,CA2BlB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS,mBAAmB,EAAE,EACrC,MAAM,EAAE,SAAS,mBAAmB,EAAE,GACrC,OAAO,CAUT"}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* read off one conformer lands on the same atoms of every other conformer of
|
|
8
8
|
* the same molecule.
|
|
9
9
|
*/
|
|
10
|
+
import { sameAtoms } from "./measurement.js";
|
|
10
11
|
/**
|
|
11
12
|
* The atoms and the bonds a list of highlights emphasises.
|
|
12
13
|
*
|
|
@@ -67,15 +68,8 @@ export function sameHighlights(first, second) {
|
|
|
67
68
|
const other = second[index]?.atoms;
|
|
68
69
|
if (one === undefined || other === undefined)
|
|
69
70
|
return false;
|
|
70
|
-
if (one
|
|
71
|
+
if (!sameAtoms(one, other))
|
|
71
72
|
return false;
|
|
72
|
-
for (let position = 0; position < one.length; position++) {
|
|
73
|
-
const atom = one[position];
|
|
74
|
-
const match = other[position];
|
|
75
|
-
if (atom?.unit !== match?.unit || atom?.element !== match?.element) {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
73
|
}
|
|
80
74
|
return true;
|
|
81
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../../src/molecule3d/core/highlight.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"highlight.js","sourceRoot":"","sources":["../../../src/molecule3d/core/highlight.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ export { MOLECULE_3D_GESTURES } from './gestures.ts';
|
|
|
7
7
|
export type { HighlightedBond, HighlightedParts, Molecule3DHighlight, } from './highlight.ts';
|
|
8
8
|
export { highlightedParts, sameHighlights } from './highlight.ts';
|
|
9
9
|
export type { AtomReference, Measurement, MeasurementKind, } from './measurement.ts';
|
|
10
|
-
export { MEASUREMENT_ATOM_COUNTS, MEASUREMENT_KINDS, MEASUREMENT_LABELS, } from './measurement.ts';
|
|
10
|
+
export { MEASUREMENT_ATOM_COUNTS, MEASUREMENT_KINDS, MEASUREMENT_LABELS, sameMeasurements, } from './measurement.ts';
|
|
11
11
|
export type { Molecule3DFile, Molecule3DSettings, Molecule3DTools, RepresentationId, SurfaceColoringId, } from './settings.ts';
|
|
12
12
|
export { DEFAULT_MOLECULE_3D_SETTINGS, DEFAULT_MOLECULE_3D_TOOLS, MOLECULE_3D_RANGES, REPRESENTATIONS, REPRESENTATION_LABELS, SURFACE_CHARGE_COLORS, SURFACE_COLORINGS, SURFACE_COLORING_LABELS, isRepresentationId, isSurfaceColoringId, normalizeMolecule3DSettings, resetMolecule3DSettings, resolveMolecule3DTools, sameMolecule3DSettings, } from './settings.ts';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EACV,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/core/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,gBAAgB,EAChB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACjE,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EACV,eAAe,EACf,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EACV,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC"}
|
|
@@ -2,6 +2,6 @@ export { DEFAULT_MOLECULE_3D_CAMERA, MOLECULE_3D_ZOOM_RANGE, formatMolecule3DCam
|
|
|
2
2
|
export { dataUriBytes, rasterSvgMarkup } from "./exportImage.js";
|
|
3
3
|
export { MOLECULE_3D_GESTURES } from "./gestures.js";
|
|
4
4
|
export { highlightedParts, sameHighlights } from "./highlight.js";
|
|
5
|
-
export { MEASUREMENT_ATOM_COUNTS, MEASUREMENT_KINDS, MEASUREMENT_LABELS, } from "./measurement.js";
|
|
5
|
+
export { MEASUREMENT_ATOM_COUNTS, MEASUREMENT_KINDS, MEASUREMENT_LABELS, sameMeasurements, } from "./measurement.js";
|
|
6
6
|
export { DEFAULT_MOLECULE_3D_SETTINGS, DEFAULT_MOLECULE_3D_TOOLS, MOLECULE_3D_RANGES, REPRESENTATIONS, REPRESENTATION_LABELS, SURFACE_CHARGE_COLORS, SURFACE_COLORINGS, SURFACE_COLORING_LABELS, isRepresentationId, isSurfaceColoringId, normalizeMolecule3DSettings, resetMolecule3DSettings, resolveMolecule3DTools, sameMolecule3DSettings, } from "./settings.js";
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/molecule3d/core/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAMrD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMlE,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/molecule3d/core/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,0BAA0B,EAC1B,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAMrD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMlE,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,mBAAmB,EACnB,2BAA2B,EAC3B,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,eAAe,CAAC"}
|
|
@@ -27,4 +27,21 @@ export interface Measurement {
|
|
|
27
27
|
kind: MeasurementKind;
|
|
28
28
|
atoms: readonly AtomReference[];
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Whether two lists name the same measurements, of the same kinds over the
|
|
32
|
+
* same atoms, in the same order — what decides that nothing needs drawing
|
|
33
|
+
* again.
|
|
34
|
+
* @param first - One list.
|
|
35
|
+
* @param second - The other.
|
|
36
|
+
* @returns True when every measurement of one is the measurement of the other
|
|
37
|
+
* at its place.
|
|
38
|
+
*/
|
|
39
|
+
export declare function sameMeasurements(first: readonly Measurement[], second: readonly Measurement[]): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether two lists name the same atoms in the same order.
|
|
42
|
+
* @param first - One list.
|
|
43
|
+
* @param second - The other.
|
|
44
|
+
* @returns True when every atom of one is the atom of the other at its place.
|
|
45
|
+
*/
|
|
46
|
+
export declare function sameAtoms(first: readonly AtomReference[], second: readonly AtomReference[]): boolean;
|
|
30
47
|
//# sourceMappingURL=measurement.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measurement.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/core/measurement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,4CAA6C,CAAC;AAE5E,wCAAwC;AACxC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAInE,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAI9D,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CACjC"}
|
|
1
|
+
{"version":3,"file":"measurement.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/core/measurement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,iBAAiB,4CAA6C,CAAC;AAE5E,wCAAwC;AACxC,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjE,oDAAoD;AACpD,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAInE,CAAC;AAEF,wCAAwC;AACxC,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAI9D,CAAC;AAEF,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;CACjC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,WAAW,EAAE,EAC7B,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,OAAO,CAYT;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,MAAM,EAAE,SAAS,aAAa,EAAE,GAC/B,OAAO,CAUT"}
|
|
@@ -21,4 +21,47 @@ export const MEASUREMENT_LABELS = {
|
|
|
21
21
|
angle: 'Angle',
|
|
22
22
|
dihedral: 'Dihedral angle',
|
|
23
23
|
};
|
|
24
|
+
/**
|
|
25
|
+
* Whether two lists name the same measurements, of the same kinds over the
|
|
26
|
+
* same atoms, in the same order — what decides that nothing needs drawing
|
|
27
|
+
* again.
|
|
28
|
+
* @param first - One list.
|
|
29
|
+
* @param second - The other.
|
|
30
|
+
* @returns True when every measurement of one is the measurement of the other
|
|
31
|
+
* at its place.
|
|
32
|
+
*/
|
|
33
|
+
export function sameMeasurements(first, second) {
|
|
34
|
+
if (first === second)
|
|
35
|
+
return true;
|
|
36
|
+
if (first.length !== second.length)
|
|
37
|
+
return false;
|
|
38
|
+
for (let index = 0; index < first.length; index++) {
|
|
39
|
+
const one = first[index];
|
|
40
|
+
const other = second[index];
|
|
41
|
+
if (one === undefined || other === undefined)
|
|
42
|
+
return false;
|
|
43
|
+
if (one.kind !== other.kind || !sameAtoms(one.atoms, other.atoms)) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether two lists name the same atoms in the same order.
|
|
51
|
+
* @param first - One list.
|
|
52
|
+
* @param second - The other.
|
|
53
|
+
* @returns True when every atom of one is the atom of the other at its place.
|
|
54
|
+
*/
|
|
55
|
+
export function sameAtoms(first, second) {
|
|
56
|
+
if (first.length !== second.length)
|
|
57
|
+
return false;
|
|
58
|
+
for (let position = 0; position < first.length; position++) {
|
|
59
|
+
const atom = first[position];
|
|
60
|
+
const match = second[position];
|
|
61
|
+
if (atom?.unit !== match?.unit || atom?.element !== match?.element) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
24
67
|
//# sourceMappingURL=measurement.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measurement.js","sourceRoot":"","sources":["../../../src/molecule3d/core/measurement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAK5E,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAoC;IACtE,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF,wCAAwC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAoC;IACjE,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,gBAAgB;CAC3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"measurement.js","sourceRoot":"","sources":["../../../src/molecule3d/core/measurement.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAU,CAAC;AAK5E,oDAAoD;AACpD,MAAM,CAAC,MAAM,uBAAuB,GAAoC;IACtE,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;IACR,QAAQ,EAAE,CAAC;CACZ,CAAC;AAEF,wCAAwC;AACxC,MAAM,CAAC,MAAM,kBAAkB,GAAoC;IACjE,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,gBAAgB;CAC3B,CAAC;AAgBF;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAC9B,KAA6B,EAC7B,MAA8B;IAE9B,IAAI,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAClC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACjD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,GAAG,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAC3D,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAClE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CACvB,KAA+B,EAC/B,MAAgC;IAEhC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACjD,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,IAAI,IAAI,EAAE,IAAI,KAAK,KAAK,EAAE,IAAI,IAAI,IAAI,EAAE,OAAO,KAAK,KAAK,EAAE,OAAO,EAAE,CAAC;YACnE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { Measurement } from '../core/measurement.ts';
|
|
2
2
|
import type { Molecule3DFile, Molecule3DSettings } from '../core/settings.ts';
|
|
3
3
|
import type { Molecule3DViewer } from './viewer.ts';
|
|
4
|
+
/** The operations of the viewer a scene is drawn with. */
|
|
5
|
+
export type SceneViewer = Pick<Molecule3DViewer, 'showMolecule' | 'hideMolecule' | 'showSurface' | 'showMeasurements' | 'resetCamera' | 'setCamera'>;
|
|
4
6
|
/**
|
|
5
|
-
* Draw the scene. `showMolecule` empties it, so the surface and the
|
|
7
|
+
* Draw the whole scene. `showMolecule` empties it, so the surface and the
|
|
6
8
|
* measurements are added after the model, and the camera is framed last.
|
|
7
9
|
* @param viewer - The viewer holding the canvas.
|
|
8
10
|
* @param molfile - What to draw, or `null` to empty the scene.
|
|
@@ -13,5 +15,5 @@ import type { Molecule3DViewer } from './viewer.ts';
|
|
|
13
15
|
* down -z, `none` leaves the camera alone.
|
|
14
16
|
* @returns Nothing; resolves once the scene is complete.
|
|
15
17
|
*/
|
|
16
|
-
export declare function drawScene(viewer:
|
|
18
|
+
export declare function drawScene(viewer: SceneViewer, molfile: Molecule3DFile | null, settings: Molecule3DSettings, measurements: readonly Measurement[], frameCamera: 'none' | 'keep' | 'front'): Promise<void>;
|
|
17
19
|
//# sourceMappingURL=drawScene.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawScene.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/drawScene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"drawScene.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/drawScene.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GAAG,IAAI,CAC5B,gBAAgB,EACd,cAAc,GACd,cAAc,GACd,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,WAAW,CACd,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,cAAc,GAAG,IAAI,EAC9B,QAAQ,EAAE,kBAAkB,EAC5B,YAAY,EAAE,SAAS,WAAW,EAAE,EACpC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GACrC,OAAO,CAAC,IAAI,CAAC,CAqBf"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { normalizeMolecule3DSettings } from "../core/settings.js";
|
|
2
2
|
/**
|
|
3
|
-
* Draw the scene. `showMolecule` empties it, so the surface and the
|
|
3
|
+
* Draw the whole scene. `showMolecule` empties it, so the surface and the
|
|
4
4
|
* measurements are added after the model, and the camera is framed last.
|
|
5
5
|
* @param viewer - The viewer holding the canvas.
|
|
6
6
|
* @param molfile - What to draw, or `null` to empty the scene.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drawScene.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/drawScene.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"drawScene.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/drawScene.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAelE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,MAAmB,EACnB,OAA8B,EAC9B,QAA4B,EAC5B,YAAoC,EACpC,WAAsC;IAEtC,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,MAAM,CAAC,YAAY,EAAE,CAAC;QAC5B,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE;QACjC,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CAAC,CAAC;IACH,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,MAAM,CAAC,WAAW,CAAC;YACvB,KAAK,EAAE,IAAI,CAAC,YAAY;YACxB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,eAAe;YAC9B,KAAK,EAAE,IAAI,CAAC,YAAY;SACzB,CAAC,CAAC;IACL,CAAC;IACD,MAAM,MAAM,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,WAAW,KAAK,MAAM;QAAE,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC;IACvD,IAAI,WAAW,KAAK,OAAO;QAAE,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -66,7 +66,9 @@ export interface MoleculeViewer3DProps {
|
|
|
66
66
|
/**
|
|
67
67
|
* The measurements drawn over the model, when the site owns them. They name
|
|
68
68
|
* atoms by position, so they carry over to another conformer of the same
|
|
69
|
-
* molecule; a site showing an unrelated molecule should clear them.
|
|
69
|
+
* molecule; a site showing an unrelated molecule should clear them. Changing
|
|
70
|
+
* them redraws the measurements and nothing else: the model, its highlights
|
|
71
|
+
* and the camera are left as they are.
|
|
70
72
|
* @default undefined
|
|
71
73
|
*/
|
|
72
74
|
measurements?: readonly Measurement[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"moleculeViewer3DProps.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/moleculeViewer3DProps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB
|
|
1
|
+
{"version":3,"file":"moleculeViewer3DProps.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/moleculeViewer3DProps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EAChB,MAAM,qBAAqB,CAAC;AAE7B;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACpC;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACjC;;;OAGG;IACH,QAAQ,CAAC,EAAE,kBAAkB,CAAC;IAC9B;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC9C;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC1D;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC;;;OAGG;IACH,oBAAoB,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,WAAW,EAAE,KAAK,IAAI,CAAC;IACtE;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC5C;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACxC;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACpD;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,SAAS,CAAC;CACjE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one canvas shows, what it is asked to show next, and the least work
|
|
3
|
+
* between the two.
|
|
4
|
+
*
|
|
5
|
+
* The measurements are drawn over the model, not into it: a change of them
|
|
6
|
+
* alone replaces their own representations and leaves the model, its surface,
|
|
7
|
+
* its highlights and the camera as they are. Only another molecule, or another
|
|
8
|
+
* style for it, draws the scene again, and only another molecule frames the
|
|
9
|
+
* camera. Draws run one after another, so a measurement never lands on a model
|
|
10
|
+
* that is half built, and the last request asked is the one drawn.
|
|
11
|
+
*/
|
|
12
|
+
import type { Molecule3DCamera } from '../core/camera.ts';
|
|
13
|
+
import type { Measurement } from '../core/measurement.ts';
|
|
14
|
+
import type { Molecule3DFile, Molecule3DSettings } from '../core/settings.ts';
|
|
15
|
+
import type { SceneViewer } from './drawScene.ts';
|
|
16
|
+
/** What the canvas is asked to show. */
|
|
17
|
+
export interface SceneRequest {
|
|
18
|
+
/** What to draw, or `null` to empty the scene. */
|
|
19
|
+
molfile: Molecule3DFile | null;
|
|
20
|
+
/** How the model is drawn. */
|
|
21
|
+
settings: Molecule3DSettings;
|
|
22
|
+
/** What is drawn over it. */
|
|
23
|
+
measurements: readonly Measurement[];
|
|
24
|
+
/** How the camera meets a molecule it has not shown before. */
|
|
25
|
+
frameNewMolecule: 'front' | 'keep';
|
|
26
|
+
}
|
|
27
|
+
/** Keeps one viewer showing the last scene it was asked for. */
|
|
28
|
+
export declare class SceneDrawer {
|
|
29
|
+
#private;
|
|
30
|
+
/** The viewer drawn on. */
|
|
31
|
+
readonly viewer: SceneViewer;
|
|
32
|
+
/**
|
|
33
|
+
* Start drawing on `viewer`, whose scene is empty.
|
|
34
|
+
* @param viewer - The viewer to draw on.
|
|
35
|
+
* @param takeLinkedCamera - Asked when a molecule is new: a camera to stand
|
|
36
|
+
* at instead of framing it, or `null`.
|
|
37
|
+
*/
|
|
38
|
+
constructor(viewer: SceneViewer, takeLinkedCamera: () => Molecule3DCamera | null);
|
|
39
|
+
/**
|
|
40
|
+
* Bring the canvas to `request`, once whatever was asked before is drawn.
|
|
41
|
+
* @param request - The scene to show; replaces any request still waiting.
|
|
42
|
+
* @returns Nothing; resolves once the canvas shows the last request asked,
|
|
43
|
+
* and rejects with what stopped it from being drawn.
|
|
44
|
+
*/
|
|
45
|
+
draw(request: SceneRequest): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=sceneDrawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sceneDrawer.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/sceneDrawer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAG9E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGlD,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,8BAA8B;IAC9B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,6BAA6B;IAC7B,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IACrC,+DAA+D;IAC/D,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAAC;CACpC;AAED,gEAAgE;AAChE,qBAAa,WAAW;;IACtB,2BAA2B;IAC3B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAW7B;;;;;OAKG;gBAED,MAAM,EAAE,WAAW,EACnB,gBAAgB,EAAE,MAAM,gBAAgB,GAAG,IAAI;IAMjD;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;CAoD3C"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one canvas shows, what it is asked to show next, and the least work
|
|
3
|
+
* between the two.
|
|
4
|
+
*
|
|
5
|
+
* The measurements are drawn over the model, not into it: a change of them
|
|
6
|
+
* alone replaces their own representations and leaves the model, its surface,
|
|
7
|
+
* its highlights and the camera as they are. Only another molecule, or another
|
|
8
|
+
* style for it, draws the scene again, and only another molecule frames the
|
|
9
|
+
* camera. Draws run one after another, so a measurement never lands on a model
|
|
10
|
+
* that is half built, and the last request asked is the one drawn.
|
|
11
|
+
*/
|
|
12
|
+
import { sameMeasurements } from "../core/measurement.js";
|
|
13
|
+
import { sameMolecule3DSettings } from "../core/settings.js";
|
|
14
|
+
import { drawScene } from "./drawScene.js";
|
|
15
|
+
/** Keeps one viewer showing the last scene it was asked for. */
|
|
16
|
+
export class SceneDrawer {
|
|
17
|
+
/** The viewer drawn on. */
|
|
18
|
+
viewer;
|
|
19
|
+
#takeLinkedCamera;
|
|
20
|
+
#asked = null;
|
|
21
|
+
// The model on screen, or `null` when the next request must draw it again.
|
|
22
|
+
#drawn = null;
|
|
23
|
+
// The measurements on screen, or `null` when the next request must draw them.
|
|
24
|
+
#measured = [];
|
|
25
|
+
// The molecule the camera was last framed on, so another one is told apart.
|
|
26
|
+
#framed = null;
|
|
27
|
+
#queue = Promise.resolve();
|
|
28
|
+
/**
|
|
29
|
+
* Start drawing on `viewer`, whose scene is empty.
|
|
30
|
+
* @param viewer - The viewer to draw on.
|
|
31
|
+
* @param takeLinkedCamera - Asked when a molecule is new: a camera to stand
|
|
32
|
+
* at instead of framing it, or `null`.
|
|
33
|
+
*/
|
|
34
|
+
constructor(viewer, takeLinkedCamera) {
|
|
35
|
+
this.viewer = viewer;
|
|
36
|
+
this.#takeLinkedCamera = takeLinkedCamera;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Bring the canvas to `request`, once whatever was asked before is drawn.
|
|
40
|
+
* @param request - The scene to show; replaces any request still waiting.
|
|
41
|
+
* @returns Nothing; resolves once the canvas shows the last request asked,
|
|
42
|
+
* and rejects with what stopped it from being drawn.
|
|
43
|
+
*/
|
|
44
|
+
draw(request) {
|
|
45
|
+
this.#asked = request;
|
|
46
|
+
const drawn = this.#queue.then(() => this.#catchUp());
|
|
47
|
+
this.#queue = drawn.catch(ignore);
|
|
48
|
+
return drawn;
|
|
49
|
+
}
|
|
50
|
+
async #catchUp() {
|
|
51
|
+
const request = this.#asked;
|
|
52
|
+
if (request === null)
|
|
53
|
+
return;
|
|
54
|
+
const drawn = this.#drawn;
|
|
55
|
+
if (drawn !== null &&
|
|
56
|
+
sameFile(drawn.molfile, request.molfile) &&
|
|
57
|
+
sameMolecule3DSettings(drawn.settings, request.settings)) {
|
|
58
|
+
await this.#measure(request);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
await this.#redraw(request);
|
|
62
|
+
}
|
|
63
|
+
// The model stays: only the measurements over it can have changed.
|
|
64
|
+
async #measure(request) {
|
|
65
|
+
const { molfile, measurements } = request;
|
|
66
|
+
const measured = this.#measured;
|
|
67
|
+
if (measured !== null && sameMeasurements(measured, measurements))
|
|
68
|
+
return;
|
|
69
|
+
// As for the model: a list that fails partway is drawn again next time.
|
|
70
|
+
this.#measured = null;
|
|
71
|
+
// An empty scene has nothing to measure; the list waits for a molecule.
|
|
72
|
+
if (molfile !== null)
|
|
73
|
+
await this.viewer.showMeasurements(measurements);
|
|
74
|
+
this.#measured = measurements;
|
|
75
|
+
}
|
|
76
|
+
async #redraw(request) {
|
|
77
|
+
const { molfile, settings, measurements, frameNewMolecule } = request;
|
|
78
|
+
const isNew = molfile !== null &&
|
|
79
|
+
(this.#framed === null || !sameFile(this.#framed, molfile));
|
|
80
|
+
this.#framed = molfile;
|
|
81
|
+
// A link's camera is spent on the first molecule framed; afterwards the
|
|
82
|
+
// camera is the reader's and a new molecule is framed as usual.
|
|
83
|
+
const linked = isNew ? this.#takeLinkedCamera() : null;
|
|
84
|
+
const frameCamera = isNew && linked === null ? frameNewMolecule : 'none';
|
|
85
|
+
// Kept only once drawn: a draw that fails is drawn again by the next
|
|
86
|
+
// request, whatever that one changes.
|
|
87
|
+
this.#drawn = null;
|
|
88
|
+
await drawScene(this.viewer, molfile, settings, measurements, frameCamera);
|
|
89
|
+
this.#drawn = { molfile, settings };
|
|
90
|
+
this.#measured = measurements;
|
|
91
|
+
if (linked !== null)
|
|
92
|
+
await this.viewer.setCamera(linked);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function sameFile(first, second) {
|
|
96
|
+
if (first === null || second === null)
|
|
97
|
+
return first === second;
|
|
98
|
+
return first.format === second.format && first.data === second.data;
|
|
99
|
+
}
|
|
100
|
+
function ignore() {
|
|
101
|
+
// A failure reached the caller of `draw`; the next draw still runs.
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=sceneDrawer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sceneDrawer.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/sceneDrawer.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* The draw is coalesced into one animation frame, so dragging a slider costs
|
|
6
6
|
* one rebuild rather than one per pixel, and the camera is framed only when the
|
|
7
7
|
* molecule is new — a restyle that snapped the view back would undo the
|
|
8
|
-
* reader's orientation.
|
|
8
|
+
* reader's orientation. What each draw rebuilds is the scene drawer's call: a
|
|
9
|
+
* change of the measurements alone redraws them and nothing else.
|
|
9
10
|
*/
|
|
10
11
|
import type { RefObject } from 'react';
|
|
11
12
|
import type { Measurement } from '../core/measurement.ts';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMoleculeScene.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/useMoleculeScene.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useMoleculeScene.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/useMoleculeScene.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAMxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,8CAA8C;AAC9C,MAAM,WAAW,oBAAoB;IACnC,gEAAgE;IAChE,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,gCAAgC;IAChC,SAAS,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC9C,kDAAkD;IAClD,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,8DAA8D;IAC9D,gBAAgB,EAAE,OAAO,GAAG,MAAM,CAAC;IACnC,8BAA8B;IAC9B,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,6BAA6B;IAC7B,YAAY,EAAE,SAAS,WAAW,EAAE,CAAC;IACrC,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAC;IAClB,2EAA2E;IAC3E,eAAe,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD,kFAAkF;IAClF,MAAM,EAAE,IAAI,CACV,qBAAqB,EACrB,mBAAmB,GAAG,eAAe,GAAG,gBAAgB,CACzD,CAAC;CACH;AAED,6CAA6C;AAC7C,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAqE7E"}
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* The draw is coalesced into one animation frame, so dragging a slider costs
|
|
6
6
|
* one rebuild rather than one per pixel, and the camera is framed only when the
|
|
7
7
|
* molecule is new — a restyle that snapped the view back would undo the
|
|
8
|
-
* reader's orientation.
|
|
8
|
+
* reader's orientation. What each draw rebuilds is the scene drawer's call: a
|
|
9
|
+
* change of the measurements alone redraws them and nothing else.
|
|
9
10
|
*/
|
|
10
11
|
import { useCallback, useEffect, useRef } from 'react';
|
|
11
|
-
import {
|
|
12
|
+
import { SceneDrawer } from "./sceneDrawer.js";
|
|
12
13
|
import { DEFAULT_CAMERA_SETTLE_DELAY, useSharedCamera, } from "./useSharedCamera.js";
|
|
13
14
|
/**
|
|
14
15
|
* Draw the scene the options describe, and keep it drawn.
|
|
@@ -17,7 +18,7 @@ import { DEFAULT_CAMERA_SETTLE_DELAY, useSharedCamera, } from "./useSharedCamera
|
|
|
17
18
|
*/
|
|
18
19
|
export function useMoleculeScene(options) {
|
|
19
20
|
const { container, viewerRef, molfile, frameNewMolecule, settings, measurements, spinning, onFailureChange, camera: cameraProps, } = options;
|
|
20
|
-
const
|
|
21
|
+
const drawerRef = useRef(null);
|
|
21
22
|
const reportFailure = useRef(onFailureChange);
|
|
22
23
|
useEffect(() => {
|
|
23
24
|
reportFailure.current = onFailureChange;
|
|
@@ -34,27 +35,17 @@ export function useMoleculeScene(options) {
|
|
|
34
35
|
const viewer = viewerRef.current;
|
|
35
36
|
if (container === null || viewer === null)
|
|
36
37
|
return;
|
|
38
|
+
// A new viewer starts from an empty scene, so it gets a drawer of its own.
|
|
39
|
+
if (drawerRef.current?.viewer !== viewer) {
|
|
40
|
+
drawerRef.current = new SceneDrawer(viewer, camera.takeLinkedCamera);
|
|
41
|
+
}
|
|
42
|
+
const drawer = drawerRef.current;
|
|
37
43
|
let cancelled = false;
|
|
38
44
|
const frame = requestAnimationFrame(() => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// The link's camera is spent on the first molecule framed; afterwards the
|
|
44
|
-
// camera is the reader's and a new molecule is framed as usual.
|
|
45
|
-
const linked = isNew
|
|
46
|
-
? camera.takeLinkedCamera()
|
|
47
|
-
: null;
|
|
48
|
-
const frameCamera = isNew && linked === null ? frameNewMolecule : 'none';
|
|
49
|
-
void drawScene(viewer, molfile, settings, measurements, frameCamera)
|
|
50
|
-
.then(() => {
|
|
51
|
-
if (cancelled)
|
|
52
|
-
return;
|
|
53
|
-
if (linked !== null)
|
|
54
|
-
void viewer.setCamera(linked);
|
|
55
|
-
reportFailure.current(null);
|
|
56
|
-
})
|
|
57
|
-
.catch((error) => {
|
|
45
|
+
drawer.draw({ molfile, settings, measurements, frameNewMolecule }).then(() => {
|
|
46
|
+
if (!cancelled)
|
|
47
|
+
reportFailure.current(null);
|
|
48
|
+
}, (error) => {
|
|
58
49
|
if (cancelled)
|
|
59
50
|
return;
|
|
60
51
|
reportFailure.current(error instanceof Error ? error.message : String(error));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMoleculeScene.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/useMoleculeScene.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"useMoleculeScene.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/useMoleculeScene.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAMvD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EACL,2BAA2B,EAC3B,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAkC9B;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA6B;IAC5D,MAAM,EACJ,SAAS,EACT,SAAS,EACT,OAAO,EACP,gBAAgB,EAChB,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,eAAe,EACf,MAAM,EAAE,WAAW,GACpB,GAAG,OAAO,CAAC;IACZ,MAAM,SAAS,GAAG,MAAM,CAAqB,IAAI,CAAC,CAAC;IACnD,MAAM,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IAC9C,SAAS,CAAC,GAAG,EAAE;QACb,aAAa,CAAC,OAAO,GAAG,eAAe,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,eAAe,CAAC;QAC7B,SAAS;QACT,SAAS;QACT,QAAQ;QACR,aAAa,EAAE,WAAW,CAAC,aAAa,IAAI,IAAI;QAChD,cAAc,EAAE,WAAW,CAAC,cAAc;QAC1C,WAAW,EAAE,WAAW,CAAC,iBAAiB,IAAI,2BAA2B;KAC1E,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;QACjC,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO;QAClD,2EAA2E;QAC3E,IAAI,SAAS,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;YACzC,SAAS,CAAC,OAAO,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC;QACjC,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,MAAM,KAAK,GAAG,qBAAqB,CAAC,GAAG,EAAE;YACvC,MAAM,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC,CAAC,IAAI,CACrE,GAAG,EAAE;gBACH,IAAI,CAAC,SAAS;oBAAE,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC,EACD,CAAC,KAAc,EAAE,EAAE;gBACjB,IAAI,SAAS;oBAAE,OAAO;gBACtB,aAAa,CAAC,OAAO,CACnB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;YACJ,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE;YACV,SAAS,GAAG,IAAI,CAAC;YACjB,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC;IACJ,CAAC,EAAE;QACD,SAAS;QACT,SAAS;QACT,OAAO;QACP,gBAAgB;QAChB,QAAQ;QACR,YAAY;QACZ,MAAM;KACP,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAClB,KAAK,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC;IACxC,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAExB,OAAO,EAAE,SAAS,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -29,9 +29,7 @@ export interface SharedCameraOptions {
|
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
31
31
|
* What {@link useSharedCamera} answers. The same object on every render: the
|
|
32
|
-
* draw effect keys on it, and a fresh one would
|
|
33
|
-
* it again — which makes molstar frame the model afresh and loses the camera a
|
|
34
|
-
* link had just restored.
|
|
32
|
+
* draw effect keys on it, and a fresh one would run it again for nothing.
|
|
35
33
|
*/
|
|
36
34
|
export interface SharedCamera {
|
|
37
35
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSharedCamera.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/useSharedCamera.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,gCAAgC;IAChC,SAAS,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC9C,iEAAiE;IACjE,aAAa,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACpD,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED
|
|
1
|
+
{"version":3,"file":"useSharedCamera.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/useSharedCamera.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,iFAAiF;AACjF,eAAO,MAAM,2BAA2B,MAAM,CAAC;AAE/C,6CAA6C;AAC7C,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,SAAS,EAAE,WAAW,GAAG,IAAI,CAAC;IAC9B,gCAAgC;IAChC,SAAS,EAAE,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC9C,iEAAiE;IACjE,aAAa,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACvC,2DAA2D;IAC3D,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACpD,8DAA8D;IAC9D,QAAQ,EAAE,OAAO,CAAC;IAClB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;IAChD,mEAAmE;IACnE,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CA6D1E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSharedCamera.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/useSharedCamera.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAGhE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAI3D,iFAAiF;AACjF,MAAM,CAAC,MAAM,2BAA2B,GAAG,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"useSharedCamera.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/useSharedCamera.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-cheminfo",
|
|
3
|
-
"version": "0.64.
|
|
3
|
+
"version": "0.64.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React components, hooks and framework-free helpers shared by the cheminfo sites: site chrome, citations, sharing, routing, pedagogy, charts, and the structure, orbital and 3D molecule viewers",
|
|
6
6
|
"author": "Luc Patiny",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import type { AtomReference } from './measurement.ts';
|
|
12
|
+
import { sameAtoms } from './measurement.ts';
|
|
12
13
|
|
|
13
14
|
/** One bonded path of atoms to emphasise on the model. */
|
|
14
15
|
export interface Molecule3DHighlight {
|
|
@@ -95,14 +96,7 @@ export function sameHighlights(
|
|
|
95
96
|
const one = first[index]?.atoms;
|
|
96
97
|
const other = second[index]?.atoms;
|
|
97
98
|
if (one === undefined || other === undefined) return false;
|
|
98
|
-
if (one
|
|
99
|
-
for (let position = 0; position < one.length; position++) {
|
|
100
|
-
const atom = one[position];
|
|
101
|
-
const match = other[position];
|
|
102
|
-
if (atom?.unit !== match?.unit || atom?.element !== match?.element) {
|
|
103
|
-
return false;
|
|
104
|
-
}
|
|
105
|
-
}
|
|
99
|
+
if (!sameAtoms(one, other)) return false;
|
|
106
100
|
}
|
|
107
101
|
return true;
|
|
108
102
|
}
|
|
@@ -41,3 +41,50 @@ export interface Measurement {
|
|
|
41
41
|
kind: MeasurementKind;
|
|
42
42
|
atoms: readonly AtomReference[];
|
|
43
43
|
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether two lists name the same measurements, of the same kinds over the
|
|
47
|
+
* same atoms, in the same order — what decides that nothing needs drawing
|
|
48
|
+
* again.
|
|
49
|
+
* @param first - One list.
|
|
50
|
+
* @param second - The other.
|
|
51
|
+
* @returns True when every measurement of one is the measurement of the other
|
|
52
|
+
* at its place.
|
|
53
|
+
*/
|
|
54
|
+
export function sameMeasurements(
|
|
55
|
+
first: readonly Measurement[],
|
|
56
|
+
second: readonly Measurement[],
|
|
57
|
+
): boolean {
|
|
58
|
+
if (first === second) return true;
|
|
59
|
+
if (first.length !== second.length) return false;
|
|
60
|
+
for (let index = 0; index < first.length; index++) {
|
|
61
|
+
const one = first[index];
|
|
62
|
+
const other = second[index];
|
|
63
|
+
if (one === undefined || other === undefined) return false;
|
|
64
|
+
if (one.kind !== other.kind || !sameAtoms(one.atoms, other.atoms)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Whether two lists name the same atoms in the same order.
|
|
73
|
+
* @param first - One list.
|
|
74
|
+
* @param second - The other.
|
|
75
|
+
* @returns True when every atom of one is the atom of the other at its place.
|
|
76
|
+
*/
|
|
77
|
+
export function sameAtoms(
|
|
78
|
+
first: readonly AtomReference[],
|
|
79
|
+
second: readonly AtomReference[],
|
|
80
|
+
): boolean {
|
|
81
|
+
if (first.length !== second.length) return false;
|
|
82
|
+
for (let position = 0; position < first.length; position++) {
|
|
83
|
+
const atom = first[position];
|
|
84
|
+
const match = second[position];
|
|
85
|
+
if (atom?.unit !== match?.unit || atom?.element !== match?.element) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
@@ -4,8 +4,19 @@ import { normalizeMolecule3DSettings } from '../core/settings.ts';
|
|
|
4
4
|
|
|
5
5
|
import type { Molecule3DViewer } from './viewer.ts';
|
|
6
6
|
|
|
7
|
+
/** The operations of the viewer a scene is drawn with. */
|
|
8
|
+
export type SceneViewer = Pick<
|
|
9
|
+
Molecule3DViewer,
|
|
10
|
+
| 'showMolecule'
|
|
11
|
+
| 'hideMolecule'
|
|
12
|
+
| 'showSurface'
|
|
13
|
+
| 'showMeasurements'
|
|
14
|
+
| 'resetCamera'
|
|
15
|
+
| 'setCamera'
|
|
16
|
+
>;
|
|
17
|
+
|
|
7
18
|
/**
|
|
8
|
-
* Draw the scene. `showMolecule` empties it, so the surface and the
|
|
19
|
+
* Draw the whole scene. `showMolecule` empties it, so the surface and the
|
|
9
20
|
* measurements are added after the model, and the camera is framed last.
|
|
10
21
|
* @param viewer - The viewer holding the canvas.
|
|
11
22
|
* @param molfile - What to draw, or `null` to empty the scene.
|
|
@@ -17,7 +28,7 @@ import type { Molecule3DViewer } from './viewer.ts';
|
|
|
17
28
|
* @returns Nothing; resolves once the scene is complete.
|
|
18
29
|
*/
|
|
19
30
|
export async function drawScene(
|
|
20
|
-
viewer:
|
|
31
|
+
viewer: SceneViewer,
|
|
21
32
|
molfile: Molecule3DFile | null,
|
|
22
33
|
settings: Molecule3DSettings,
|
|
23
34
|
measurements: readonly Measurement[],
|
|
@@ -72,7 +72,9 @@ export interface MoleculeViewer3DProps {
|
|
|
72
72
|
/**
|
|
73
73
|
* The measurements drawn over the model, when the site owns them. They name
|
|
74
74
|
* atoms by position, so they carry over to another conformer of the same
|
|
75
|
-
* molecule; a site showing an unrelated molecule should clear them.
|
|
75
|
+
* molecule; a site showing an unrelated molecule should clear them. Changing
|
|
76
|
+
* them redraws the measurements and nothing else: the model, its highlights
|
|
77
|
+
* and the camera are left as they are.
|
|
76
78
|
* @default undefined
|
|
77
79
|
*/
|
|
78
80
|
measurements?: readonly Measurement[];
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one canvas shows, what it is asked to show next, and the least work
|
|
3
|
+
* between the two.
|
|
4
|
+
*
|
|
5
|
+
* The measurements are drawn over the model, not into it: a change of them
|
|
6
|
+
* alone replaces their own representations and leaves the model, its surface,
|
|
7
|
+
* its highlights and the camera as they are. Only another molecule, or another
|
|
8
|
+
* style for it, draws the scene again, and only another molecule frames the
|
|
9
|
+
* camera. Draws run one after another, so a measurement never lands on a model
|
|
10
|
+
* that is half built, and the last request asked is the one drawn.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { Molecule3DCamera } from '../core/camera.ts';
|
|
14
|
+
import type { Measurement } from '../core/measurement.ts';
|
|
15
|
+
import { sameMeasurements } from '../core/measurement.ts';
|
|
16
|
+
import type { Molecule3DFile, Molecule3DSettings } from '../core/settings.ts';
|
|
17
|
+
import { sameMolecule3DSettings } from '../core/settings.ts';
|
|
18
|
+
|
|
19
|
+
import type { SceneViewer } from './drawScene.ts';
|
|
20
|
+
import { drawScene } from './drawScene.ts';
|
|
21
|
+
|
|
22
|
+
/** What the canvas is asked to show. */
|
|
23
|
+
export interface SceneRequest {
|
|
24
|
+
/** What to draw, or `null` to empty the scene. */
|
|
25
|
+
molfile: Molecule3DFile | null;
|
|
26
|
+
/** How the model is drawn. */
|
|
27
|
+
settings: Molecule3DSettings;
|
|
28
|
+
/** What is drawn over it. */
|
|
29
|
+
measurements: readonly Measurement[];
|
|
30
|
+
/** How the camera meets a molecule it has not shown before. */
|
|
31
|
+
frameNewMolecule: 'front' | 'keep';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Keeps one viewer showing the last scene it was asked for. */
|
|
35
|
+
export class SceneDrawer {
|
|
36
|
+
/** The viewer drawn on. */
|
|
37
|
+
readonly viewer: SceneViewer;
|
|
38
|
+
readonly #takeLinkedCamera: () => Molecule3DCamera | null;
|
|
39
|
+
#asked: SceneRequest | null = null;
|
|
40
|
+
// The model on screen, or `null` when the next request must draw it again.
|
|
41
|
+
#drawn: Pick<SceneRequest, 'molfile' | 'settings'> | null = null;
|
|
42
|
+
// The measurements on screen, or `null` when the next request must draw them.
|
|
43
|
+
#measured: readonly Measurement[] | null = [];
|
|
44
|
+
// The molecule the camera was last framed on, so another one is told apart.
|
|
45
|
+
#framed: Molecule3DFile | null = null;
|
|
46
|
+
#queue: Promise<void> = Promise.resolve();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Start drawing on `viewer`, whose scene is empty.
|
|
50
|
+
* @param viewer - The viewer to draw on.
|
|
51
|
+
* @param takeLinkedCamera - Asked when a molecule is new: a camera to stand
|
|
52
|
+
* at instead of framing it, or `null`.
|
|
53
|
+
*/
|
|
54
|
+
constructor(
|
|
55
|
+
viewer: SceneViewer,
|
|
56
|
+
takeLinkedCamera: () => Molecule3DCamera | null,
|
|
57
|
+
) {
|
|
58
|
+
this.viewer = viewer;
|
|
59
|
+
this.#takeLinkedCamera = takeLinkedCamera;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Bring the canvas to `request`, once whatever was asked before is drawn.
|
|
64
|
+
* @param request - The scene to show; replaces any request still waiting.
|
|
65
|
+
* @returns Nothing; resolves once the canvas shows the last request asked,
|
|
66
|
+
* and rejects with what stopped it from being drawn.
|
|
67
|
+
*/
|
|
68
|
+
draw(request: SceneRequest): Promise<void> {
|
|
69
|
+
this.#asked = request;
|
|
70
|
+
const drawn = this.#queue.then(() => this.#catchUp());
|
|
71
|
+
this.#queue = drawn.catch(ignore);
|
|
72
|
+
return drawn;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async #catchUp(): Promise<void> {
|
|
76
|
+
const request = this.#asked;
|
|
77
|
+
if (request === null) return;
|
|
78
|
+
const drawn = this.#drawn;
|
|
79
|
+
if (
|
|
80
|
+
drawn !== null &&
|
|
81
|
+
sameFile(drawn.molfile, request.molfile) &&
|
|
82
|
+
sameMolecule3DSettings(drawn.settings, request.settings)
|
|
83
|
+
) {
|
|
84
|
+
await this.#measure(request);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
await this.#redraw(request);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The model stays: only the measurements over it can have changed.
|
|
91
|
+
async #measure(request: SceneRequest): Promise<void> {
|
|
92
|
+
const { molfile, measurements } = request;
|
|
93
|
+
const measured = this.#measured;
|
|
94
|
+
if (measured !== null && sameMeasurements(measured, measurements)) return;
|
|
95
|
+
// As for the model: a list that fails partway is drawn again next time.
|
|
96
|
+
this.#measured = null;
|
|
97
|
+
// An empty scene has nothing to measure; the list waits for a molecule.
|
|
98
|
+
if (molfile !== null) await this.viewer.showMeasurements(measurements);
|
|
99
|
+
this.#measured = measurements;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
async #redraw(request: SceneRequest): Promise<void> {
|
|
103
|
+
const { molfile, settings, measurements, frameNewMolecule } = request;
|
|
104
|
+
const isNew =
|
|
105
|
+
molfile !== null &&
|
|
106
|
+
(this.#framed === null || !sameFile(this.#framed, molfile));
|
|
107
|
+
this.#framed = molfile;
|
|
108
|
+
// A link's camera is spent on the first molecule framed; afterwards the
|
|
109
|
+
// camera is the reader's and a new molecule is framed as usual.
|
|
110
|
+
const linked = isNew ? this.#takeLinkedCamera() : null;
|
|
111
|
+
const frameCamera = isNew && linked === null ? frameNewMolecule : 'none';
|
|
112
|
+
// Kept only once drawn: a draw that fails is drawn again by the next
|
|
113
|
+
// request, whatever that one changes.
|
|
114
|
+
this.#drawn = null;
|
|
115
|
+
await drawScene(this.viewer, molfile, settings, measurements, frameCamera);
|
|
116
|
+
this.#drawn = { molfile, settings };
|
|
117
|
+
this.#measured = measurements;
|
|
118
|
+
if (linked !== null) await this.viewer.setCamera(linked);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function sameFile(
|
|
123
|
+
first: Molecule3DFile | null,
|
|
124
|
+
second: Molecule3DFile | null,
|
|
125
|
+
): boolean {
|
|
126
|
+
if (first === null || second === null) return first === second;
|
|
127
|
+
return first.format === second.format && first.data === second.data;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function ignore(): void {
|
|
131
|
+
// A failure reached the caller of `draw`; the next draw still runs.
|
|
132
|
+
}
|
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
* The draw is coalesced into one animation frame, so dragging a slider costs
|
|
6
6
|
* one rebuild rather than one per pixel, and the camera is framed only when the
|
|
7
7
|
* molecule is new — a restyle that snapped the view back would undo the
|
|
8
|
-
* reader's orientation.
|
|
8
|
+
* reader's orientation. What each draw rebuilds is the scene drawer's call: a
|
|
9
|
+
* change of the measurements alone redraws them and nothing else.
|
|
9
10
|
*/
|
|
10
11
|
|
|
11
12
|
import type { RefObject } from 'react';
|
|
12
13
|
import { useCallback, useEffect, useRef } from 'react';
|
|
13
14
|
|
|
14
|
-
import type { Molecule3DCamera } from '../core/camera.ts';
|
|
15
15
|
import type { Measurement } from '../core/measurement.ts';
|
|
16
16
|
import type { Molecule3DFile, Molecule3DSettings } from '../core/settings.ts';
|
|
17
17
|
|
|
18
|
-
import { drawScene } from './drawScene.ts';
|
|
19
18
|
import type { MoleculeViewer3DProps } from './moleculeViewer3DProps.ts';
|
|
19
|
+
import { SceneDrawer } from './sceneDrawer.ts';
|
|
20
20
|
import {
|
|
21
21
|
DEFAULT_CAMERA_SETTLE_DELAY,
|
|
22
22
|
useSharedCamera,
|
|
@@ -71,10 +71,7 @@ export function useMoleculeScene(options: MoleculeSceneOptions): MoleculeScene {
|
|
|
71
71
|
onFailureChange,
|
|
72
72
|
camera: cameraProps,
|
|
73
73
|
} = options;
|
|
74
|
-
const
|
|
75
|
-
molfile: Molecule3DFile;
|
|
76
|
-
viewer: Molecule3DViewer;
|
|
77
|
-
} | null>(null);
|
|
74
|
+
const drawerRef = useRef<SceneDrawer | null>(null);
|
|
78
75
|
const reportFailure = useRef(onFailureChange);
|
|
79
76
|
useEffect(() => {
|
|
80
77
|
reportFailure.current = onFailureChange;
|
|
@@ -92,31 +89,24 @@ export function useMoleculeScene(options: MoleculeSceneOptions): MoleculeScene {
|
|
|
92
89
|
useEffect(() => {
|
|
93
90
|
const viewer = viewerRef.current;
|
|
94
91
|
if (container === null || viewer === null) return;
|
|
92
|
+
// A new viewer starts from an empty scene, so it gets a drawer of its own.
|
|
93
|
+
if (drawerRef.current?.viewer !== viewer) {
|
|
94
|
+
drawerRef.current = new SceneDrawer(viewer, camera.takeLinkedCamera);
|
|
95
|
+
}
|
|
96
|
+
const drawer = drawerRef.current;
|
|
95
97
|
let cancelled = false;
|
|
96
98
|
const frame = requestAnimationFrame(() => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
// The link's camera is spent on the first molecule framed; afterwards the
|
|
103
|
-
// camera is the reader's and a new molecule is framed as usual.
|
|
104
|
-
const linked: Molecule3DCamera | null = isNew
|
|
105
|
-
? camera.takeLinkedCamera()
|
|
106
|
-
: null;
|
|
107
|
-
const frameCamera = isNew && linked === null ? frameNewMolecule : 'none';
|
|
108
|
-
void drawScene(viewer, molfile, settings, measurements, frameCamera)
|
|
109
|
-
.then(() => {
|
|
110
|
-
if (cancelled) return;
|
|
111
|
-
if (linked !== null) void viewer.setCamera(linked);
|
|
112
|
-
reportFailure.current(null);
|
|
113
|
-
})
|
|
114
|
-
.catch((error: unknown) => {
|
|
99
|
+
drawer.draw({ molfile, settings, measurements, frameNewMolecule }).then(
|
|
100
|
+
() => {
|
|
101
|
+
if (!cancelled) reportFailure.current(null);
|
|
102
|
+
},
|
|
103
|
+
(error: unknown) => {
|
|
115
104
|
if (cancelled) return;
|
|
116
105
|
reportFailure.current(
|
|
117
106
|
error instanceof Error ? error.message : String(error),
|
|
118
107
|
);
|
|
119
|
-
}
|
|
108
|
+
},
|
|
109
|
+
);
|
|
120
110
|
});
|
|
121
111
|
return () => {
|
|
122
112
|
cancelled = true;
|
|
@@ -37,9 +37,7 @@ export interface SharedCameraOptions {
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* What {@link useSharedCamera} answers. The same object on every render: the
|
|
40
|
-
* draw effect keys on it, and a fresh one would
|
|
41
|
-
* it again — which makes molstar frame the model afresh and loses the camera a
|
|
42
|
-
* link had just restored.
|
|
40
|
+
* draw effect keys on it, and a fresh one would run it again for nothing.
|
|
43
41
|
*/
|
|
44
42
|
export interface SharedCamera {
|
|
45
43
|
/**
|