@ccp-nc/crystvis-js 0.4.13 → 0.5.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 (141) hide show
  1. package/.eslintrc.json +0 -0
  2. package/.github/workflows/test-mocha.yml +1 -1
  3. package/.vscode/settings.json +1 -2
  4. package/LICENSE +0 -0
  5. package/README.html +0 -0
  6. package/README.md +2 -2
  7. package/demo/index.html +14 -0
  8. package/demo/main.js +12 -0
  9. package/docs/.nojekyll +0 -0
  10. package/docs-tutorials/Events.md +0 -0
  11. package/docs-tutorials/Queries.md +0 -0
  12. package/fonts/OpenSans/OFL.txt +93 -0
  13. package/fonts/OpenSans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  14. package/fonts/OpenSans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
  15. package/fonts/OpenSans/README.txt +100 -0
  16. package/fonts/OpenSans/static/OpenSans/OpenSans-Bold.ttf +0 -0
  17. package/fonts/OpenSans/static/OpenSans/OpenSans-BoldItalic.ttf +0 -0
  18. package/fonts/OpenSans/static/OpenSans/OpenSans-ExtraBold.ttf +0 -0
  19. package/fonts/OpenSans/static/OpenSans/OpenSans-ExtraBoldItalic.ttf +0 -0
  20. package/fonts/OpenSans/static/OpenSans/OpenSans-Italic.ttf +0 -0
  21. package/fonts/OpenSans/static/OpenSans/OpenSans-Light.ttf +0 -0
  22. package/fonts/OpenSans/static/OpenSans/OpenSans-LightItalic.ttf +0 -0
  23. package/fonts/OpenSans/static/OpenSans/OpenSans-Medium.ttf +0 -0
  24. package/fonts/OpenSans/static/OpenSans/OpenSans-MediumItalic.ttf +0 -0
  25. package/fonts/OpenSans/static/OpenSans/OpenSans-Regular.ttf +0 -0
  26. package/fonts/OpenSans/static/OpenSans/OpenSans-SemiBold.ttf +0 -0
  27. package/fonts/OpenSans/static/OpenSans/OpenSans-SemiBoldItalic.ttf +0 -0
  28. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Bold.ttf +0 -0
  29. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-BoldItalic.ttf +0 -0
  30. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-ExtraBold.ttf +0 -0
  31. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
  32. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Italic.ttf +0 -0
  33. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Light.ttf +0 -0
  34. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-LightItalic.ttf +0 -0
  35. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Medium.ttf +0 -0
  36. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-MediumItalic.ttf +0 -0
  37. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-Regular.ttf +0 -0
  38. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-SemiBold.ttf +0 -0
  39. package/fonts/OpenSans/static/OpenSans_Condensed/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
  40. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Bold.ttf +0 -0
  41. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
  42. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
  43. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  44. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Italic.ttf +0 -0
  45. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Light.ttf +0 -0
  46. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
  47. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Medium.ttf +0 -0
  48. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
  49. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-Regular.ttf +0 -0
  50. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
  51. package/fonts/OpenSans/static/OpenSans_SemiCondensed/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
  52. package/fonts/Rubik/OFL.txt +0 -0
  53. package/fonts/Rubik/README.txt +0 -0
  54. package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
  55. package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
  56. package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
  57. package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
  58. package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
  59. package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
  60. package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
  61. package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
  62. package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
  63. package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
  64. package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
  65. package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
  66. package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
  67. package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
  68. package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
  69. package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
  70. package/index.html +0 -0
  71. package/index.js +0 -0
  72. package/jsconf.json +0 -0
  73. package/lib/assets/fonts/OpenSans-Medium.fnt +157 -0
  74. package/lib/assets/fonts/OpenSans-Medium.png +0 -0
  75. package/lib/assets/fonts/Rubik-Medium.fnt +141 -89
  76. package/lib/assets/fonts/Rubik-Medium.png +0 -0
  77. package/lib/assets/fonts/bmpfonts.in.js +6 -1
  78. package/lib/assets/fonts/bmpfonts.js +10 -2
  79. package/lib/assets/fonts/font.js +0 -0
  80. package/lib/assets/fonts/index.js +4 -2
  81. package/lib/assets/fonts/threebmfont.js +0 -0
  82. package/lib/data.js +0 -0
  83. package/lib/formats/cell.js +26 -3
  84. package/lib/formats/cif.js +1 -1
  85. package/lib/formats/magres.js +37 -3
  86. package/lib/formats/xyz.js +7 -2
  87. package/lib/loader.js +0 -0
  88. package/lib/model.js +83 -8
  89. package/lib/modelview.js +35 -0
  90. package/lib/nmrdata.js +0 -0
  91. package/lib/primitives/atoms.js +0 -0
  92. package/lib/primitives/cell.js +25 -3
  93. package/lib/primitives/dither.js +0 -0
  94. package/lib/primitives/ellipsoid.js +29 -9
  95. package/lib/primitives/geometries.js +0 -0
  96. package/lib/primitives/isosurface.js +0 -0
  97. package/lib/primitives/shapes.js +0 -0
  98. package/lib/primitives/sprites.js +2 -2
  99. package/lib/query.js +0 -0
  100. package/lib/render.js +107 -5
  101. package/lib/selbox.js +0 -0
  102. package/lib/shaders/aura.frag +0 -0
  103. package/lib/shaders/aura.vert +0 -0
  104. package/lib/shaders/dither.frag +0 -0
  105. package/lib/shaders/dither.vert +0 -0
  106. package/lib/shaders/index.in.js +0 -0
  107. package/lib/shaders/index.js +0 -0
  108. package/lib/shaders/msdf300.frag +0 -0
  109. package/lib/shaders/msdf300.vert +0 -0
  110. package/lib/tensor.js +1 -1
  111. package/lib/utils.js +22 -1
  112. package/lib/visualizer.js +95 -4
  113. package/package.json +18 -18
  114. package/scripts/build-bundle.js +0 -0
  115. package/scripts/build-fonts.js +8 -3
  116. package/scripts/build-resources.js +0 -0
  117. package/scripts/plugins-shim.js +0 -0
  118. package/test/chemdata.js +1 -1
  119. package/test/data/CHA.cif +0 -0
  120. package/test/data/H2O.xyz +0 -0
  121. package/test/data/H2_bound.xyz +0 -0
  122. package/test/data/bohr.cell +11 -0
  123. package/test/data/ethanol.cell +0 -0
  124. package/test/data/example_single.cif +0 -0
  125. package/test/data/frac.cell +0 -0
  126. package/test/data/org.cif +0 -0
  127. package/test/data/pyridine.xyz +1 -1
  128. package/test/data/pyridine_nocell.xyz +13 -0
  129. package/test/data/si8.xyz +0 -0
  130. package/test/data/si8_noisy.xyz +10 -0
  131. package/test/loader.js +22 -1
  132. package/test/model.js +40 -9
  133. package/test/query.js +1 -1
  134. package/test/tensor.js +1 -1
  135. package/test/test-html/examples.js +0 -0
  136. package/test/test-html/index.html +0 -0
  137. package/test/test-html/index.js +35 -5
  138. package/tools/compile_colors.py +0 -0
  139. package/tools/compile_periodic.py +0 -0
  140. package/tools/ptable.json +0 -0
  141. package/tools/test +0 -0
