@ccp-nc/crystvis-js 0.4.13

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 (100) hide show
  1. package/.eslintrc.json +16 -0
  2. package/.github/workflows/test-mocha.yml +30 -0
  3. package/.vscode/settings.json +4 -0
  4. package/LICENSE +21 -0
  5. package/README.html +1127 -0
  6. package/README.md +76 -0
  7. package/demo/demo.css +30 -0
  8. package/demo/index.html +76 -0
  9. package/demo/main.js +143 -0
  10. package/docs/.nojekyll +0 -0
  11. package/docs-tutorials/Events.md +57 -0
  12. package/docs-tutorials/Queries.md +50 -0
  13. package/fonts/Rubik/OFL.txt +93 -0
  14. package/fonts/Rubik/README.txt +77 -0
  15. package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
  16. package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
  17. package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
  18. package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
  19. package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
  20. package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
  21. package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
  22. package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
  23. package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
  24. package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
  25. package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
  26. package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
  27. package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
  28. package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
  29. package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
  30. package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
  31. package/index.html +25 -0
  32. package/index.js +11 -0
  33. package/jsconf.json +14 -0
  34. package/lib/assets/fonts/Rubik-Medium.fnt +297 -0
  35. package/lib/assets/fonts/Rubik-Medium.png +0 -0
  36. package/lib/assets/fonts/bmpfonts.in.js +16 -0
  37. package/lib/assets/fonts/bmpfonts.js +9 -0
  38. package/lib/assets/fonts/font.js +82 -0
  39. package/lib/assets/fonts/index.js +14 -0
  40. package/lib/assets/fonts/threebmfont.js +28 -0
  41. package/lib/data.js +125 -0
  42. package/lib/formats/cell.js +114 -0
  43. package/lib/formats/cif.js +22 -0
  44. package/lib/formats/magres.js +337 -0
  45. package/lib/formats/xyz.js +124 -0
  46. package/lib/loader.js +87 -0
  47. package/lib/model.js +2076 -0
  48. package/lib/modelview.js +382 -0
  49. package/lib/nmrdata.js +2898 -0
  50. package/lib/orbit.js +1233 -0
  51. package/lib/primitives/atoms.js +261 -0
  52. package/lib/primitives/cell.js +160 -0
  53. package/lib/primitives/dither.js +156 -0
  54. package/lib/primitives/ellipsoid.js +183 -0
  55. package/lib/primitives/geometries.js +20 -0
  56. package/lib/primitives/index.js +48 -0
  57. package/lib/primitives/isosurface.js +171 -0
  58. package/lib/primitives/shapes.js +100 -0
  59. package/lib/primitives/sprites.js +172 -0
  60. package/lib/query.js +158 -0
  61. package/lib/render.js +440 -0
  62. package/lib/selbox.js +361 -0
  63. package/lib/shaders/aura.frag +26 -0
  64. package/lib/shaders/aura.vert +37 -0
  65. package/lib/shaders/dither.frag +42 -0
  66. package/lib/shaders/dither.vert +8 -0
  67. package/lib/shaders/index.in.js +17 -0
  68. package/lib/shaders/index.js +25 -0
  69. package/lib/shaders/msdf300.frag +25 -0
  70. package/lib/shaders/msdf300.vert +45 -0
  71. package/lib/tensor.js +227 -0
  72. package/lib/utils.js +168 -0
  73. package/lib/visualizer.js +480 -0
  74. package/package.json +106 -0
  75. package/scripts/build-bundle.js +17 -0
  76. package/scripts/build-fonts.js +43 -0
  77. package/scripts/build-resources.js +46 -0
  78. package/scripts/plugins-shim.js +10 -0
  79. package/test/chemdata.js +69 -0
  80. package/test/data/CHA.cif +74 -0
  81. package/test/data/H2O.xyz +8 -0
  82. package/test/data/H2_bound.xyz +4 -0
  83. package/test/data/ethanol.cell +25 -0
  84. package/test/data/ethanol.magres +238 -0
  85. package/test/data/example_single.cif +789 -0
  86. package/test/data/frac.cell +8 -0
  87. package/test/data/org.cif +427 -0
  88. package/test/data/pyridine.xyz +13 -0
  89. package/test/data/si8.xyz +10 -0
  90. package/test/loader.js +107 -0
  91. package/test/model.js +368 -0
  92. package/test/query.js +135 -0
  93. package/test/tensor.js +133 -0
  94. package/test/test-html/examples.js +1485 -0
  95. package/test/test-html/index.html +33 -0
  96. package/test/test-html/index.js +279 -0
  97. package/tools/compile_colors.py +120 -0
  98. package/tools/compile_periodic.py +96 -0
  99. package/tools/ptable.json +497 -0
  100. package/tools/test +5844 -0
