matterviz 0.1.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.
- package/dist/BohrAtom.svelte +105 -0
- package/dist/BohrAtom.svelte.d.ts +21 -0
- package/dist/ControlPanel.svelte +158 -0
- package/dist/ControlPanel.svelte.d.ts +18 -0
- package/dist/Icon.svelte +23 -0
- package/dist/Icon.svelte.d.ts +8 -0
- package/dist/InfoCard.svelte +79 -0
- package/dist/InfoCard.svelte.d.ts +23 -0
- package/dist/Nucleus.svelte +64 -0
- package/dist/Nucleus.svelte.d.ts +16 -0
- package/dist/Spinner.svelte +44 -0
- package/dist/Spinner.svelte.d.ts +7 -0
- package/dist/api.d.ts +6 -0
- package/dist/api.js +30 -0
- package/dist/colors/alloy-colors.json +111 -0
- package/dist/colors/dark-mode-colors.json +111 -0
- package/dist/colors/index.d.ts +26 -0
- package/dist/colors/index.js +72 -0
- package/dist/colors/jmol-colors.json +111 -0
- package/dist/colors/muted-colors.json +111 -0
- package/dist/colors/pastel-colors.json +111 -0
- package/dist/colors/vesta-colors.json +111 -0
- package/dist/composition/BarChart.svelte +260 -0
- package/dist/composition/BarChart.svelte.d.ts +33 -0
- package/dist/composition/BubbleChart.svelte +166 -0
- package/dist/composition/BubbleChart.svelte.d.ts +30 -0
- package/dist/composition/Composition.svelte +73 -0
- package/dist/composition/Composition.svelte.d.ts +27 -0
- package/dist/composition/PieChart.svelte +236 -0
- package/dist/composition/PieChart.svelte.d.ts +36 -0
- package/dist/composition/index.d.ts +5 -0
- package/dist/composition/index.js +5 -0
- package/dist/composition/parse.d.ts +14 -0
- package/dist/composition/parse.js +307 -0
- package/dist/element/ElementHeading.svelte +21 -0
- package/dist/element/ElementHeading.svelte.d.ts +8 -0
- package/dist/element/ElementPhoto.svelte +56 -0
- package/dist/element/ElementPhoto.svelte.d.ts +9 -0
- package/dist/element/ElementStats.svelte +73 -0
- package/dist/element/ElementStats.svelte.d.ts +8 -0
- package/dist/element/ElementTile.svelte +449 -0
- package/dist/element/ElementTile.svelte.d.ts +25 -0
- package/dist/element/data.d.ts +4958 -0
- package/dist/element/data.js +5628 -0
- package/dist/element/index.d.ts +4 -0
- package/dist/element/index.js +4 -0
- package/dist/icons.d.ts +435 -0
- package/dist/icons.js +435 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +43 -0
- package/dist/io/decompress.d.ts +16 -0
- package/dist/io/decompress.js +78 -0
- package/dist/io/export.d.ts +9 -0
- package/dist/io/export.js +205 -0
- package/dist/io/parse.d.ts +53 -0
- package/dist/io/parse.js +747 -0
- package/dist/labels.d.ts +31 -0
- package/dist/labels.js +209 -0
- package/dist/material/MaterialCard.svelte +135 -0
- package/dist/material/MaterialCard.svelte.d.ts +10 -0
- package/dist/material/SymmetryCard.svelte +23 -0
- package/dist/material/SymmetryCard.svelte.d.ts +9 -0
- package/dist/material/index.d.ts +2 -0
- package/dist/material/index.js +2 -0
- package/dist/math.d.ts +24 -0
- package/dist/math.js +216 -0
- package/dist/periodic-table/PeriodicTable.svelte +284 -0
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +50 -0
- package/dist/periodic-table/PropertySelect.svelte +20 -0
- package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
- package/dist/periodic-table/TableInset.svelte +18 -0
- package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
- package/dist/periodic-table/index.d.ts +9 -0
- package/dist/periodic-table/index.js +3 -0
- package/dist/plot/ColorBar.svelte +414 -0
- package/dist/plot/ColorBar.svelte.d.ts +22 -0
- package/dist/plot/ColorScaleSelect.svelte +31 -0
- package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
- package/dist/plot/ElementScatter.svelte +38 -0
- package/dist/plot/ElementScatter.svelte.d.ts +14 -0
- package/dist/plot/Line.svelte +42 -0
- package/dist/plot/Line.svelte.d.ts +15 -0
- package/dist/plot/PlotLegend.svelte +206 -0
- package/dist/plot/PlotLegend.svelte.d.ts +18 -0
- package/dist/plot/ScatterPlot.svelte +1753 -0
- package/dist/plot/ScatterPlot.svelte.d.ts +114 -0
- package/dist/plot/ScatterPlotControls.svelte +505 -0
- package/dist/plot/ScatterPlotControls.svelte.d.ts +33 -0
- package/dist/plot/ScatterPoint.svelte +72 -0
- package/dist/plot/ScatterPoint.svelte.d.ts +17 -0
- package/dist/plot/index.d.ts +168 -0
- package/dist/plot/index.js +46 -0
- package/dist/state.svelte.d.ts +12 -0
- package/dist/state.svelte.js +11 -0
- package/dist/structure/Bond.svelte +68 -0
- package/dist/structure/Bond.svelte.d.ts +13 -0
- package/dist/structure/Lattice.svelte +115 -0
- package/dist/structure/Lattice.svelte.d.ts +15 -0
- package/dist/structure/Structure.svelte +298 -0
- package/dist/structure/Structure.svelte.d.ts +28 -0
- package/dist/structure/StructureCard.svelte +26 -0
- package/dist/structure/StructureCard.svelte.d.ts +9 -0
- package/dist/structure/StructureControls.svelte +383 -0
- package/dist/structure/StructureControls.svelte.d.ts +23 -0
- package/dist/structure/StructureLegend.svelte +130 -0
- package/dist/structure/StructureLegend.svelte.d.ts +17 -0
- package/dist/structure/StructureScene.svelte +331 -0
- package/dist/structure/StructureScene.svelte.d.ts +47 -0
- package/dist/structure/bonding.d.ts +16 -0
- package/dist/structure/bonding.js +150 -0
- package/dist/structure/index.d.ts +98 -0
- package/dist/structure/index.js +114 -0
- package/dist/structure/pbc.d.ts +6 -0
- package/dist/structure/pbc.js +72 -0
- package/dist/trajectory/Sidebar.svelte +412 -0
- package/dist/trajectory/Sidebar.svelte.d.ts +14 -0
- package/dist/trajectory/Trajectory.svelte +1084 -0
- package/dist/trajectory/Trajectory.svelte.d.ts +49 -0
- package/dist/trajectory/TrajectoryError.svelte +120 -0
- package/dist/trajectory/TrajectoryError.svelte.d.ts +12 -0
- package/dist/trajectory/extract.d.ts +5 -0
- package/dist/trajectory/extract.js +157 -0
- package/dist/trajectory/index.d.ts +16 -0
- package/dist/trajectory/index.js +49 -0
- package/dist/trajectory/parse.d.ts +13 -0
- package/dist/trajectory/parse.js +1093 -0
- package/dist/trajectory/plotting.d.ts +12 -0
- package/dist/trajectory/plotting.js +148 -0
- package/license +21 -0
- package/package.json +131 -0
- package/readme.md +95 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
<script lang="ts">import { ControlPanel } from '..';
|
|
2
|
+
import { element_color_schemes } from '../colors';
|
|
3
|
+
import * as exports from '../io/export';
|
|
4
|
+
import Select from 'svelte-multiselect';
|
|
5
|
+
import { Tooltip } from 'svelte-zoo';
|
|
6
|
+
let { controls_open = $bindable(false), scene_props = $bindable({}), lattice_props = $bindable({}), show_image_atoms = $bindable(true), show_site_labels = $bindable(false), show_full_controls = $bindable(false), background_color = $bindable(`#ffffff`), background_opacity = $bindable(0.1), color_scheme = $bindable(`Vesta`), structure = undefined, wrapper = undefined, png_dpi = $bindable(150), save_json_btn_text = `⬇ Save as JSON`, save_png_btn_text = `✎ Save as PNG`, save_xyz_btn_text = `📄 Save as XYZ`, } = $props();
|
|
7
|
+
// Color scheme selection state
|
|
8
|
+
let color_scheme_selected = $state([color_scheme]);
|
|
9
|
+
$effect(() => {
|
|
10
|
+
if (color_scheme_selected.length > 0) {
|
|
11
|
+
color_scheme = color_scheme_selected[0];
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
// Helper function to get example set of colors from an element color scheme
|
|
15
|
+
function get_representative_colors(scheme_name) {
|
|
16
|
+
const scheme = element_color_schemes[scheme_name];
|
|
17
|
+
if (!scheme)
|
|
18
|
+
return [];
|
|
19
|
+
// Get colors for common elements: H, C, N, O, Fe, Ca, Si, Al
|
|
20
|
+
const sample_elements = [`H`, `C`, `N`, `O`, `Fe`, `Ca`, `Si`, `Al`];
|
|
21
|
+
return sample_elements
|
|
22
|
+
.slice(0, 4) // Take first 4
|
|
23
|
+
.map((el) => scheme[el] || scheme.H || `#cccccc`)
|
|
24
|
+
.filter(Boolean);
|
|
25
|
+
}
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<ControlPanel bind:controls_open>
|
|
29
|
+
{#snippet controls_content()}
|
|
30
|
+
<!-- Visibility Controls -->
|
|
31
|
+
<div style="display: flex; align-items: center; gap: 4pt; flex-wrap: wrap;">
|
|
32
|
+
Show <label>
|
|
33
|
+
<input type="checkbox" bind:checked={scene_props.show_atoms} />
|
|
34
|
+
atoms
|
|
35
|
+
</label>
|
|
36
|
+
<label>
|
|
37
|
+
<input type="checkbox" bind:checked={scene_props.show_bonds} />
|
|
38
|
+
bonds
|
|
39
|
+
</label>
|
|
40
|
+
<label>
|
|
41
|
+
<input type="checkbox" bind:checked={show_image_atoms} />
|
|
42
|
+
image atoms
|
|
43
|
+
</label>
|
|
44
|
+
<label>
|
|
45
|
+
<input type="checkbox" bind:checked={show_site_labels} />
|
|
46
|
+
site labels
|
|
47
|
+
</label>
|
|
48
|
+
<label>
|
|
49
|
+
<input type="checkbox" bind:checked={show_full_controls} />
|
|
50
|
+
full controls
|
|
51
|
+
</label>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<hr />
|
|
55
|
+
|
|
56
|
+
<!-- Atom Controls -->
|
|
57
|
+
<h4 class="section-heading">Atoms</h4>
|
|
58
|
+
<label class="slider-control">
|
|
59
|
+
Radius <small>(Å)</small>
|
|
60
|
+
<input
|
|
61
|
+
type="number"
|
|
62
|
+
min="0.2"
|
|
63
|
+
max={2}
|
|
64
|
+
step={0.05}
|
|
65
|
+
bind:value={scene_props.atom_radius}
|
|
66
|
+
/>
|
|
67
|
+
<input
|
|
68
|
+
type="range"
|
|
69
|
+
min="0.2"
|
|
70
|
+
max={2}
|
|
71
|
+
step={0.05}
|
|
72
|
+
bind:value={scene_props.atom_radius}
|
|
73
|
+
/>
|
|
74
|
+
</label>
|
|
75
|
+
<label>
|
|
76
|
+
<input type="checkbox" bind:checked={scene_props.same_size_atoms} />
|
|
77
|
+
<span>
|
|
78
|
+
Scale according to atomic radii
|
|
79
|
+
<small> (if false, all atoms same size)</small>
|
|
80
|
+
</span>
|
|
81
|
+
</label>
|
|
82
|
+
<label style="align-items: flex-start;">
|
|
83
|
+
Color scheme
|
|
84
|
+
<Select
|
|
85
|
+
options={Object.keys(element_color_schemes)}
|
|
86
|
+
maxSelect={1}
|
|
87
|
+
minSelect={1}
|
|
88
|
+
bind:selected={color_scheme_selected}
|
|
89
|
+
liOptionStyle="padding: 3pt 6pt;"
|
|
90
|
+
style="width: 10em; border: none;"
|
|
91
|
+
>
|
|
92
|
+
{#snippet children({ option })}
|
|
93
|
+
{@const style = `display: flex; align-items: center; gap: 6pt; justify-content: space-between;`}
|
|
94
|
+
<div {style}>
|
|
95
|
+
{option}
|
|
96
|
+
<div style="display: flex; gap: 3pt;">
|
|
97
|
+
{#each get_representative_colors(String(option)) as color (color)}
|
|
98
|
+
{@const style = `width: 15px; height: 15px; border-radius: 2px; background: {color};`}
|
|
99
|
+
<div {style}></div>
|
|
100
|
+
{/each}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
{/snippet}
|
|
104
|
+
</Select>
|
|
105
|
+
</label>
|
|
106
|
+
|
|
107
|
+
<hr />
|
|
108
|
+
|
|
109
|
+
<!-- Cell Controls -->
|
|
110
|
+
<h4 class="section-heading">Cell</h4>
|
|
111
|
+
<label>
|
|
112
|
+
<input type="checkbox" bind:checked={lattice_props.show_vectors} />
|
|
113
|
+
lattice vectors
|
|
114
|
+
</label>
|
|
115
|
+
{#each [
|
|
116
|
+
{ label: `Edge color`, color_prop: `cell_edge_color`, opacity_prop: `cell_edge_opacity`, step: 0.05 },
|
|
117
|
+
{ label: `Surface color`, color_prop: `cell_surface_color`, opacity_prop: `cell_surface_opacity`, step: 0.01 },
|
|
118
|
+
] as const as { label, color_prop, opacity_prop, step } (label)}
|
|
119
|
+
<div class="control-row">
|
|
120
|
+
<label class="compact">
|
|
121
|
+
{label}
|
|
122
|
+
<input type="color" bind:value={lattice_props[color_prop]} />
|
|
123
|
+
</label>
|
|
124
|
+
<label class="slider-control">
|
|
125
|
+
opacity
|
|
126
|
+
<input
|
|
127
|
+
type="number"
|
|
128
|
+
min={0}
|
|
129
|
+
max={1}
|
|
130
|
+
{step}
|
|
131
|
+
bind:value={lattice_props[opacity_prop]}
|
|
132
|
+
/>
|
|
133
|
+
<input
|
|
134
|
+
type="range"
|
|
135
|
+
min={0}
|
|
136
|
+
max={1}
|
|
137
|
+
{step}
|
|
138
|
+
bind:value={lattice_props[opacity_prop]}
|
|
139
|
+
/>
|
|
140
|
+
</label>
|
|
141
|
+
</div>
|
|
142
|
+
{/each}
|
|
143
|
+
|
|
144
|
+
<hr />
|
|
145
|
+
|
|
146
|
+
<!-- Background Controls -->
|
|
147
|
+
<h4 class="section-heading">Background</h4>
|
|
148
|
+
<div class="control-row">
|
|
149
|
+
<label class="compact">
|
|
150
|
+
Color
|
|
151
|
+
<input type="color" bind:value={background_color} />
|
|
152
|
+
</label>
|
|
153
|
+
<label class="slider-control">
|
|
154
|
+
Opacity
|
|
155
|
+
<input
|
|
156
|
+
type="number"
|
|
157
|
+
min={0}
|
|
158
|
+
max={1}
|
|
159
|
+
step={0.02}
|
|
160
|
+
bind:value={background_opacity}
|
|
161
|
+
/>
|
|
162
|
+
<input
|
|
163
|
+
type="range"
|
|
164
|
+
min={0}
|
|
165
|
+
max={1}
|
|
166
|
+
step={0.02}
|
|
167
|
+
bind:value={background_opacity}
|
|
168
|
+
/>
|
|
169
|
+
</label>
|
|
170
|
+
</div>
|
|
171
|
+
|
|
172
|
+
{#if show_full_controls}
|
|
173
|
+
<!-- Camera Controls -->
|
|
174
|
+
<h4 class="section-heading">Camera</h4>
|
|
175
|
+
<label>
|
|
176
|
+
Auto rotate speed
|
|
177
|
+
<input
|
|
178
|
+
type="number"
|
|
179
|
+
min={0}
|
|
180
|
+
max={2}
|
|
181
|
+
step={0.01}
|
|
182
|
+
bind:value={scene_props.auto_rotate}
|
|
183
|
+
/>
|
|
184
|
+
<input
|
|
185
|
+
type="range"
|
|
186
|
+
min={0}
|
|
187
|
+
max={2}
|
|
188
|
+
step={0.01}
|
|
189
|
+
bind:value={scene_props.auto_rotate}
|
|
190
|
+
/>
|
|
191
|
+
</label>
|
|
192
|
+
<label>
|
|
193
|
+
Zoom speed
|
|
194
|
+
<input
|
|
195
|
+
type="number"
|
|
196
|
+
min={0.1}
|
|
197
|
+
max={0.8}
|
|
198
|
+
step={0.02}
|
|
199
|
+
bind:value={scene_props.zoom_speed}
|
|
200
|
+
/>
|
|
201
|
+
<input
|
|
202
|
+
type="range"
|
|
203
|
+
min={0.1}
|
|
204
|
+
max={0.8}
|
|
205
|
+
step={0.02}
|
|
206
|
+
bind:value={scene_props.zoom_speed}
|
|
207
|
+
/>
|
|
208
|
+
</label>
|
|
209
|
+
<label>
|
|
210
|
+
<Tooltip text="pan by clicking and dragging while holding cmd, ctrl or shift">
|
|
211
|
+
Pan speed
|
|
212
|
+
</Tooltip>
|
|
213
|
+
<input
|
|
214
|
+
type="number"
|
|
215
|
+
min={0}
|
|
216
|
+
max={2}
|
|
217
|
+
step={0.01}
|
|
218
|
+
bind:value={scene_props.pan_speed}
|
|
219
|
+
/>
|
|
220
|
+
<input
|
|
221
|
+
type="range"
|
|
222
|
+
min={0}
|
|
223
|
+
max={2}
|
|
224
|
+
step={0.01}
|
|
225
|
+
bind:value={scene_props.pan_speed}
|
|
226
|
+
/>
|
|
227
|
+
</label>
|
|
228
|
+
<label>
|
|
229
|
+
<Tooltip text="damping factor for rotation">Rotation damping</Tooltip>
|
|
230
|
+
<input
|
|
231
|
+
type="number"
|
|
232
|
+
min={0}
|
|
233
|
+
max={0.3}
|
|
234
|
+
step={0.01}
|
|
235
|
+
bind:value={scene_props.rotation_damping}
|
|
236
|
+
/>
|
|
237
|
+
<input
|
|
238
|
+
type="range"
|
|
239
|
+
min={0}
|
|
240
|
+
max={0.3}
|
|
241
|
+
step={0.01}
|
|
242
|
+
bind:value={scene_props.rotation_damping}
|
|
243
|
+
/>
|
|
244
|
+
</label>
|
|
245
|
+
|
|
246
|
+
<hr />
|
|
247
|
+
|
|
248
|
+
<!-- Lighting Controls -->
|
|
249
|
+
<h4 class="section-heading">Lighting</h4>
|
|
250
|
+
<label>
|
|
251
|
+
<Tooltip text="intensity of the directional light">Directional light</Tooltip>
|
|
252
|
+
<input
|
|
253
|
+
type="number"
|
|
254
|
+
min={0}
|
|
255
|
+
max={4}
|
|
256
|
+
step={0.01}
|
|
257
|
+
bind:value={scene_props.directional_light}
|
|
258
|
+
/>
|
|
259
|
+
<input
|
|
260
|
+
type="range"
|
|
261
|
+
min={0}
|
|
262
|
+
max={4}
|
|
263
|
+
step={0.01}
|
|
264
|
+
bind:value={scene_props.directional_light}
|
|
265
|
+
/>
|
|
266
|
+
</label>
|
|
267
|
+
<label>
|
|
268
|
+
<Tooltip text="intensity of the ambient light">Ambient light</Tooltip>
|
|
269
|
+
<input
|
|
270
|
+
type="number"
|
|
271
|
+
min={0.5}
|
|
272
|
+
max={3}
|
|
273
|
+
step={0.05}
|
|
274
|
+
bind:value={scene_props.ambient_light}
|
|
275
|
+
/>
|
|
276
|
+
<input
|
|
277
|
+
type="range"
|
|
278
|
+
min={0.5}
|
|
279
|
+
max={3}
|
|
280
|
+
step={0.05}
|
|
281
|
+
bind:value={scene_props.ambient_light}
|
|
282
|
+
/>
|
|
283
|
+
</label>
|
|
284
|
+
{/if}
|
|
285
|
+
|
|
286
|
+
<hr />
|
|
287
|
+
|
|
288
|
+
{#if scene_props.show_bonds}
|
|
289
|
+
<label>
|
|
290
|
+
Bonding strategy
|
|
291
|
+
<select bind:value={scene_props.bonding_strategy}>
|
|
292
|
+
<option value="max_dist">Max Distance</option>
|
|
293
|
+
<option value="nearest_neighbor">Nearest Neighbor</option>
|
|
294
|
+
<option value="vdw_radius_based">Van der Waals Radii</option>
|
|
295
|
+
</select>
|
|
296
|
+
</label>
|
|
297
|
+
|
|
298
|
+
<label>
|
|
299
|
+
Bond color
|
|
300
|
+
<input type="color" bind:value={scene_props.bond_color} />
|
|
301
|
+
</label>
|
|
302
|
+
<label>
|
|
303
|
+
Bond thickness
|
|
304
|
+
<input
|
|
305
|
+
type="number"
|
|
306
|
+
min={0.01}
|
|
307
|
+
max={0.12}
|
|
308
|
+
step={0.005}
|
|
309
|
+
bind:value={scene_props.bond_thickness}
|
|
310
|
+
/>
|
|
311
|
+
<input
|
|
312
|
+
type="range"
|
|
313
|
+
min="0.01"
|
|
314
|
+
max="0.12"
|
|
315
|
+
step={0.005}
|
|
316
|
+
bind:value={scene_props.bond_thickness}
|
|
317
|
+
/>
|
|
318
|
+
</label>
|
|
319
|
+
{/if}
|
|
320
|
+
|
|
321
|
+
<span
|
|
322
|
+
style="display: flex; gap: 4pt; margin: 3pt 0 0; align-items: center; flex-wrap: wrap;"
|
|
323
|
+
>
|
|
324
|
+
<button
|
|
325
|
+
type="button"
|
|
326
|
+
onclick={() => exports.export_json(structure)}
|
|
327
|
+
title={save_json_btn_text}
|
|
328
|
+
>
|
|
329
|
+
{save_json_btn_text}
|
|
330
|
+
</button>
|
|
331
|
+
<button
|
|
332
|
+
type="button"
|
|
333
|
+
onclick={() => exports.export_xyz(structure)}
|
|
334
|
+
title={save_xyz_btn_text}
|
|
335
|
+
>
|
|
336
|
+
{save_xyz_btn_text}
|
|
337
|
+
</button>
|
|
338
|
+
<button
|
|
339
|
+
type="button"
|
|
340
|
+
onclick={() => {
|
|
341
|
+
const canvas = wrapper?.querySelector(`canvas`) as HTMLCanvasElement
|
|
342
|
+
exports.export_png(canvas, structure, png_dpi)
|
|
343
|
+
}}
|
|
344
|
+
title="{save_png_btn_text} (${png_dpi} DPI)"
|
|
345
|
+
>
|
|
346
|
+
{save_png_btn_text}
|
|
347
|
+
</button>
|
|
348
|
+
<small style="margin-left: 4pt;">DPI:</small>
|
|
349
|
+
<input
|
|
350
|
+
type="number"
|
|
351
|
+
min={72}
|
|
352
|
+
max={300}
|
|
353
|
+
step={25}
|
|
354
|
+
bind:value={png_dpi}
|
|
355
|
+
style="width: 3.5em;"
|
|
356
|
+
title="Export resolution in dots per inch"
|
|
357
|
+
/>
|
|
358
|
+
</span>
|
|
359
|
+
{/snippet}
|
|
360
|
+
</ControlPanel>
|
|
361
|
+
|
|
362
|
+
<style>
|
|
363
|
+
.section-heading {
|
|
364
|
+
margin: 8pt 0 2pt;
|
|
365
|
+
font-size: 0.9em;
|
|
366
|
+
color: var(--text-muted, #ccc);
|
|
367
|
+
}
|
|
368
|
+
.control-row {
|
|
369
|
+
display: flex;
|
|
370
|
+
gap: 4pt;
|
|
371
|
+
align-items: flex-start;
|
|
372
|
+
}
|
|
373
|
+
.control-row label {
|
|
374
|
+
min-width: 0;
|
|
375
|
+
}
|
|
376
|
+
.control-row label.compact {
|
|
377
|
+
flex: 0 0 auto;
|
|
378
|
+
margin-right: 8pt;
|
|
379
|
+
}
|
|
380
|
+
.control-row label.slider-control {
|
|
381
|
+
flex: 1;
|
|
382
|
+
}
|
|
383
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AnyStructure, Lattice } from '..';
|
|
2
|
+
import type { ComponentProps } from 'svelte';
|
|
3
|
+
import type { StructureScene } from './index';
|
|
4
|
+
export interface Props {
|
|
5
|
+
controls_open?: boolean;
|
|
6
|
+
scene_props?: ComponentProps<typeof StructureScene>;
|
|
7
|
+
lattice_props?: ComponentProps<typeof Lattice>;
|
|
8
|
+
show_image_atoms?: boolean;
|
|
9
|
+
show_site_labels?: boolean;
|
|
10
|
+
show_full_controls?: boolean;
|
|
11
|
+
background_color?: string;
|
|
12
|
+
background_opacity?: number;
|
|
13
|
+
color_scheme?: `Jmol` | `Vesta`;
|
|
14
|
+
structure?: AnyStructure | undefined;
|
|
15
|
+
wrapper?: HTMLDivElement | undefined;
|
|
16
|
+
png_dpi?: number;
|
|
17
|
+
save_json_btn_text?: string;
|
|
18
|
+
save_png_btn_text?: string;
|
|
19
|
+
save_xyz_btn_text?: string;
|
|
20
|
+
}
|
|
21
|
+
declare const StructureControls: import("svelte").Component<Props, {}, "color_scheme" | "controls_open" | "scene_props" | "lattice_props" | "show_image_atoms" | "show_site_labels" | "show_full_controls" | "background_color" | "background_opacity" | "png_dpi">;
|
|
22
|
+
type StructureControls = ReturnType<typeof StructureControls>;
|
|
23
|
+
export default StructureControls;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<script lang="ts">import { choose_bw_for_contrast, element_data, format_num } from '..';
|
|
2
|
+
import { default_element_colors } from '../colors';
|
|
3
|
+
import { colors } from '../state.svelte';
|
|
4
|
+
import { Tooltip } from 'svelte-zoo';
|
|
5
|
+
let { elements, elem_color_picker_title = `Double click to reset color`, labels = $bindable([]), tips_modal = $bindable(undefined), style = null, dialog_style = null, tips_modal_snippet, amount_format = `.3~f`, show_amounts = true, get_element_label, } = $props();
|
|
6
|
+
// Generate label text for each element
|
|
7
|
+
function get_label_text(element, amount) {
|
|
8
|
+
if (get_element_label)
|
|
9
|
+
return get_element_label(element, amount);
|
|
10
|
+
return show_amounts ? `${element}${format_num(amount, amount_format)}` : element;
|
|
11
|
+
}
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<div {style}>
|
|
15
|
+
{#each Object.entries(elements) as [elem, amt], idx (elem + amt)}
|
|
16
|
+
<Tooltip
|
|
17
|
+
text={element_data.find((el) => el.symbol == elem)?.name}
|
|
18
|
+
--zoo-tooltip-bg="rgba(255, 255, 255, 0.3)"
|
|
19
|
+
tip_style="font-size: initial; padding: 0 5pt;"
|
|
20
|
+
>
|
|
21
|
+
<label
|
|
22
|
+
bind:this={labels[idx]}
|
|
23
|
+
style:background-color={colors.element[elem]}
|
|
24
|
+
ondblclick={(event) => {
|
|
25
|
+
event.preventDefault()
|
|
26
|
+
colors.element[elem] = default_element_colors[elem]
|
|
27
|
+
}}
|
|
28
|
+
style:color={choose_bw_for_contrast(labels[idx], null, 0.55)}
|
|
29
|
+
>
|
|
30
|
+
{get_label_text(elem, amt)}
|
|
31
|
+
<input
|
|
32
|
+
type="color"
|
|
33
|
+
bind:value={colors.element[elem]}
|
|
34
|
+
title={elem_color_picker_title}
|
|
35
|
+
/>
|
|
36
|
+
</label>
|
|
37
|
+
</Tooltip>
|
|
38
|
+
{/each}
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<dialog
|
|
42
|
+
bind:this={tips_modal}
|
|
43
|
+
onclick={() => tips_modal?.close()}
|
|
44
|
+
onkeydown={() => tips_modal?.close()}
|
|
45
|
+
style={dialog_style}
|
|
46
|
+
>
|
|
47
|
+
{#if tips_modal_snippet}{@render tips_modal_snippet()}{:else}
|
|
48
|
+
<p>
|
|
49
|
+
Drop a POSCAR, XYZ, CIF or pymatgen JSON file onto the canvas to load a new
|
|
50
|
+
structure.
|
|
51
|
+
</p>
|
|
52
|
+
<p>
|
|
53
|
+
Click on an atom to make it active. Then hover another atom to get its distance to
|
|
54
|
+
the active atom (with PBC and direct).
|
|
55
|
+
</p>
|
|
56
|
+
<p>
|
|
57
|
+
Hold <kbd>shift</kbd> or <kbd>cmd</kbd> or <kbd>ctrl</kbd> and drag to pan the
|
|
58
|
+
scene.
|
|
59
|
+
</p>
|
|
60
|
+
<p>
|
|
61
|
+
Click on an element label in the color legend to change its color. Double click to
|
|
62
|
+
reset.
|
|
63
|
+
</p>
|
|
64
|
+
{/if}
|
|
65
|
+
</dialog>
|
|
66
|
+
|
|
67
|
+
<style>
|
|
68
|
+
div {
|
|
69
|
+
display: flex;
|
|
70
|
+
position: absolute;
|
|
71
|
+
bottom: var(--struct-legend-bottom, 8pt);
|
|
72
|
+
right: var(--struct-legend-right, 8pt);
|
|
73
|
+
gap: var(--struct-legend-gap, 8pt);
|
|
74
|
+
font-size: var(--struct-legend-font, 14pt);
|
|
75
|
+
filter: grayscale(10%) brightness(0.8) saturate(0.8);
|
|
76
|
+
z-index: var(--struct-legend-z-index, 1);
|
|
77
|
+
}
|
|
78
|
+
div label {
|
|
79
|
+
padding: var(--struct-legend-pad, 1pt 4pt);
|
|
80
|
+
border-radius: var(--struct-legend-radius, 3pt);
|
|
81
|
+
}
|
|
82
|
+
div label input[type='color'] {
|
|
83
|
+
z-index: var(--struct-legend-input-z, 1);
|
|
84
|
+
opacity: 0;
|
|
85
|
+
position: absolute;
|
|
86
|
+
width: 100%;
|
|
87
|
+
height: 100%;
|
|
88
|
+
top: 0;
|
|
89
|
+
left: 0;
|
|
90
|
+
cursor: pointer;
|
|
91
|
+
}
|
|
92
|
+
dialog {
|
|
93
|
+
position: fixed;
|
|
94
|
+
top: var(--struct-dialog-top, 50%);
|
|
95
|
+
left: var(--struct-dialog-left, 50%);
|
|
96
|
+
transform: translate(-50%, -50%);
|
|
97
|
+
margin: 0;
|
|
98
|
+
padding: var(--struct-dialog-pad, 4pt 1em);
|
|
99
|
+
background: var(--struct-dialog-bg, rgba(0, 0, 0, 0.8));
|
|
100
|
+
color: var(--struct-dialog-color, white);
|
|
101
|
+
border-radius: var(--struct-dialog-radius, 5px);
|
|
102
|
+
transition: var(--struct-dialog-transition, all 0.3s);
|
|
103
|
+
overflow: visible;
|
|
104
|
+
}
|
|
105
|
+
/* info icon in top left corner */
|
|
106
|
+
dialog::before {
|
|
107
|
+
content: '?';
|
|
108
|
+
position: absolute;
|
|
109
|
+
top: 0;
|
|
110
|
+
left: 0;
|
|
111
|
+
display: flex;
|
|
112
|
+
place-content: center;
|
|
113
|
+
place-items: center;
|
|
114
|
+
transform: var(--struct-tooltip-before-transform, translate(-50%, -50%));
|
|
115
|
+
box-sizing: border-box;
|
|
116
|
+
font-size: var(--struct-tooltip-before-font-size, 20pt);
|
|
117
|
+
color: var(--struct-tooltip-before-color, white);
|
|
118
|
+
background: var(--struct-tooltip-before-bg, rgba(0, 0, 0, 0.8));
|
|
119
|
+
border-radius: var(--struct-tooltip-before-border-radius, 50%);
|
|
120
|
+
width: var(--struct-tooltip-before-width, 1em);
|
|
121
|
+
height: var(--struct-tooltip-before-height, 1em);
|
|
122
|
+
border: var(--struct-tooltip-before-border, 1px solid white);
|
|
123
|
+
}
|
|
124
|
+
dialog::backdrop {
|
|
125
|
+
background: var(--struct-dialog-backdrop, rgba(0, 0, 0, 0.2));
|
|
126
|
+
}
|
|
127
|
+
dialog p {
|
|
128
|
+
margin: var(--struct-dialog-text-margin, 0);
|
|
129
|
+
}
|
|
130
|
+
</style>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CompositionType } from '..';
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
interface Props {
|
|
4
|
+
elements: CompositionType;
|
|
5
|
+
elem_color_picker_title?: string;
|
|
6
|
+
labels?: HTMLLabelElement[];
|
|
7
|
+
tips_modal?: HTMLDialogElement | undefined;
|
|
8
|
+
style?: string | null;
|
|
9
|
+
dialog_style?: string | null;
|
|
10
|
+
tips_modal_snippet?: Snippet;
|
|
11
|
+
amount_format?: string;
|
|
12
|
+
show_amounts?: boolean;
|
|
13
|
+
get_element_label?: (element: string, amount: number) => string;
|
|
14
|
+
}
|
|
15
|
+
declare const StructureLegend: import("svelte").Component<Props, {}, "labels" | "tips_modal">;
|
|
16
|
+
type StructureLegend = ReturnType<typeof StructureLegend>;
|
|
17
|
+
export default StructureLegend;
|