package/lib/render.js CHANGED
@@ -21,6 +21,29 @@ import {
21
21
 
22
22
  import * as Primitives from './primitives/index.js';
23
23
 
24
+ import {
25
+ TextSprite
26
+ } from './primitives/index.js';
27
+
28
+ // themes:
29
+ const themes = {
30
+ dark: {
31
+ background: 0x000000,
32
+ foreground: 0xffffff,
33
+ highlight: 0x00ff00,
34
+ cell_line_color: 0xffffff,
35
+ label_color: 0xffffff,
36
+
37
+ },
38
+ light: {
39
+ background: 0xffffff,
40
+ foreground: 0x000000,
41
+ highlight: 0x00ff00,
42
+ cell_line_color: 0x000000,
43
+ label_color: 0x000000,
44
+ }
45
+ }
46
+
24
47
 
25
48
  class Renderer {
26
49
 
@@ -31,8 +54,9 @@ class Renderer {
31
54
  * @param {int} width Desired width for the renderer
32
55
  * @param {int} height Desired height for the renderer. If both this and width are zero, automatically
33
56
  * resizes with the container
57
+ * @param {object} options Optional parameters for the WebGLRenderer
34
58
  */
35
- constructor(target, width, height) {
59
+ constructor(target, width, height, options = {}) {
36
60
 
37
61
  // Grab the target element
38
62
  this._div = $(target);
@@ -42,8 +66,14 @@ class Renderer {
42
66
  this._h = height;
43
67
  this._updateSize();
44
68
 
69
+ // combine options with defaults
70
+ this._options = Object.assign({
71
+ antialias: true,
72
+ alpha: true,
73
+ }, options);
74
+
45
75
  // Renderer
46
- this._r = new THREE.WebGLRenderer();
76
+ this._r = new THREE.WebGLRenderer(this._options);
47
77
  this._r.autoClear = true;
48
78
  this._r.setPixelRatio(window.devicePixelRatio);
49
79
  this._r.setSize(this._w, this._h);
@@ -81,11 +111,13 @@ class Renderer {
81
111
  // Groups
82
112
  this._groups = {
83
113
  model: new THREE.Group(),
84
- primitives: new THREE.Group()
114
+ primitives: new THREE.Group(),
115
+ notifications: new THREE.Group(),
85
116
  };
86
117
 
87
118
  this._s.add(this._groups.model);
88
119
  this._s.add(this._groups.primitives);
120
+ this._s.add(this._groups.notifications);
89
121
 
90
122
  // Selection box (multiple raycast)
91
123
  this._sboxlist = [];
@@ -94,7 +126,7 @@ class Renderer {
94
126
  this._sboxhelp.selectOverCallback = this._selectBoxEnd.bind(this);
95
127
 
96
128
  // Color scheme
97
- this._cell_line_color = 0xaaaaaa;
129
+ this.theme = themes.dark;
98
130
  this._cell_x_color = 0xff0000;
99
131
  this._cell_y_color = 0x00ff00;
100
132
  this._cell_z_color = 0x0000ff;
@@ -193,6 +225,51 @@ class Renderer {
193
225
  }
194
226
  }
195
227
 
228
+ /**
229
+ * Draw list of notifications
230
+ * @param {Array} messages - List of (strings) messages to display
231
+ * @param {Object} parameters - Parameters for the messages
232
+ *
233
+ */
234
+ addNotifications(messages, parameters={}) {
235
+ // TODO: adjust position of messages when camera is rotated
236
+ // currently this is only correct when camera is looking down the z-axis
237
+ //top of message should be the bottom left corner of the canvas
238
+ var position = [this._c.left, this._c.bottom, this._c.near];
239
+ // calculate height of messages
240
+ const messages_height = 0.05 * messages.length;
241
+ // todo: this should really be the x projection of the unit cell
242
+ // rather than the length of the 0th unit cell vector
243
+ // but it works for now...
244
+ const xshift = this.getOrbitCenter().x * 2;
245
+ const yshift = 0.05 * messages_height + this.getOrbitCenter().y + 0.5;
246
+ const defaults = {
247
+ position: position,
248
+ height: messages_height,
249
+ color: this.theme.label_color,
250
+ faceCamera: true,
251
+ fixScale: true,
252
+ shift: [xshift,yshift,0.0],
253
+ onOverlay: true,
254
+ };
255
+
256
+ parameters = _.merge(defaults, parameters);
257
+
258
+ // add text sprite to scene
259
+ // Create a TextSprite to hold the message
260
+ var messageSprite = new TextSprite(messages.join('\n'), parameters);
261
+
262
+ this._groups.notifications.add(messageSprite);
263
+ }
264
+
265
+ /**
266
+ * Remove all notifications from the scene
267
+ */
268
+ clearNotifications() {
269
+ this._groups.notifications.remove(...this._groups.notifications.children);
270
+ }
271
+
272
+
196
273
  add(object, group = 'primitives') {
197
274
  if (!(this._groups[group].children.includes(object)))
198
275
  this._groups[group].add(object);
@@ -301,6 +378,11 @@ class Renderer {
301
378
  this._oc.target = p;
302
379
  }
303
380
 
381
+ getOrbitCenter() {
382
+ return this._oc.target;
383
+ }
384
+
385
+
304
386
  /**
305
387
  * Remove all currently rendered objects.
306
388
  */
@@ -362,6 +444,25 @@ class Renderer {
362
444
  this._sboxhelp.element.css({
363
445
  'opacity': o
364
446
  });
447
+ }
448
+
449
+ // themes
450
+ get theme() {
451
+ return this._theme;
452
+ }
453
+
454
+ set theme(t) {
455
+ this._theme = t;
456
+ // background color
457
+ this._r.setClearColor(t.background, 1);
458
+ // Cell color scheme
459
+ this._r._cell_line_color = t.cell_line_color;
460
+ // labels
461
+ this._label_color = t.label_color;
462
+
463
+
464
+
465
+
365
466
  }
366
467
 
367
468
  // This convenient wrapper is useful to keep the Primitives out of the Model's logic.
@@ -436,5 +537,6 @@ _addVectorField: function(points, vectors, colors, scale) {
436
537
 
437
538
 
438
539
  export {
439
- Renderer
540
+ Renderer,
541
+ themes
440
542
  };
package/lib/selbox.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/lib/tensor.js CHANGED
@@ -37,7 +37,7 @@ class TensorData {
37
37
  // Diagonalize
38
38
  var eigs = mjs.eigs(this._Msymm);
39
39
  // Sort by eigenvalue magnitude
40
- var evecs = mjs.transpose(eigs.vectors._data);
40
+ var evecs = eigs.eigenvectors.map(e => e.vector._data);
41
41
  eigs = _.zip(eigs.values._data, evecs);
42
42
  eigs = _.sortBy(eigs, function(x) {
43
43
  return x[0];
package/lib/utils.js CHANGED
@@ -163,6 +163,27 @@ function hashCode(arg) {
163
163
  return hash;
164
164
  }
165
165
 
166
+
167
+ /**
168
+ * Compare floating point numbers for equality with a given tolerance
169
+ *
170
+ * @param {float} a First number
171
+ * @param {float} b Second number
172
+ * @param {float} tol Tolerance (absolute)
173
+ *
174
+ * @return {bool} True if the numbers are equal within the tolerance
175
+ *
176
+ * TODO: could add relative tolerance as well
177
+ */
178
+ function floatEqual(a, b, tol=1e-6) {
179
+ // check for NaNs
180
+ if (a !== a || b !== b) {
181
+ return false;
182
+ }
183
+
184
+ return Math.abs(a-b) < tol;
185
+ }
186
+
166
187
  export {
167
- supercellGrid, supercellIndex, cellMatrix3, addStaticVar, shiftCpkColor, hashCode
188
+ supercellGrid, supercellIndex, cellMatrix3, addStaticVar, shiftCpkColor, hashCode, floatEqual
168
189
  }
package/lib/visualizer.js CHANGED
@@ -10,6 +10,8 @@ import * as _ from 'lodash';
10
10
  import {
11
11
  Renderer as Renderer
12
12
  } from './render.js';
13
+ // themes
14
+ import {themes} from './render.js';
13
15
  import {
14
16
  Loader as Loader
15
17
  } from './loader.js';
@@ -45,11 +47,12 @@ class CrystVis {
45
47
  * @param {int} height Window height. If both this and width are
46
48
  * set to 0, the window fits its context and
47
49
  * automatically resizes with it
50
+ * @param {Object} rendererOptions Options for the renderer
48
51
  */
49
- constructor(element, width = 0, height = 0) {
52
+ constructor(element, width = 0, height = 0, rendererOptions = {}) {
50
53
 
51
54
  // Create a renderer
52
- this._renderer = new Renderer(element, width, height);
55
+ this._renderer = new Renderer(element, width, height, rendererOptions);
53
56
  this._loader = new Loader();
54
57
 
55
58
  this._models = {};
@@ -58,6 +61,7 @@ class CrystVis {
58
61
  this._current_mname = null;
59
62
  this._displayed = null;
60
63
  this._selected = null;
64
+ this._notifications = [];
61
65
 
62
66
  // Handling events
63
67
  this._atom_click_events = {};
@@ -158,6 +162,36 @@ class CrystVis {
158
162
  }
159
163
  }
160
164
 
165
+ get notifications() {
166
+ return this._notifications;
167
+ }
168
+
169
+ set notifications(n) {
170
+ this._notifications = n;
171
+ }
172
+
173
+
174
+ /** Theme
175
+ * @type {object}
176
+ */
177
+ get theme() {
178
+ return this._renderer.theme;
179
+ }
180
+
181
+ set theme(t) {
182
+ // if t is a string, try to find the corresponding theme
183
+ // from the list of themes
184
+ if (typeof t === 'string') {
185
+ if (themes[t]) {
186
+ t = themes[t];
187
+ } else {
188
+ throw new Error('Theme ' + t + ' not found');
189
+ }
190
+ }
191
+ this._renderer.theme = t;
192
+ }
193
+
194
+
161
195
  /**
162
196
  * Set a callback function for an event where a user clicks on an atom. The
163
197
  * function should take as arguments the atom image for the clicked atom and
@@ -305,6 +339,8 @@ class CrystVis {
305
339
  * @return {Object} Names of the models we tried to load, and values of true/false for successful loading or not
306
340
  */
307
341
  loadModels(contents, format = 'cif', prefix = null, parameters = {}) {
342
+ // clear existing notifications
343
+ this.clearNotifications();
308
344
 
309
345
  parameters = _.merge(model_parameter_defaults, parameters);
310
346
 
@@ -320,6 +356,9 @@ class CrystVis {
320
356
 
321
357
  if (this._loader.status == Loader.STATUS_ERROR) {
322
358
  status[prefix] = this._loader.error_message;
359
+ // display error notification to user
360
+ this.addNotification('Error loading model: '+ prefix);
361
+ this.addNotification(this._loader.error_message);
323
362
  return status;
324
363
  }
325
364
 
@@ -336,6 +375,7 @@ class CrystVis {
336
375
  var s = structs[n];
337
376
  if (!s) {
338
377
  status[nn] = 'Model could not load properly';
378
+ this.addNotification('Model '+ nn + ' could not load properly');
339
379
  continue;
340
380
  }
341
381
  this._models[nn] = new Model(s, parameters);
@@ -352,6 +392,8 @@ class CrystVis {
352
392
  * @param {Object} parameters Loading parameters as in .loadModels()
353
393
  */
354
394
  reloadModel(name, parameters = {}) {
395
+ // clear existing notifications from scene
396
+ this.clearNotifications();
355
397
 
356
398
  if (!(name in this._models)) {
357
399
  throw 'The requested model does not exist';
@@ -382,6 +424,8 @@ class CrystVis {
382
424
  displayModel(name = null) {
383
425
 
384
426
  if (this._current_model) {
427
+ // clear notifications from previous model
428
+ this.clearNotifications();
385
429
  this.selected = this._current_model.view([]);
386
430
  this._current_model.renderer = null;
387
431
  this._current_model = null;
@@ -395,6 +439,9 @@ class CrystVis {
395
439
  }
396
440
 
397
441
  if (!(name in this._models)) {
442
+ // in case the model does not exist, reset the orbit
443
+ this._renderer.resetOrbitCenter(5,5,5);
444
+ this.addNotification('The requested model does not exist')
398
445
  throw 'The requested model does not exist';
399
446
  }
400
447
 
@@ -454,16 +501,60 @@ class CrystVis {
454
501
  this._renderer.remove(p);
455
502
  }
456
503
 
504
+ /**
505
+ * Add a notification to the list of notifications to be displayed
506
+ */
507
+ addNotification(n) {
508
+ this._notifications.push(n);
509
+ this.addNotifications();
510
+ }
511
+
512
+ /**
513
+ * Adds all notifications to the drawing
514
+ *
515
+ */
516
+ addNotifications() {
517
+ // remove displayed notifications
518
+ // (doesn't remove them from this._notifications)
519
+ this._renderer.clearNotifications();
520
+ // add full list of notifications
521
+ this._renderer.addNotifications(this._notifications);
522
+ }
523
+
524
+ /**
525
+ * Removes notifications from the drawing
526
+ */
527
+ clearNotifications() {
528
+ this._notifications = [];
529
+ this._renderer.clearNotifications();
530
+ }
531
+
457
532
  /**
458
533
  * Recover a data URL of a PNG screenshot of the current scene
459
534
  *
460
535
  * @return {String} A data URL of the PNG screenshot
461
536
  */
462
- getScreenshotData() {
537
+ getScreenshotData(transparent = true, scale_pixels = 3) {
538
+
539
+ var renderer = this._renderer;
540
+ // save current alpha and antialias settings
541
+ var old_alpha = renderer._r.getClearAlpha();
542
+ var old_PixelRatio = renderer._r.getPixelRatio();
543
+
544
+ // set new alpha and antialias settings
545
+ renderer._r.setClearAlpha(transparent ? 0 : 1);
546
+ renderer._r.setPixelRatio(scale_pixels);
547
+
463
548
  // Force a render
464
549
  this._renderer._render();
465
550
  // Grab the data from the canvas
466
- return this._renderer._r.domElement.toDataURL();
551
+ var data = renderer._r.domElement.toDataURL();
552
+
553
+ // restore old alpha and antialias settings
554
+ renderer._r.setClearAlpha(old_alpha);
555
+ renderer._r.setPixelRatio(old_PixelRatio);
556
+
557
+ return data;
467
558
  }
468
559
  }
469
560
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ccp-nc/crystvis-js",
3
- "version": "0.4.13",
3
+ "version": "0.5.0",
4
4
  "description": "A Three.js based crystallographic visualisation tool",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -69,36 +69,36 @@
69
69
  },
70
70
  "homepage": "https://github.com/ccp-nc/crystvis-js#readme",
71
71
  "dependencies": {
72
- "@jkshenton/three-bmfont-text": ">=3.0.4",
72
+ "@jkshenton/three-bmfont-text": "^3.0.5",
73
73
  "buffer": "^6.0.3",
74
74
  "chroma-js": "^2.4.2",
75
- "crystcif-parse": "^0.2.9",
75
+ "@ccp-nc/crystcif-parse": "^0.2.9",
76
76
  "isosurface": "^1.0.0",
77
- "jquery": "^3.6.0",
77
+ "jquery": "^3.7.1",
78
78
  "load-bmfont": "^1.4.1",
79
79
  "lodash": "^4.17.21",
80
- "mathjs": "^8.0.1",
81
- "three": "^0.143.0",
80
+ "mathjs": "^12.3.0",
81
+ "three": "^0.137.0",
82
82
  "yargs-parser": "^21.1.1"
83
83
  },
84
84
  "devDependencies": {
85
- "@babel/eslint-parser": "^7.18.9",
86
- "chai": "^4.3.6",
85
+ "@babel/eslint-parser": "^7.23.3",
86
+ "chai": "^5.0.0",
87
87
  "chai-almost": "^1.0.1",
88
- "clean-jsdoc-theme": "^4.1.7",
88
+ "clean-jsdoc-theme": "^4.2.17",
89
89
  "datauri": "^4.1.0",
90
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",
91
+ "esbuild": "^0.19.11",
92
+ "eslint": "^8.56.0",
93
+ "gh-pages": "^6.1.1",
94
+ "glob": "^10.3.10",
95
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",
96
+ "jsdoc": "^4.0.2",
97
+ "minimist": "^1.2.8",
98
+ "mocha": "^10.2.0",
99
+ "msdf-bmfont-xml": "^2.7.0",
100
100
  "npm-watch": "^0.11.0",
101
- "serve": "^14.0.1"
101
+ "serve": "^14.2.1"
102
102
  },
103
103
  "overrides": {
104
104
  "minimist": "$minimist"
File without changes
@@ -1,13 +1,18 @@
1
1
  import generateBMFont from 'msdf-bmfont-xml';
2
2
  import fs from 'fs';
3
3
  import path from 'path';
4
- import glob from 'glob';
4
+ import * as glob from 'glob';
5
+
5
6
 
6
7
  // We update by hand whenever we want to build a new font
7
8
  const fontList = [
8
- 'fonts/Rubik/static/Rubik-Medium.ttf'
9
+ 'fonts/Rubik/static/Rubik-Medium.ttf',
10
+ 'fonts/OpenSans/static/OpenSans/OpenSans-Medium.ttf'
9
11
  ];
10
12
 
13
+ const defaultCharset = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ αβγδεζηθικλμνξοπρστυφχψωΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩŰ".split('');
14
+
15
+
11
16
  const savePath = 'lib/assets/fonts';
12
17
 
13
18
  // Clean up the destination path!
@@ -19,7 +24,7 @@ old_files.forEach((fname, index) => {
19
24
  for (var i in fontList) {
20
25
  const fname = fontList[i];
21
26
 
22
- generateBMFont(fname, (error, textures, font) => {
27
+ generateBMFont(fname, {charset: defaultCharset}, (error, textures, font) => {
23
28
 
24
29
  textures.forEach((texture, index) => {
25
30
 
File without changes
File without changes
package/test/chemdata.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- import chai from 'chai'
3
+ import * as chai from 'chai';
4
4
  import chaiAlmost from 'chai-almost'
5
5
 
6
6
  import {
package/test/data/CHA.cif CHANGED
File without changes
package/test/data/H2O.xyz CHANGED
File without changes
File without changes
@@ -0,0 +1,11 @@
1
+ %block LATTICE_ABC
2
+ bohr
3
+ 7 7 7
4
+ 90.0000 90.0000 90.0000
5
+ %endblock LATTICE_ABC
6
+
7
+ %block POSITIONS_ABS
8
+ bohr
9
+ H 0 0 0
10
+ He 3.5 0 0
11
+ %endblock POSITIONS_ABS
File without changes
File without changes
File without changes
package/test/data/org.cif CHANGED
File without changes
@@ -1,5 +1,5 @@
1
1
  11
2
- Pyridine molecule (source: Wikipedia)
2
+ Lattice="10 0 0 0 10 0 0 0 10" Properties=species:S:1:pos:R:3 pbc="T T T" Label="Pyridine molecule (source: Wikipedia)"
3
3
  C -0.180226841 0.360945118 -1.120304970
4
4
  C -0.180226841 1.559292118 -0.407860970
5
5
  C -0.180226841 1.503191118 0.986935030
@@ -0,0 +1,13 @@
1
+ 11
2
+ Pyridine molecule (source: Wikipedia)
3
+ C -0.180226841 0.360945118 -1.120304970
4
+ C -0.180226841 1.559292118 -0.407860970
5
+ C -0.180226841 1.503191118 0.986935030
6
+ N -0.180226841 0.360945118 1.685965030
7
+ C -0.180226841 -0.781300882 0.986935030
8
+ C -0.180226841 -0.837401882 -0.407860970
9
+ H -0.180226841 0.360945118 -2.206546970
10
+ H -0.180226841 2.517950118 -0.917077970
11
+ H -0.180226841 2.421289118 1.572099030
12
+ H -0.180226841 -1.699398882 1.572099030
13
+ H -0.180226841 -1.796059882 -0.917077970
package/test/data/si8.xyz CHANGED
File without changes
@@ -0,0 +1,10 @@
1
+ 8
2
+ Lattice="5.47545112629462 4.96819156878786e-36 1.10608096941637e-36 4.96819156878786e-36 5.47545112629462 -3.12695835139248e-36 1.10608096941637e-36 -3.12695835139248e-36 5.47545112629462" Properties=species:S:1:pos:R:3:initial_magmoms:R:1:castep_labels:S:1 pbc="T T T"
3
+ Si 0.00000000 0.00000000 0.00000000 0.00000000 NULL
4
+ Si 4.10658834 4.10658834 1.36886278 0.00000000 NULL
5
+ Si 2.73772556 0.00000000 2.73772556 0.00000000 NULL
6
+ Si 4.10658834 1.36886278 4.10658834 0.00000000 NULL
7
+ Si 0.00000000 2.73772556 2.73772556 0.00000000 NULL
8
+ Si 1.36886278 1.36886278 1.36886278 0.00000000 NULL
9
+ Si 1.36886278 4.10658834 4.10658834 0.00000000 NULL
10
+ Si 2.73772556 2.73772556 -0.00000000 0.00000000 NULL
package/test/loader.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- import chai from 'chai'
3
+ import * as chai from 'chai';
4
4
  import chaiAlmost from 'chai-almost'
5
5
 
6
6
  import fs from 'fs'
@@ -55,6 +55,20 @@ describe('#loading', function() {
55
55
  [1.7848106706548383, 1.959874486240255, 12.914460443940394]
56
56
  ]);
57
57
  });
58
+ it ('should load a noisy .xyz file', function() {
59
+
60
+ var loader = new Loader();
61
+
62
+ var xyz = fs.readFileSync(path.join(__dirname, 'data', 'si8_noisy.xyz'), "utf8");
63
+ var a = loader.load(xyz, 'xyz')['xyz'];
64
+
65
+ expect(a.get_cell()).to.deep.almost.equal([
66
+ [5.475, 0, 0],
67
+ [0, 5.475, 0],
68
+ [0, 0, 5.475]
69
+ ]);
70
+ });
71
+
58
72
  it('should load properly a Magres file', function() {
59
73
 
60
74
  var loader = new Loader();
@@ -103,5 +117,12 @@ describe('#loading', function() {
103
117
  expect(a.get_cell()).to.almost.deep.equal([[10.0, 0, 0], [10.0, 10.0, 0], [0, 0, 10.0]]);
104
118
  expect(a.get_positions()[0]).to.almost.deep.equal([10.0, 5.0, 5.0]);
105
119
 
120
+
121
+ // Test an example with ABC lattice and ABS positions but with bohr units
122
+ cell = fs.readFileSync(path.join(__dirname, 'data', 'bohr.cell'), "utf8");
123
+ a = loader.load(cell, 'cell')['cell'];
124
+
125
+ expect(a.get_cell()).to.almost.deep.equal([[3.7042404756, 0, 0], [0, 3.7042404756, 0], [0, 0, 3.7042404756]]);
126
+ expect(a.get_positions()[1]).to.almost.deep.equal([1.8521202378, 0.0, 0.0]);
106
127
  });
107
128
  });