@@ -0,0 +1,480 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * @fileoverview Class constituting the main object that plots crystals in the webpage
5
+ * @module
6
+ */
7
+
8
+ import * as _ from 'lodash';
9
+
10
+ import {
11
+ Renderer as Renderer
12
+ } from './render.js';
13
+ import {
14
+ Loader as Loader
15
+ } from './loader.js';
16
+ import {
17
+ Model as Model
18
+ } from './model.js';
19
+ import {
20
+ ModelView as ModelView
21
+ } from './modelview.js';
22
+ import {
23
+ AtomMesh
24
+ } from './primitives/index.js';
25
+ import {
26
+ addStaticVar
27
+ } from './utils.js';
28
+
29
+
30
+ const model_parameter_defaults = {
31
+ supercell: [1, 1, 1],
32
+ molecularCrystal: false
33
+ };
34
+
35
+ /** An object providing a full interface to a renderer for crystallographic models */
36
+ class CrystVis {
37
+
38
+ /**
39
+ * An object providing a full interface to a renderer for crystallographic
40
+ * models
41
+ * @class
42
+ * @param {string} element CSS-style identifier for the HTML element to
43
+ * put the renderer in
44
+ * @param {int} width Window width
45
+ * @param {int} height Window height. If both this and width are
46
+ * set to 0, the window fits its context and
47
+ * automatically resizes with it
48
+ */
49
+ constructor(element, width = 0, height = 0) {
50
+
51
+ // Create a renderer
52
+ this._renderer = new Renderer(element, width, height);
53
+ this._loader = new Loader();
54
+
55
+ this._models = {};
56
+
57
+ this._current_model = null;
58
+ this._current_mname = null;
59
+ this._displayed = null;
60
+ this._selected = null;
61
+
62
+ // Handling events
63
+ this._atom_click_events = {};
64
+ this._atom_click_events[CrystVis.LEFT_CLICK] = this._defaultAtomLeftClick.bind(this);
65
+ this._atom_click_events[CrystVis.LEFT_CLICK + CrystVis.SHIFT_BUTTON] = this._defaultAtomShiftLeftClick.bind(this);
66
+ this._atom_click_events[CrystVis.LEFT_CLICK + CrystVis.CTRL_BUTTON] = this._defaultAtomCtrlLeftClick.bind(this);
67
+
68
+ this._atom_click_defaults = _.cloneDeep(this._atom_click_events);
69
+
70
+ this._atom_box_event = this._defaultAtomBox.bind(this);
71
+
72
+ this._renderer.addClickListener(this._handleAtomClick.bind(this),
73
+ this._renderer._groups.model, AtomMesh);
74
+ this._renderer.addSelBoxListener(this._handleAtomBox.bind(this),
75
+ this._renderer._groups.model, AtomMesh);
76
+
77
+ // Additional options
78
+ // Hidden (need dedicated setters)
79
+ this._hsel = false; // If true, highlight the selected atoms
80
+
81
+ // Vanilla (no get/set needed)
82
+ this.cifsymtol = 1e-2; // Parameter controlling the tolerance to symmetry when loading CIF files
83
+
84
+ }
85
+
86
+ /**
87
+ * List of loaded models
88
+ * @readonly
89
+ * @type {Array}
90
+ */
91
+ get modelList() {
92
+ return Object.keys(this._models);
93
+ }
94
+
95
+ /**
96
+ * Currently loaded model
97
+ * @readonly
98
+ * @type {Model}
99
+ */
100
+ get model() {
101
+ return this._current_model;
102
+ }
103
+
104
+ /**
105
+ * Name of the currently loaded model
106
+ * @readonly
107
+ * @type {String}
108
+ */
109
+ get modelName() {
110
+ return this._current_mname;
111
+ }
112
+
113
+ /**
114
+ * Displayed atoms
115
+ * @type {ModelView}
116
+ */
117
+ get displayed() {
118
+ return this._displayed;
119
+ }
120
+
121
+ set displayed(d) {
122
+ if (!(d instanceof ModelView)) {
123
+ throw new Error('.displayed must be set with a ModelView');
124
+ }
125
+ this._displayed.hide();
126
+ this._displayed = d;
127
+ this._displayed.show();
128
+ }
129
+
130
+ /**
131
+ * Selected atoms
132
+ * @type {ModelView}
133
+ */
134
+ get selected() {
135
+ return this._selected;
136
+ }
137
+
138
+ set selected(s) {
139
+ if (!(s instanceof ModelView)) {
140
+ throw new Error('.selected must be set with a ModelView');
141
+ }
142
+ this._selected.setProperty('highlighted', false);
143
+ this._selected = s;
144
+ this._selected.setProperty('highlighted', this._hsel);
145
+ }
146
+
147
+ /** Whether the selected atoms should be highlighted with auras
148
+ * @type {bool}
149
+ */
150
+ get highlightSelected() {
151
+ return this._hsel;
152
+ }
153
+
154
+ set highlightSelected(hs) {
155
+ this._hsel = hs;
156
+ if (this._selected) {
157
+ this._selected.setProperty('highlighted', this._hsel);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Set a callback function for an event where a user clicks on an atom. The
163
+ * function should take as arguments the atom image for the clicked atom and
164
+ * the event object:
165
+ *
166
+ * function callback(atom, event) {
167
+ * ...
168
+ * }
169
+ *
170
+ * @param {Function} callback Callback function for the event. Passing "null" restores default behaviour
171
+ * @param {int} modifiers Click event. Use the following flags to define it:
172
+ *
173
+ * * CrystVis.LEFT_CLICK
174
+ * * CrystVis.RIGHT_CLICK
175
+ * * CrystVis.MIDDLE_CLICK
176
+ * * CrystVis.CTRL_BUTTON
177
+ * * CrystVis.ALT_BUTTON
178
+ * * CrystVis.SHIFT_BUTTON
179
+ * * CrystVis.CMD_BUTTON
180
+ *
181
+ * For example, CrystVis.LEFT_CLICK + CrystVis.SHIFT_BUTTON
182
+ * defines the event for a click while the Shift key is pressed.
183
+ *
184
+ */
185
+ onAtomClick(callback = null, modifiers = CrystVis.LEFT_CLICK) {
186
+
187
+ // Check that event makes sense
188
+ var lc = modifiers & CrystVis.LEFT_CLICK;
189
+ var mc = modifiers & CrystVis.MIDDLE_CLICK;
190
+ var rc = modifiers & CrystVis.RIGHT_CLICK;
191
+
192
+ if (lc + mc + rc == 0) {
193
+ throw 'Can not set event without any click type';
194
+ }
195
+ if ((lc && mc) || (lc && rc) || (mc && rc)) {
196
+ throw 'Can not set event with two or more click types';
197
+ }
198
+
199
+ if (callback)
200
+ this._atom_click_events[modifiers] = callback.bind(this);
201
+ else
202
+ this._atom_click_events[modifiers] = this._atom_click_defaults[modifiers];
203
+ }
204
+
205
+ /**
206
+ * Set a callback function for an event where a user drags a box around multiple atoms.
207
+ * The function should take as arguments a ModelView including the atoms in the box:
208
+ *
209
+ * function callback(view) {
210
+ * ...
211
+ * }
212
+ *
213
+ * @param {Function} callback Callback function for the event. Passing "null" restores default behaviour
214
+ */
215
+ onAtomBox(callback = null) {
216
+ if (callback)
217
+ this._atom_box_event = callback;
218
+ else
219
+ this._atom_box_event = this._defaultAtomBox.bind(this);
220
+ }
221
+
222
+ _defaultAtomLeftClick(atom, event) {
223
+ var i = atom.imgIndex;
224
+ this.selected = new ModelView(this._current_model, [i]);
225
+ }
226
+ _defaultAtomShiftLeftClick(atom, event) {
227
+ var i = atom.imgIndex;
228
+ this.selected = this.selected.or(new ModelView(this._current_model, [i]));
229
+ }
230
+ _defaultAtomCtrlLeftClick(atom, event) {
231
+ var i = atom.imgIndex;
232
+ this.selected = this.selected.xor(new ModelView(this._current_model, [i]));
233
+ }
234
+
235
+ _defaultAtomBox(view) {
236
+ this.selected = this.selected.xor(view);
237
+ console.log(view);
238
+ }
239
+
240
+ // Callback for when atoms are clicked
241
+ _handleAtomClick(alist, event) {
242
+
243
+ if (alist.length == 0) {
244
+ return;
245
+ }
246
+
247
+ let clicked = alist[0].image;
248
+
249
+ let modifiers = [CrystVis.LEFT_CLICK, CrystVis.MIDDLE_CLICK, CrystVis.RIGHT_CLICK][event.button];
250
+
251
+ modifiers += event.shiftKey * CrystVis.SHIFT_BUTTON;
252
+ modifiers += (event.ctrlKey || event.metaKey) * CrystVis.CTRL_BUTTON;
253
+ modifiers += event.altKey * CrystVis.ALT_BUTTON;
254
+
255
+ var callback = this._atom_click_events[modifiers];
256
+
257
+ if (callback)
258
+ callback(clicked, event);
259
+
260
+ }
261
+
262
+ // Callback for a whole box dragged over atoms
263
+ _handleAtomBox(alist) {
264
+
265
+ var indices = alist.map(function(a) {
266
+ return a.image.imgIndex;
267
+ });
268
+
269
+ var callback = this._atom_box_event;
270
+
271
+ if (callback)
272
+ callback(new ModelView(this._current_model, indices));
273
+ }
274
+
275
+ /**
276
+ * Center the camera on a given point
277
+ *
278
+ * @param {float[]} center Point in model space that the orbiting camera
279
+ * should be centred on and look at
280
+ * @param {float[]} shift Shift (in units of width/height of the canvas) with
281
+ * which the center of the camera should be rendered with
282
+ * respect to the center of the canvas
283
+ */
284
+ centerCamera(center = [0, 0, 0], shift = [0, 0]) {
285
+ const renderer = this._renderer;
286
+
287
+ renderer.resetOrbitCenter(center[0], center[1], center[2]);
288
+ renderer.resetCameraCenter(shift[0], shift[1]);
289
+ }
290
+
291
+ /**
292
+ * Load one or more atomic models from a file's contents
293
+ *
294
+ * @param {String} contents The contents of the structure file
295
+ * @param {String} format The file's format (cif, xyz, etc.). Default is cif.
296
+ * @param {String} prefix Prefix to use when naming the models. Default is empty.
297
+ * @param {Object} parameters Loading parameters:
298
+ *
299
+ * - `supercell`: supercell size (only used if the structure is periodic)
300
+ * - `molecularCrystal`: if true, try to make the model load completing molecules across periodic boundaries
301
+ * - `useNMRActiveIsotopes`: if true, all isotopes are set by default to the most common one with non-zero spin
302
+ * - `vdwScaling`: scale van der Waals radii by a constant factor
303
+ * - `vdwElementScaling`: table of per-element factors to scale VdW radii by
304
+ *
305
+ * @return {Object} Names of the models we tried to load, and values of true/false for successful loading or not
306
+ */
307
+ loadModels(contents, format = 'cif', prefix = null, parameters = {}) {
308
+
309
+ parameters = _.merge(model_parameter_defaults, parameters);
310
+
311
+ // By default, it's cif
312
+ format = format.toLowerCase();
313
+
314
+ // By default, same as the format
315
+ prefix = prefix || format;
316
+
317
+ var structs = this._loader.load(contents, format, prefix);
318
+
319
+ var status = {};
320
+
321
+ if (this._loader.status == Loader.STATUS_ERROR) {
322
+ status[prefix] = this._loader.error_message;
323
+ return status;
324
+ }
325
+
326
+ // Now make unique names
327
+ for (var n in structs) {
328
+ var iter = 0;
329
+ var coll = true;
330
+ var nn = n;
331
+ while (coll) {
332
+ nn = n + (iter > 0 ? '_' + iter : '');
333
+ coll = nn in this._models;
334
+ iter++;
335
+ }
336
+ var s = structs[n];
337
+ if (!s) {
338
+ status[nn] = 'Model could not load properly';
339
+ continue;
340
+ }
341
+ this._models[nn] = new Model(s, parameters);
342
+ status[nn] = 0; // Success
343
+ }
344
+
345
+ return status;
346
+ }
347
+
348
+ /**
349
+ * Reload a model, possibly with new parameters
350
+ *
351
+ * @param {String} name Name of the model to reload.
352
+ * @param {Object} parameters Loading parameters as in .loadModels()
353
+ */
354
+ reloadModel(name, parameters = {}) {
355
+
356
+ if (!(name in this._models)) {
357
+ throw 'The requested model does not exist';
358
+ }
359
+
360
+ var current = (this._current_mname == name);
361
+ if (current) {
362
+ // Hide the model to reload it later
363
+ this.displayModel();
364
+ }
365
+
366
+ var s = this._models[name]._atoms_base;
367
+ parameters = _.merge(model_parameter_defaults, parameters);
368
+
369
+ this._models[name] = new Model(s, parameters);
370
+
371
+ if (current) {
372
+ this.displayModel(name);
373
+ }
374
+ }
375
+
376
+ /**
377
+ * Render a model
378
+ *
379
+ * @param {String} name Name of the model to display. If empty, just
380
+ * clear the renderer window.
381
+ */
382
+ displayModel(name = null) {
383
+
384
+ if (this._current_model) {
385
+ this.selected = this._current_model.view([]);
386
+ this._current_model.renderer = null;
387
+ this._current_model = null;
388
+ this._current_mname = null;
389
+ }
390
+ this._renderer.clear();
391
+
392
+ if (!name) {
393
+ // If called with nothing, just quit here
394
+ return;
395
+ }
396
+
397
+ if (!(name in this._models)) {
398
+ throw 'The requested model does not exist';
399
+ }
400
+
401
+ var m = this._models[name];
402
+ m.renderer = this._renderer;
403
+
404
+ this._current_model = m;
405
+ this._current_mname = name;
406
+
407
+ this._displayed = m.find({
408
+ 'cell': [
409
+ [0, 0, 0]
410
+ ]
411
+ });
412
+ this._selected = new ModelView(m, []); // Empty
413
+
414
+ // Set the camera in a way that will center the model
415
+ var c = m.fracToAbs([0.5, 0.5, 0.5]);
416
+ this._renderer.resetOrbitCenter(c[0], c[1], c[2]);
417
+
418
+ this._displayed.show();
419
+ }
420
+
421
+ /**
422
+ * Erase a model from the recorded ones
423
+ *
424
+ * @param {String} name Name of the model to delete
425
+ */
426
+ deleteModel(name) {
427
+
428
+ if (!(name in this._models)) {
429
+ throw 'The requested model does not exist';
430
+ }
431
+
432
+ if (this._current_mname == name) {
433
+ this.displayModel();
434
+ }
435
+
436
+ delete this._models[name];
437
+ }
438
+
439
+ /**
440
+ * Add a primitive shape to the drawing
441
+ *
442
+ * @param {THREE.Object3D} p Primitive to add
443
+ */
444
+ addPrimitive(p) {
445
+ this._renderer.add(p);
446
+ }
447
+
448
+ /**
449
+ * Remove a primitive shape from the drawing
450
+ *
451
+ * @param {THREE.Object3D} p Primitive to remove
452
+ */
453
+ removePrimitive(p) {
454
+ this._renderer.remove(p);
455
+ }
456
+
457
+ /**
458
+ * Recover a data URL of a PNG screenshot of the current scene
459
+ *
460
+ * @return {String} A data URL of the PNG screenshot
461
+ */
462
+ getScreenshotData() {
463
+ // Force a render
464
+ this._renderer._render();
465
+ // Grab the data from the canvas
466
+ return this._renderer._r.domElement.toDataURL();
467
+ }
468
+ }
469
+
470
+ addStaticVar(CrystVis, 'LEFT_CLICK', 1);
471
+ addStaticVar(CrystVis, 'MIDDLE_CLICK', 2);
472
+ addStaticVar(CrystVis, 'RIGHT_CLICK', 4);
473
+ addStaticVar(CrystVis, 'ALT_BUTTON', 8);
474
+ addStaticVar(CrystVis, 'CTRL_BUTTON', 16);
475
+ addStaticVar(CrystVis, 'CMD_BUTTON', 16); // Alias for Mac users
476
+ addStaticVar(CrystVis, 'SHIFT_BUTTON', 32);
477
+
478
+ export {
479
+ CrystVis
480
+ }
package/package.json ADDED
@@ -0,0 +1,106 @@
1
+ {
2
+ "name": "@ccp-nc/crystvis-js",
3
+ "version": "0.4.13",
4
+ "description": "A Three.js based crystallographic visualisation tool",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "watch": {
8
+ "build-demo": {
9
+ "patterns": [
10
+ "demo/main.js",
11
+ "lib/*",
12
+ "lib/*/*",
13
+ "lib/*/*/*"
14
+ ],
15
+ "extensions": "js,json"
16
+ },
17
+ "build-html-test": {
18
+ "patterns": [
19
+ "test/test-html/index.js",
20
+ "lib/*",
21
+ "lib/*/*",
22
+ "lib/*/*/*"
23
+ ],
24
+ "extensions": "js,json"
25
+ },
26
+ "build-resources": {
27
+ "patterns": [
28
+ "lib/assets/fonts/*",
29
+ "lib/shaders/*"
30
+ ],
31
+ "extensions": "png,fnt,vert,frag"
32
+ }
33
+ },
34
+ "scripts": {
35
+ "test": "mocha --reporter spec",
36
+ "start": "npm run watch-testserver",
37
+ "clean-docs": "rm -rf docs/* || true",
38
+ "predocs": "npm run clean-docs",
39
+ "docs": "jsdoc -d docs -u docs-tutorials --configure jsconf.json index.js; touch docs/.nojekyll",
40
+ "predeploy-docs": "npm run docs",
41
+ "deploy-docs": "gh-pages -d docs",
42
+ "prepare": "npm run build-resources",
43
+ "build-fonts": "node scripts/build-fonts.js",
44
+ "build-demo": "node scripts/build-bundle.js demo/main.js demo/demo.js",
45
+ "build-resources": "node scripts/build-resources.js",
46
+ "build-html-test": "node scripts/build-bundle.js test/test-html/index.js test/test-html/testbuild.js",
47
+ "watch-testserver": "npx serve & npm-watch build-demo & npm-watch build-html-test & npm-watch build-resources"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/ccp-nc/crystvis-js.git"
52
+ },
53
+ "keywords": [
54
+ "Three.js",
55
+ "crystallography",
56
+ "visualisation",
57
+ "webgl"
58
+ ],
59
+ "author": "Simone Sturniolo",
60
+ "contributors": [
61
+ {
62
+ "name": "Kane Shenton",
63
+ "email": "jkshenton@gmail.com"
64
+ }
65
+ ],
66
+ "license": "MIT",
67
+ "bugs": {
68
+ "url": "https://github.com/ccp-nc/crystvis-js/issues"
69
+ },
70
+ "homepage": "https://github.com/ccp-nc/crystvis-js#readme",
71
+ "dependencies": {
72
+ "@jkshenton/three-bmfont-text": ">=3.0.4",
73
+ "buffer": "^6.0.3",
74
+ "chroma-js": "^2.4.2",
75
+ "crystcif-parse": "^0.2.9",
76
+ "isosurface": "^1.0.0",
77
+ "jquery": "^3.6.0",
78
+ "load-bmfont": "^1.4.1",
79
+ "lodash": "^4.17.21",
80
+ "mathjs": "^8.0.1",
81
+ "three": "^0.143.0",
82
+ "yargs-parser": "^21.1.1"
83
+ },
84
+ "devDependencies": {
85
+ "@babel/eslint-parser": "^7.18.9",
86
+ "chai": "^4.3.6",
87
+ "chai-almost": "^1.0.1",
88
+ "clean-jsdoc-theme": "^4.1.7",
89
+ "datauri": "^4.1.0",
90
+ "elliptic": ">=6.5.4",
91
+ "esbuild": "^0.15.5",
92
+ "eslint": "^8.22.0",
93
+ "gh-pages": "^4.0.0",
94
+ "glob": "^8.0.3",
95
+ "jpeg-js": ">=0.4.4",
96
+ "jsdoc": "^3.6.11",
97
+ "minimist": "^1.2.6",
98
+ "mocha": "^10.0.0",
99
+ "msdf-bmfont-xml": "^2.5.4",
100
+ "npm-watch": "^0.11.0",
101
+ "serve": "^14.0.1"
102
+ },
103
+ "overrides": {
104
+ "minimist": "$minimist"
105
+ }
106
+ }
@@ -0,0 +1,17 @@
1
+ import esbuild from 'esbuild';
2
+ import path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+
5
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
6
+
7
+ esbuild.build({
8
+ entryPoints: [process.argv[2]],
9
+ bundle: true,
10
+ outfile: process.argv[3],
11
+ target: [
12
+ 'chrome58',
13
+ 'firefox57',
14
+ 'safari11',
15
+ 'edge18',
16
+ ]
17
+ });
@@ -0,0 +1,43 @@
1
+ import generateBMFont from 'msdf-bmfont-xml';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import glob from 'glob';
5
+
6
+ // We update by hand whenever we want to build a new font
7
+ const fontList = [
8
+ 'fonts/Rubik/static/Rubik-Medium.ttf'
9
+ ];
10
+
11
+ const savePath = 'lib/assets/fonts';
12
+
13
+ // Clean up the destination path!
14
+ var old_files = glob.sync(path.join(savePath, '*.+(png|fnt)'));
15
+ old_files.forEach((fname, index) => {
16
+ fs.unlinkSync(fname);
17
+ });
18
+
19
+ for (var i in fontList) {
20
+ const fname = fontList[i];
21
+
22
+ generateBMFont(fname, (error, textures, font) => {
23
+
24
+ textures.forEach((texture, index) => {
25
+
26
+ var save = path.basename(texture.filename) + '.png';
27
+ save = path.join(savePath, save);
28
+
29
+ fs.writeFile(save, texture.texture, (err) => {
30
+ if (err) throw err;
31
+ });
32
+
33
+ });
34
+
35
+ var save = path.basename(font.filename);
36
+ save = path.join(savePath, save);
37
+
38
+ fs.writeFile(save, font.data, (err) => {
39
+ if (err) throw err;
40
+ });
41
+
42
+ });
43
+ }
@@ -0,0 +1,46 @@
1
+ import esbuild from 'esbuild';
2
+ import path from 'path';
3
+ import {
4
+ fileURLToPath
5
+ } from 'url';
6
+
7
+ const __dirname = path.dirname(fileURLToPath(
8
+ import.meta.url));
9
+
10
+ const toBuild = [
11
+ '../lib/assets/fonts/bmpfonts.in.js',
12
+ '../lib/shaders/index.in.js'
13
+ ];
14
+
15
+ toBuild.forEach((inputFile) => {
16
+
17
+ var outputFile = inputFile.replace('.in.js', '.js');
18
+
19
+ esbuild.build({
20
+ entryPoints: [path.join(__dirname, inputFile)],
21
+ bundle: true,
22
+ platform: 'node',
23
+ format: 'esm',
24
+ outfile: path.join(__dirname, outputFile),
25
+ loader: {
26
+ '.png': 'dataurl',
27
+ '.fnt': 'dataurl',
28
+ '.frag': 'text',
29
+ '.vert': 'text'
30
+ }
31
+ });
32
+ });
33
+
34
+ // // A special treatment for fonts.js. Needs some definitions injected
35
+ // esbuild.build({
36
+ // entryPoints: [path.join(__dirname, '../lib/assets/fonts/threebmfont.in.js')],
37
+ // bundle: true,
38
+ // inject: [path.join(__dirname, 'plugins-shim.js')], // Crude, but a necessary fix for load-bmfont
39
+ // define: {
40
+ // Buffer: 'Buffer',
41
+ // THREE: 'THREE',
42
+ // },
43
+ // platform: 'node',
44
+ // outfile: path.join(__dirname, '../lib/assets/fonts/threebmfont.js')
45
+ // });
46
+
@@ -0,0 +1,10 @@
1
+ import {
2
+ Buffer
3
+ } from 'buffer';
4
+
5
+ import * as THREE from 'three';
6
+
7
+ export {
8
+ Buffer,
9
+ THREE
10
+ };