react-cheminfo 0.39.0 → 0.40.0

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.
Files changed (104) hide show
  1. package/bin/check-deploy.mjs +4 -2
  2. package/lib/deploy/core/checkDeploy.d.ts +3 -1
  3. package/lib/deploy/core/checkDeploy.d.ts.map +1 -1
  4. package/lib/deploy/core/checkDeploy.js +8 -2
  5. package/lib/deploy/core/checkDeploy.js.map +1 -1
  6. package/lib/deploy/core/index.d.ts +1 -0
  7. package/lib/deploy/core/index.d.ts.map +1 -1
  8. package/lib/deploy/core/index.js +1 -0
  9. package/lib/deploy/core/index.js.map +1 -1
  10. package/lib/deploy/core/publishedImage.d.ts +30 -0
  11. package/lib/deploy/core/publishedImage.d.ts.map +1 -0
  12. package/lib/deploy/core/publishedImage.js +96 -0
  13. package/lib/deploy/core/publishedImage.js.map +1 -0
  14. package/lib/deploy/core/types.d.ts +1 -1
  15. package/lib/deploy/core/types.d.ts.map +1 -1
  16. package/lib/deploy/core/types.js.map +1 -1
  17. package/lib/molecule3d/ui/Molecule3DToolbar.d.ts +9 -7
  18. package/lib/molecule3d/ui/Molecule3DToolbar.d.ts.map +1 -1
  19. package/lib/molecule3d/ui/Molecule3DToolbar.js +13 -8
  20. package/lib/molecule3d/ui/Molecule3DToolbar.js.map +1 -1
  21. package/lib/molecule3d/ui/MoleculeCanvas3D.js +1 -1
  22. package/lib/molecule3d/ui/MoleculeCanvas3D.js.map +1 -1
  23. package/lib/molecule3d/ui/camera.d.ts +0 -11
  24. package/lib/molecule3d/ui/camera.d.ts.map +1 -1
  25. package/lib/molecule3d/ui/camera.js +6 -80
  26. package/lib/molecule3d/ui/camera.js.map +1 -1
  27. package/lib/molecule3d/ui/exportMoleculeImage.d.ts +6 -2
  28. package/lib/molecule3d/ui/exportMoleculeImage.d.ts.map +1 -1
  29. package/lib/molecule3d/ui/exportMoleculeImage.js.map +1 -1
  30. package/lib/molecule3d/ui/index.d.ts +9 -0
  31. package/lib/molecule3d/ui/index.d.ts.map +1 -1
  32. package/lib/molecule3d/ui/index.js +5 -0
  33. package/lib/molecule3d/ui/index.js.map +1 -1
  34. package/lib/molecule3d/ui/measurements.d.ts +22 -2
  35. package/lib/molecule3d/ui/measurements.d.ts.map +1 -1
  36. package/lib/molecule3d/ui/measurements.js +25 -3
  37. package/lib/molecule3d/ui/measurements.js.map +1 -1
  38. package/lib/molecule3d/ui/useImageExport.d.ts +2 -2
  39. package/lib/molecule3d/ui/useImageExport.d.ts.map +1 -1
  40. package/lib/molecule3d/ui/useImageExport.js.map +1 -1
  41. package/lib/molecule3d/ui/viewer.d.ts.map +1 -1
  42. package/lib/molecule3d/ui/viewer.js +16 -49
  43. package/lib/molecule3d/ui/viewer.js.map +1 -1
  44. package/lib/molstar/core/camera.d.ts +37 -0
  45. package/lib/molstar/core/camera.d.ts.map +1 -0
  46. package/lib/molstar/core/camera.js +49 -0
  47. package/lib/molstar/core/camera.js.map +1 -0
  48. package/lib/molstar/core/cameraPose.d.ts +54 -0
  49. package/lib/molstar/core/cameraPose.d.ts.map +1 -0
  50. package/lib/molstar/core/cameraPose.js +78 -0
  51. package/lib/molstar/core/cameraPose.js.map +1 -0
  52. package/lib/molstar/core/hover.d.ts +49 -0
  53. package/lib/molstar/core/hover.d.ts.map +1 -0
  54. package/lib/molstar/core/hover.js +91 -0
  55. package/lib/molstar/core/hover.js.map +1 -0
  56. package/lib/molstar/core/index.d.ts +7 -0
  57. package/lib/molstar/core/index.d.ts.map +1 -0
  58. package/lib/molstar/core/index.js +5 -0
  59. package/lib/molstar/core/index.js.map +1 -0
  60. package/lib/molstar/core/plugin.d.ts +80 -0
  61. package/lib/molstar/core/plugin.d.ts.map +1 -0
  62. package/lib/molstar/core/plugin.js +125 -0
  63. package/lib/molstar/core/plugin.js.map +1 -0
  64. package/lib/molstar.d.ts +18 -0
  65. package/lib/molstar.d.ts.map +1 -0
  66. package/lib/molstar.js +17 -0
  67. package/lib/molstar.js.map +1 -0
  68. package/lib/share/ui/SharePreview.d.ts.map +1 -1
  69. package/lib/share/ui/SharePreview.js +25 -0
  70. package/lib/share/ui/SharePreview.js.map +1 -1
  71. package/lib/share/ui/useShareRegionReports.d.ts.map +1 -1
  72. package/lib/share/ui/useShareRegionReports.js +41 -12
  73. package/lib/share/ui/useShareRegionReports.js.map +1 -1
  74. package/lib/structure/ui/ConformerTable.d.ts +8 -0
  75. package/lib/structure/ui/ConformerTable.d.ts.map +1 -1
  76. package/lib/structure/ui/ConformerTable.js +24 -4
  77. package/lib/structure/ui/ConformerTable.js.map +1 -1
  78. package/package.json +2 -1
  79. package/src/deploy/core/checkDeploy.ts +14 -2
  80. package/src/deploy/core/index.ts +5 -0
  81. package/src/deploy/core/publishedImage.ts +110 -0
  82. package/src/deploy/core/types.ts +3 -1
  83. package/src/molecule3d/ui/Molecule3DToolbar.tsx +23 -16
  84. package/src/molecule3d/ui/MoleculeCanvas3D.tsx +1 -1
  85. package/src/molecule3d/ui/camera.ts +18 -93
  86. package/src/molecule3d/ui/exportMoleculeImage.ts +6 -2
  87. package/src/molecule3d/ui/index.ts +12 -0
  88. package/src/molecule3d/ui/measurements.ts +42 -3
  89. package/src/molecule3d/ui/useImageExport.ts +2 -2
  90. package/src/molecule3d/ui/viewer.ts +21 -51
  91. package/src/molstar/core/camera.ts +61 -0
  92. package/src/molstar/core/cameraPose.ts +126 -0
  93. package/src/molstar/core/hover.ts +109 -0
  94. package/src/molstar/core/index.ts +13 -0
  95. package/src/molstar/core/plugin.ts +159 -0
  96. package/src/molstar.ts +22 -0
  97. package/src/share/ui/SharePreview.tsx +31 -0
  98. package/src/share/ui/useShareRegionReports.ts +39 -15
  99. package/src/structure/ui/ConformerTable.tsx +38 -4
  100. package/lib/molecule3d/ui/viewerSpec.d.ts +0 -17
  101. package/lib/molecule3d/ui/viewerSpec.d.ts.map +0 -1
  102. package/lib/molecule3d/ui/viewerSpec.js +0 -34
  103. package/lib/molecule3d/ui/viewerSpec.js.map +0 -1
  104. package/src/molecule3d/ui/viewerSpec.ts +0 -38
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Lifecycle of one headless molstar canvas: created now, disposed whenever,
3
+ * every call queued behind initialisation.
4
+ *
5
+ * The constructor is **synchronous** on purpose. React 19 runs an effect, its
6
+ * cleanup and the effect again on every mount in development, so an `await`ed
7
+ * constructor hands the cleanup nothing to dispose and leaks a WebGL context
8
+ * per mount — browsers drop the oldest after about sixteen, and the viewer
9
+ * silently goes blank. Returning the handle immediately means `dispose()` can
10
+ * always be called, even before initialisation has finished; the work is queued
11
+ * behind `ready`.
12
+ *
13
+ * molstar's own UI is never mounted: every control on our sites is ours.
14
+ */
15
+
16
+ import { PluginViewModel } from 'molstar/lib/extensions/plugin/view-model.js';
17
+ import type { PluginContext } from 'molstar/lib/mol-plugin/context.js';
18
+ import type { PluginSpec } from 'molstar/lib/mol-plugin/spec.js';
19
+ // Lowercased on import: it is a factory, not a constructor.
20
+ import { DefaultPluginSpec as defaultPluginSpec } from 'molstar/lib/mol-plugin/spec.js';
21
+ import { Color } from 'molstar/lib/mol-util/color/color.js';
22
+
23
+ /** Settings fixed for the life of a plugin. */
24
+ export interface MolstarPluginOptions {
25
+ /**
26
+ * Scene background, as `#rrggbb`. A WebGL clear colour, so it cannot be a CSS
27
+ * custom property.
28
+ * @default '#ffffff'
29
+ */
30
+ background?: string;
31
+ /**
32
+ * How long molstar animates a reframe it decided on itself; 0 jumps.
33
+ *
34
+ * Replacing a scene commits several times — the old drawing is deleted, the
35
+ * new one added — and molstar glides the camera on each, so the model appears
36
+ * to drift into place. Reframing is right; animating it between two unrelated
37
+ * scenes is not.
38
+ * @default molstar's own 250 ms
39
+ */
40
+ cameraResetDurationMilliseconds?: number;
41
+ /**
42
+ * The last word on the spec, applied over everything above: a site that needs
43
+ * a behaviour dropped, a marking colour or a renderer setting of its own
44
+ * passes it here rather than mounting its own view model.
45
+ */
46
+ spec?: (spec: PluginSpec) => PluginSpec;
47
+ }
48
+
49
+ /** One molstar canvas, and the queue everything drawn on it goes through. */
50
+ export class MolstarPlugin {
51
+ readonly #model: PluginViewModel;
52
+ #disposed = false;
53
+
54
+ /** Resolves once the canvas exists; every call awaits it internally. */
55
+ readonly ready: Promise<void>;
56
+
57
+ /**
58
+ * Mount a canvas in `container` and start initialising it.
59
+ * @param container - An element with `position: relative`; molstar inserts
60
+ * its own canvas into it.
61
+ * @param options - See {@link MolstarPluginOptions}.
62
+ */
63
+ constructor(container: HTMLElement, options: MolstarPluginOptions = {}) {
64
+ const {
65
+ background = '#ffffff', // tokens-ok: a WebGL clear colour
66
+ cameraResetDurationMilliseconds,
67
+ spec: refine,
68
+ } = options;
69
+ const base = defaultPluginSpec();
70
+ const spec: PluginSpec = {
71
+ ...base,
72
+ canvas3d: {
73
+ ...base.canvas3d,
74
+ renderer: { backgroundColor: Color.fromHexStyle(background) },
75
+ // A scene is read from its own shape, never from the world axes.
76
+ camera: { helper: { axes: { name: 'off', params: {} } } },
77
+ ...(cameraResetDurationMilliseconds === undefined
78
+ ? {}
79
+ : { cameraResetDurationMs: cameraResetDurationMilliseconds }),
80
+ },
81
+ };
82
+ this.#model = new PluginViewModel({
83
+ spec: refine === undefined ? spec : refine(spec),
84
+ });
85
+ this.#model.mount(container);
86
+ this.ready = this.#model.initialized;
87
+ }
88
+
89
+ /** Whether {@link dispose} has been called. */
90
+ get disposed(): boolean {
91
+ return this.#disposed;
92
+ }
93
+
94
+ /**
95
+ * Wait for initialisation, then run `action` on the plugin.
96
+ * @param action - What to do with the molstar context.
97
+ * @returns What `action` returned, or `undefined` once the plugin has been
98
+ * disposed — before the call or while `action` was still running. An
99
+ * initialisation failure, and anything `action` throws while the plugin is
100
+ * alive, still reach the caller.
101
+ */
102
+ async run<Result>(
103
+ action: (plugin: PluginContext) => Result | Promise<Result>,
104
+ ): Promise<Result | undefined> {
105
+ if (this.#disposed) return undefined;
106
+ await this.ready;
107
+ if (this.#disposed) return undefined;
108
+ try {
109
+ return await action(this.#model.plugin);
110
+ } catch (error) {
111
+ if (this.#disposed) return undefined;
112
+ throw error;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Start a subscription once the plugin exists.
118
+ * @param start - Subscribes, and returns its own unsubscribe function.
119
+ * @returns A function that stops the subscription, or stops it from ever
120
+ * starting; safe to call at any time.
121
+ */
122
+ subscribe(start: (plugin: PluginContext) => () => void): () => void {
123
+ let stop: (() => void) | null = null;
124
+ let cancelled = false;
125
+ void this.run((plugin) => {
126
+ if (cancelled) return;
127
+ stop = start(plugin);
128
+ });
129
+ return () => {
130
+ cancelled = true;
131
+ stop?.();
132
+ stop = null;
133
+ };
134
+ }
135
+
136
+ /** Re-read the container's size. Call from a `ResizeObserver`. */
137
+ handleResize(): void {
138
+ if (this.#disposed) return;
139
+ this.#model.plugin.handleResize();
140
+ }
141
+
142
+ /**
143
+ * Tear the canvas down and release its WebGL context. Idempotent, and safe to
144
+ * call before initialisation has finished.
145
+ */
146
+ dispose(): void {
147
+ if (this.#disposed) return;
148
+ this.#disposed = true;
149
+ // `mount` creates the canvas synchronously, so the context exists even when
150
+ // initialisation went on to fail; releasing it is what stops the browser
151
+ // dropping an older viewer's. A rejected `ready` must not escape here
152
+ // either — nobody is left to handle it.
153
+ void this.ready
154
+ .catch(() => undefined)
155
+ .then(() => {
156
+ this.#model.plugin.dispose();
157
+ });
158
+ }
159
+ }
package/src/molstar.ts ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The molstar layer under the 3D views: the plugin lifecycle, the camera, the
3
+ * hover labels, the measurements and the picture of a scene.
4
+ *
5
+ * Three of our sites mount a headless molstar canvas — the molecule viewer
6
+ * here, lcao's orbitals and symmetry's crystals — and each of them had its own
7
+ * copy of the lifecycle, the spec and the spin. This is that one copy; what
8
+ * stays in a site is the scene it draws.
9
+ *
10
+ * **Importing this pulls molstar in statically.** A site that only wants
11
+ * `<MoleculeViewer3D>` imports `react-cheminfo/molecule3d`, whose canvas is
12
+ * lazy.
13
+ */
14
+
15
+ export * from './molstar/core/index.ts';
16
+ export { captureScene } from './molecule3d/ui/captureScene.ts';
17
+ export type { MoleculeStructureSource } from './molecule3d/ui/measurements.ts';
18
+ export {
19
+ atomReferenceOf,
20
+ clearMeasurements,
21
+ renderMeasurements,
22
+ } from './molecule3d/ui/measurements.ts';
@@ -22,6 +22,12 @@ import { SharePreviewDevices } from './SharePreviewDevices.tsx';
22
22
  /** Room the window's own bar takes, which the page is not scaled into. */
23
23
  const CHROME_HEIGHT = 26;
24
24
 
25
+ /** How often the framed page is asked again while it has answered nothing. */
26
+ const ASK_INTERVAL = 300;
27
+
28
+ /** How many times, so a page with nothing to report is left alone. */
29
+ const ASK_LIMIT = 10;
30
+
25
31
  export interface SharePreviewProps {
26
32
  /** The address the frame loads — the link as it stands. */
27
33
  url: string;
@@ -97,6 +103,31 @@ export function SharePreview(props: SharePreviewProps): ReactElement {
97
103
  mark.current?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
98
104
  }, [highlight?.part]);
99
105
 
106
+ // The frame's own load says the document is there, never that the page it
107
+ // builds is listening: a React tree mounts in a task of its own, after it.
108
+ // So the question is repeated until it is answered — there is no event on
109
+ // this side to wait for, and a page that answers nothing is a page with no
110
+ // parts to point at, which costs ten messages and stops.
111
+ useEffect(() => {
112
+ if (regions.length > 0) return undefined;
113
+ let asked = 0;
114
+ const timer = setInterval(() => {
115
+ asked += 1;
116
+ if (asked > ASK_LIMIT) {
117
+ clearInterval(timer);
118
+ return;
119
+ }
120
+ frame.current?.contentWindow?.postMessage(
121
+ { type: SHARE_REGIONS_REQUEST },
122
+ '*',
123
+ );
124
+ }, ASK_INTERVAL);
125
+
126
+ return () => {
127
+ clearInterval(timer);
128
+ };
129
+ }, [regions, src]);
130
+
100
131
  return (
101
132
  <section className="share-preview" aria-label={t('share.preview')}>
102
133
  <header className="share-preview__header">
@@ -33,25 +33,47 @@ export function useShareRegionReports(hidden: ReadonlySet<string>): boolean {
33
33
  useEffect(() => {
34
34
  if (!marking) return undefined;
35
35
  const host = globalThis.parent;
36
+ let scheduled = 0;
37
+ let reported = '';
36
38
 
37
39
  function report(): void {
38
- host.postMessage(
39
- { type: SHARE_REGIONS_MESSAGE, regions: measureRegions() },
40
- '*',
41
- );
40
+ scheduled = 0;
41
+ const regions = measureRegions();
42
+ // A page that is drawing — a structure, a result, a chart — mutates many
43
+ // times a second while its boxes stay where they are, and every message
44
+ // sent re-renders the dialog on the other side. Only a move is news.
45
+ const signature = JSON.stringify(regions);
46
+ if (signature === reported) return;
47
+ reported = signature;
48
+ host.postMessage({ type: SHARE_REGIONS_MESSAGE, regions }, '*');
49
+ }
50
+
51
+ // A search that returns, a structure that draws and a font that lands all
52
+ // move the boxes within a frame of each other, so the page is measured
53
+ // once after them rather than once per notification.
54
+ function schedule(): void {
55
+ if (scheduled === 0) scheduled = requestAnimationFrame(report);
42
56
  }
43
57
 
44
58
  // A chart, a web font or a structure drawn after mount all move the boxes,
45
- // so the page is measured again whenever anything in it resizes rather
46
- // than once, on a deadline it would lose.
47
- const observer = new ResizeObserver(report);
48
- observer.observe(document.documentElement);
49
- globalThis.addEventListener('resize', report);
59
+ // so the page is measured again whenever anything in it changes rather
60
+ // than once, on a deadline it would lose. Watching its size is not enough:
61
+ // a page laid out to the height of the viewport keeps that height while a
62
+ // result appears inside a column of it, and the part nobody measured is
63
+ // the one the reader is pointing at.
64
+ const resizes = new ResizeObserver(schedule);
65
+ resizes.observe(document.documentElement);
66
+ resizes.observe(document.body);
67
+ const mutations = new MutationObserver(schedule);
68
+ mutations.observe(document.body, { childList: true, subtree: true });
69
+ globalThis.addEventListener('resize', schedule);
50
70
  report();
51
71
 
52
72
  return () => {
53
- observer.disconnect();
54
- globalThis.removeEventListener('resize', report);
73
+ if (scheduled !== 0) cancelAnimationFrame(scheduled);
74
+ resizes.disconnect();
75
+ mutations.disconnect();
76
+ globalThis.removeEventListener('resize', schedule);
55
77
  };
56
78
  }, [marking, hidden]);
57
79
 
@@ -71,12 +93,14 @@ function measureRegions(): ShareRegion[] {
71
93
  range.selectNodeContents(marker);
72
94
  const box = range.getBoundingClientRect();
73
95
  if (box.width === 0 || box.height === 0) continue;
96
+ // Rounded, so a layout that settles half a pixel to the left is not
97
+ // reported as a part that moved.
74
98
  regions.push({
75
99
  part,
76
- x: box.x + globalThis.scrollX,
77
- y: box.y + globalThis.scrollY,
78
- width: box.width,
79
- height: box.height,
100
+ x: Math.round(box.x + globalThis.scrollX),
101
+ y: Math.round(box.y + globalThis.scrollY),
102
+ width: Math.round(box.width),
103
+ height: Math.round(box.height),
80
104
  });
81
105
  }
82
106
 
@@ -78,6 +78,14 @@ export interface ConformerTableProps {
78
78
  * @default undefined — every column keeps its own
79
79
  */
80
80
  columnLabels?: Partial<Record<ConformerColumn, string>>;
81
+ /**
82
+ * Whether the energies on screen are expected to be replaced — a force
83
+ * field's numbers while a better method is still working on the set. They
84
+ * are then drawn muted, so a reader can tell at a glance which of the two
85
+ * rankings they are looking at.
86
+ * @default false
87
+ */
88
+ provisional?: boolean;
81
89
  }
82
90
 
83
91
  /**
@@ -102,6 +110,7 @@ export function ConformerTable(
102
110
  label = 'Conformers, most stable first',
103
111
  rowName = String,
104
112
  columnLabels,
113
+ provisional = false,
105
114
  } = props;
106
115
 
107
116
  const bodyRef = useRef<HTMLTableSectionElement>(null);
@@ -208,7 +217,7 @@ export function ConformerTable(
208
217
  <ClickToCopy
209
218
  key={column}
210
219
  as="td"
211
- style={cellStyle(column)}
220
+ style={cellStyle(column, provisional)}
212
221
  value={content}
213
222
  label={COPY_LABELS[column]}
214
223
  testId={CELL_TEST_IDS[column]}
@@ -218,7 +227,7 @@ export function ConformerTable(
218
227
  ) : (
219
228
  <td
220
229
  key={column}
221
- style={cellStyle(column)}
230
+ style={cellStyle(column, provisional)}
222
231
  data-testid={CELL_TEST_IDS[column]}
223
232
  >
224
233
  {content}
@@ -360,8 +369,24 @@ function headerStyle(column: ConformerColumn): CSSProperties | undefined {
360
369
  return NUMERIC_CONFORMER_COLUMNS.has(column) ? numericStyle : undefined;
361
370
  }
362
371
 
363
- function cellStyle(column: ConformerColumn): CSSProperties | undefined {
364
- return NUMERIC_CONFORMER_COLUMNS.has(column) ? numericStyle : undefined;
372
+ /**
373
+ * A cell's own style: numbers are right-aligned and tabular, and every cell a
374
+ * better method will restate is muted while it works. The rank is not one of
375
+ * them — it names the row rather than measuring it, and it is what a reader
376
+ * follows as the order changes under them.
377
+ * @param column - The column the cell is in.
378
+ * @param provisional - Whether the energies are still expected to change.
379
+ * @returns The cell's inline style, or `undefined` when it needs none.
380
+ */
381
+ function cellStyle(
382
+ column: ConformerColumn,
383
+ provisional: boolean,
384
+ ): CSSProperties | undefined {
385
+ const numeric = NUMERIC_CONFORMER_COLUMNS.has(column);
386
+ if (!provisional || column === 'id') {
387
+ return numeric ? numericStyle : undefined;
388
+ }
389
+ return numeric ? provisionalNumericStyle : provisionalStyle;
365
390
  }
366
391
 
367
392
  const tableStyle = { width: '100%' } as const satisfies CSSProperties;
@@ -371,6 +396,15 @@ const numericStyle = {
371
396
  fontVariantNumeric: 'tabular-nums',
372
397
  } as const satisfies CSSProperties;
373
398
 
399
+ const provisionalStyle = {
400
+ color: 'var(--text-muted)',
401
+ } as const satisfies CSSProperties;
402
+
403
+ const provisionalNumericStyle = {
404
+ ...numericStyle,
405
+ ...provisionalStyle,
406
+ } as const satisfies CSSProperties;
407
+
374
408
  /**
375
409
  * The selected row is tinted with the site's own accent, so the table belongs
376
410
  * to whichever site draws it; a row is a pointer only where a click does
@@ -1,17 +0,0 @@
1
- /**
2
- * How the molecule viewer configures molstar: the plugin spec it mounts with.
3
- *
4
- * molstar's own UI is not mounted — every control is the component's — and the
5
- * axes helper is off, since a molecule is read from its own shape rather than
6
- * from the world axes.
7
- */
8
- import { PluginViewModel } from 'molstar/lib/extensions/plugin/view-model.js';
9
- /**
10
- * Build a view model for one canvas and mount it.
11
- * @param container - A positioned element; molstar inserts its canvas into it.
12
- * @param background - Scene background as `#rrggbb`; a WebGL clear colour, so
13
- * it cannot be a CSS custom property.
14
- * @returns The mounted view model, still initialising.
15
- */
16
- export declare function mountMolecule3DPlugin(container: HTMLElement, background: string): PluginViewModel;
17
- //# sourceMappingURL=viewerSpec.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"viewerSpec.d.ts","sourceRoot":"","sources":["../../../src/molecule3d/ui/viewerSpec.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAK9E;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,WAAW,EACtB,UAAU,EAAE,MAAM,GACjB,eAAe,CAcjB"}
@@ -1,34 +0,0 @@
1
- /**
2
- * How the molecule viewer configures molstar: the plugin spec it mounts with.
3
- *
4
- * molstar's own UI is not mounted — every control is the component's — and the
5
- * axes helper is off, since a molecule is read from its own shape rather than
6
- * from the world axes.
7
- */
8
- import { PluginViewModel } from 'molstar/lib/extensions/plugin/view-model.js';
9
- // Lowercased on import: it is a factory, not a constructor.
10
- import { DefaultPluginSpec as defaultPluginSpec } from 'molstar/lib/mol-plugin/spec.js';
11
- import { Color } from 'molstar/lib/mol-util/color/color.js';
12
- /**
13
- * Build a view model for one canvas and mount it.
14
- * @param container - A positioned element; molstar inserts its canvas into it.
15
- * @param background - Scene background as `#rrggbb`; a WebGL clear colour, so
16
- * it cannot be a CSS custom property.
17
- * @returns The mounted view model, still initialising.
18
- */
19
- export function mountMolecule3DPlugin(container, background) {
20
- const spec = defaultPluginSpec();
21
- const model = new PluginViewModel({
22
- spec: {
23
- ...spec,
24
- canvas3d: {
25
- ...spec.canvas3d,
26
- renderer: { backgroundColor: Color.fromHexStyle(background) },
27
- camera: { helper: { axes: { name: 'off', params: {} } } },
28
- },
29
- },
30
- });
31
- model.mount(container);
32
- return model;
33
- }
34
- //# sourceMappingURL=viewerSpec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"viewerSpec.js","sourceRoot":"","sources":["../../../src/molecule3d/ui/viewerSpec.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,4DAA4D;AAC5D,OAAO,EAAE,iBAAiB,IAAI,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACxF,OAAO,EAAE,KAAK,EAAE,MAAM,qCAAqC,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,SAAsB,EACtB,UAAkB;IAElB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC;QAChC,IAAI,EAAE;YACJ,GAAG,IAAI;YACP,QAAQ,EAAE;gBACR,GAAG,IAAI,CAAC,QAAQ;gBAChB,QAAQ,EAAE,EAAE,eAAe,EAAE,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE;gBAC7D,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE;aAC1D;SACF;KACF,CAAC,CAAC;IACH,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACvB,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * How the molecule viewer configures molstar: the plugin spec it mounts with.
3
- *
4
- * molstar's own UI is not mounted — every control is the component's — and the
5
- * axes helper is off, since a molecule is read from its own shape rather than
6
- * from the world axes.
7
- */
8
-
9
- import { PluginViewModel } from 'molstar/lib/extensions/plugin/view-model.js';
10
- // Lowercased on import: it is a factory, not a constructor.
11
- import { DefaultPluginSpec as defaultPluginSpec } from 'molstar/lib/mol-plugin/spec.js';
12
- import { Color } from 'molstar/lib/mol-util/color/color.js';
13
-
14
- /**
15
- * Build a view model for one canvas and mount it.
16
- * @param container - A positioned element; molstar inserts its canvas into it.
17
- * @param background - Scene background as `#rrggbb`; a WebGL clear colour, so
18
- * it cannot be a CSS custom property.
19
- * @returns The mounted view model, still initialising.
20
- */
21
- export function mountMolecule3DPlugin(
22
- container: HTMLElement,
23
- background: string,
24
- ): PluginViewModel {
25
- const spec = defaultPluginSpec();
26
- const model = new PluginViewModel({
27
- spec: {
28
- ...spec,
29
- canvas3d: {
30
- ...spec.canvas3d,
31
- renderer: { backgroundColor: Color.fromHexStyle(background) },
32
- camera: { helper: { axes: { name: 'off', params: {} } } },
33
- },
34
- },
35
- });
36
- model.mount(container);
37
- return model;
38
- }