@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.
- package/.eslintrc.json +16 -0
- package/.github/workflows/test-mocha.yml +30 -0
- package/.vscode/settings.json +4 -0
- package/LICENSE +21 -0
- package/README.html +1127 -0
- package/README.md +76 -0
- package/demo/demo.css +30 -0
- package/demo/index.html +76 -0
- package/demo/main.js +143 -0
- package/docs/.nojekyll +0 -0
- package/docs-tutorials/Events.md +57 -0
- package/docs-tutorials/Queries.md +50 -0
- package/fonts/Rubik/OFL.txt +93 -0
- package/fonts/Rubik/README.txt +77 -0
- package/fonts/Rubik/Rubik-Italic-VariableFont_wght.ttf +0 -0
- package/fonts/Rubik/Rubik-VariableFont_wght.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Black.ttf +0 -0
- package/fonts/Rubik/static/Rubik-BlackItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Bold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-BoldItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-ExtraBold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-ExtraBoldItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Italic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Light.ttf +0 -0
- package/fonts/Rubik/static/Rubik-LightItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Medium.ttf +0 -0
- package/fonts/Rubik/static/Rubik-MediumItalic.ttf +0 -0
- package/fonts/Rubik/static/Rubik-Regular.ttf +0 -0
- package/fonts/Rubik/static/Rubik-SemiBold.ttf +0 -0
- package/fonts/Rubik/static/Rubik-SemiBoldItalic.ttf +0 -0
- package/index.html +25 -0
- package/index.js +11 -0
- package/jsconf.json +14 -0
- package/lib/assets/fonts/Rubik-Medium.fnt +297 -0
- package/lib/assets/fonts/Rubik-Medium.png +0 -0
- package/lib/assets/fonts/bmpfonts.in.js +16 -0
- package/lib/assets/fonts/bmpfonts.js +9 -0
- package/lib/assets/fonts/font.js +82 -0
- package/lib/assets/fonts/index.js +14 -0
- package/lib/assets/fonts/threebmfont.js +28 -0
- package/lib/data.js +125 -0
- package/lib/formats/cell.js +114 -0
- package/lib/formats/cif.js +22 -0
- package/lib/formats/magres.js +337 -0
- package/lib/formats/xyz.js +124 -0
- package/lib/loader.js +87 -0
- package/lib/model.js +2076 -0
- package/lib/modelview.js +382 -0
- package/lib/nmrdata.js +2898 -0
- package/lib/orbit.js +1233 -0
- package/lib/primitives/atoms.js +261 -0
- package/lib/primitives/cell.js +160 -0
- package/lib/primitives/dither.js +156 -0
- package/lib/primitives/ellipsoid.js +183 -0
- package/lib/primitives/geometries.js +20 -0
- package/lib/primitives/index.js +48 -0
- package/lib/primitives/isosurface.js +171 -0
- package/lib/primitives/shapes.js +100 -0
- package/lib/primitives/sprites.js +172 -0
- package/lib/query.js +158 -0
- package/lib/render.js +440 -0
- package/lib/selbox.js +361 -0
- package/lib/shaders/aura.frag +26 -0
- package/lib/shaders/aura.vert +37 -0
- package/lib/shaders/dither.frag +42 -0
- package/lib/shaders/dither.vert +8 -0
- package/lib/shaders/index.in.js +17 -0
- package/lib/shaders/index.js +25 -0
- package/lib/shaders/msdf300.frag +25 -0
- package/lib/shaders/msdf300.vert +45 -0
- package/lib/tensor.js +227 -0
- package/lib/utils.js +168 -0
- package/lib/visualizer.js +480 -0
- package/package.json +106 -0
- package/scripts/build-bundle.js +17 -0
- package/scripts/build-fonts.js +43 -0
- package/scripts/build-resources.js +46 -0
- package/scripts/plugins-shim.js +10 -0
- package/test/chemdata.js +69 -0
- package/test/data/CHA.cif +74 -0
- package/test/data/H2O.xyz +8 -0
- package/test/data/H2_bound.xyz +4 -0
- package/test/data/ethanol.cell +25 -0
- package/test/data/ethanol.magres +238 -0
- package/test/data/example_single.cif +789 -0
- package/test/data/frac.cell +8 -0
- package/test/data/org.cif +427 -0
- package/test/data/pyridine.xyz +13 -0
- package/test/data/si8.xyz +10 -0
- package/test/loader.js +107 -0
- package/test/model.js +368 -0
- package/test/query.js +135 -0
- package/test/tensor.js +133 -0
- package/test/test-html/examples.js +1485 -0
- package/test/test-html/index.html +33 -0
- package/test/test-html/index.js +279 -0
- package/tools/compile_colors.py +120 -0
- package/tools/compile_periodic.py +96 -0
- package/tools/ptable.json +497 -0
- package/tools/test +5844 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# crystvis-js
|
|
2
|
+
|
|
3
|
+
A [Three.js](https://threejs.org/) based crystallographic visualisation tool. It reads multiple file formats and renders them with WebGL to a `canvas` element, allowing the user to interact with them. A few of the key functionality:
|
|
4
|
+
|
|
5
|
+
* visualize popular file formats as ball-and-stick structures, easily embedded within a webpage, with orbit mouse control for rotation and zooming;
|
|
6
|
+
* interactive visualisation responsive to user clicks via customizable callbacks;
|
|
7
|
+
* high definition text labels;
|
|
8
|
+
* advanced searching and selection functions to interact with specific subset of atoms (select by proximity, bonding, species and more);
|
|
9
|
+
* smart visualisation of molecular crystal: reconstruct full molecules across the periodic boundary;
|
|
10
|
+
* compute and display isosurfaces from volumetric data;
|
|
11
|
+
* visualize tensor data as ellipsoids centred on atoms.
|
|
12
|
+
|
|
13
|
+
### Supported formats
|
|
14
|
+
|
|
15
|
+
The currently supported file formats are the following:
|
|
16
|
+
|
|
17
|
+
* **CIF**, using [crystcif-parse](https://github.com/stur86/crystcif-parse);
|
|
18
|
+
* **XYZ**, including Extended XYZ such as the one written by the [Atomic Simulation Environment](https://wiki.fysik.dtu.dk/ase/);
|
|
19
|
+
* **CELL**, input file supported by the DFT package [CASTEP](http://www.castep.org/);
|
|
20
|
+
* **Magres**, output file format for simulated NMR parameters used by CASTEP and Quantum Espresso and developed by the [CCP for NMR Crystallography](https://www.ccpnc.ac.uk/).
|
|
21
|
+
|
|
22
|
+
### Getting started
|
|
23
|
+
|
|
24
|
+
In order to install `crystvis-js`, simply use the Node Package Manager:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install crystvis-js --save
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
You can then create a visualizer for your webpage by simply importing and instantiating it:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import CrystVis from 'crystvis-js';
|
|
34
|
+
|
|
35
|
+
const visualizer = CrystVis('#target-id', 800, 600)
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
will create an 800x600 canvas with the visualizer inside the element specified by the given selector. To load a model, simply load the contents of your file as a text string and then pass them to the visualizer's `loadModels` method:
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
var loaded = visualizer.loadModels(contents);
|
|
42
|
+
console.log('Models loaded: ', loaded);
|
|
43
|
+
visualizer.displayModel(loaded[0])
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Preparing for development
|
|
47
|
+
|
|
48
|
+
If you want to develop for crystvis-js, you should follow these steps:
|
|
49
|
+
|
|
50
|
+
* fork the repository
|
|
51
|
+
* clone the forked repository locally to your system
|
|
52
|
+
* install all the required packages, *including the development dependencies*, with `npm install --production=false`
|
|
53
|
+
|
|
54
|
+
You're then ready to develop. In particular you can use:
|
|
55
|
+
|
|
56
|
+
* `npm test` to run with Mocha the suite of tests found in `./test`
|
|
57
|
+
* `npm start` to start a server that includes the in-browser tests from `./test/test-html` as well as the demo from `./demo`
|
|
58
|
+
* `npm run docs` to compile the documents
|
|
59
|
+
* `npm run deploy-docs` to compile the documents and then deploy them to the `gh-pages` branch of your repository
|
|
60
|
+
|
|
61
|
+
#### Fonts and shaders
|
|
62
|
+
|
|
63
|
+
Some additional steps are necessary when dealing with fonts and shaders. You generally shouldn't worry about these when working
|
|
64
|
+
with most of the code, but in some special cases it might be necessary to do this.
|
|
65
|
+
|
|
66
|
+
Fonts in crystvis-js need to be translated to a bitmap format to be usable. In other words, a regular font format (like a TTF file)
|
|
67
|
+
must be rendered into a bitmap texture and a table of coordinates designating each letter to then be used in graphical rendering. This operation
|
|
68
|
+
relies on the library `msdf-bmfont-xml` and is executed by running the command `npm run build-fonts`. The original fonts are found in
|
|
69
|
+
the `./fonts` folder, and they get rendered to `./lib/assets/fonts`. This command needs only to be rerun *if the TTF files change*.
|
|
70
|
+
|
|
71
|
+
Shaders are provided as `.frag` and `.vert` files. Both shaders and font textures need to baked directly into the JavaScript files in order to be
|
|
72
|
+
included in the final build. Since ESBuild (the package used to build crystvis-js) has a hard time dealing with them in the final pass, they get
|
|
73
|
+
pre-baked with an additional step that only needs to be repeated whenever either of them changes. This consists of taking "template" JS files (for
|
|
74
|
+
shaders it's `./lib/shaders/index.in.js`, for fonts `./lib/assets/fonts/bmpfonts.in.js`) and rebuilding them into final files with the
|
|
75
|
+
assets imported in data URL form. The script to do this is `npm run build-resources`. This command only needs to be rerun *if the fonts were rebuilt, if the shader
|
|
76
|
+
code was edited, or if any of the two template files was changed*.
|
package/demo/demo.css
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#main-app {
|
|
2
|
+
position: relative;
|
|
3
|
+
background-color: #002030;
|
|
4
|
+
width: 40vw;
|
|
5
|
+
height: 60vh;
|
|
6
|
+
|
|
7
|
+
color: white;
|
|
8
|
+
font-size: 30pt;
|
|
9
|
+
font-weight: bold;
|
|
10
|
+
font-family: sans-serif;
|
|
11
|
+
text-align: center;
|
|
12
|
+
line-height: 30vh;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
#main-app canvas {
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: 0;
|
|
18
|
+
left: 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#colorgrid {
|
|
22
|
+
display: grid;
|
|
23
|
+
grid-template-rows: repeat(10, 1fr);
|
|
24
|
+
grid-template-columns: repeat(30, 1fr);
|
|
25
|
+
|
|
26
|
+
width: 300px;
|
|
27
|
+
height: 300px;
|
|
28
|
+
|
|
29
|
+
background-color: #000000;
|
|
30
|
+
}
|
package/demo/index.html
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<title></title>
|
|
7
|
+
<link rel="stylesheet" href="demo.css">
|
|
8
|
+
|
|
9
|
+
<script src="demo.js" type="text/javascript" charset="utf-8" async defer></script>
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
|
|
13
|
+
<div style="width: 100%; height: 100%">
|
|
14
|
+
|
|
15
|
+
<div style="float: left" id="main-app">
|
|
16
|
+
Loading...
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div style="float: right; width: 30%">
|
|
20
|
+
<table>
|
|
21
|
+
<caption>Input controls</caption>
|
|
22
|
+
<tbody>
|
|
23
|
+
<tr>
|
|
24
|
+
<td>
|
|
25
|
+
<input id="file-load" type="file" value="Load file">
|
|
26
|
+
</td>
|
|
27
|
+
<td>
|
|
28
|
+
Supercell:
|
|
29
|
+
<input id="scell-x" type="text" size="3">
|
|
30
|
+
<input id="scell-y" type="text" size="3">
|
|
31
|
+
<input id="scell-z" type="text" size="3">
|
|
32
|
+
</td>
|
|
33
|
+
</tr>
|
|
34
|
+
<tr>
|
|
35
|
+
<td>
|
|
36
|
+
<input type="button" name="" value="Load file" onclick="loadFile()">
|
|
37
|
+
</td>
|
|
38
|
+
<td>
|
|
39
|
+
<input id="molcryst-check" type="checkbox" name="" value="" placeholder="">Load as molecular crystal
|
|
40
|
+
</td>
|
|
41
|
+
</tr>
|
|
42
|
+
<tr>
|
|
43
|
+
<td>
|
|
44
|
+
<input type="button" name="" value="Show unit cell" onclick="changeDisplayed({'cell': [[0,0,0]]})">
|
|
45
|
+
</td>
|
|
46
|
+
<td>
|
|
47
|
+
<input type="button" name="" value="Show 5 Ang sphere" onclick="changeDisplayed({'sphere': [[0,0,0], 5.0]})">
|
|
48
|
+
</td>
|
|
49
|
+
</tr>
|
|
50
|
+
<tr>
|
|
51
|
+
<td colspan="" rowspan="" headers="">
|
|
52
|
+
<input id="label-check" type="checkbox" name="" value="false" onchange="changeLabels()">Show labels
|
|
53
|
+
</td>
|
|
54
|
+
<td colspan="" rowspan="" headers="">
|
|
55
|
+
<input id="ellipsoid-check" type="checkbox" name="" value="false" onchange="changeEllipsoids()">Show ellipsoids
|
|
56
|
+
</td>
|
|
57
|
+
</tr>
|
|
58
|
+
<tr>
|
|
59
|
+
<td>
|
|
60
|
+
<input id="isosurf-check" type="checkbox" name="" value="false" onchange="changeIsosurface()">Show isosurface
|
|
61
|
+
</td>
|
|
62
|
+
<td>
|
|
63
|
+
<input type="text" id="vdw-f" size="5" value="1.0"> Van der Waals scaling
|
|
64
|
+
</td>
|
|
65
|
+
</tr>
|
|
66
|
+
</tbody>
|
|
67
|
+
</table>
|
|
68
|
+
<div id='colorgrid'>
|
|
69
|
+
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
</body>
|
|
76
|
+
</html>
|
package/demo/main.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CrystVis = require('../lib/visualizer.js').CrystVis;
|
|
4
|
+
const Primitives = require('../lib/primitives/index.js');
|
|
5
|
+
|
|
6
|
+
const shiftCpkColor = require('../lib/utils').shiftCpkColor;
|
|
7
|
+
|
|
8
|
+
var visualizer = new CrystVis('#main-app', 0, 0);
|
|
9
|
+
visualizer.highlight_selected = true;
|
|
10
|
+
|
|
11
|
+
// Generate color grid (for testing shiftCpkColor)
|
|
12
|
+
const gridEl = document.getElementById('colorgrid');
|
|
13
|
+
const gridSize = 10;
|
|
14
|
+
|
|
15
|
+
function int2hex(c) {
|
|
16
|
+
c = c.toString(16);
|
|
17
|
+
return '0'.repeat(6-c.length) + c;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < gridSize; ++i) {
|
|
21
|
+
for (let j = 0; j < gridSize; ++j) {
|
|
22
|
+
|
|
23
|
+
const hue = parseInt(j/gridSize*360);
|
|
24
|
+
const light = parseInt(i/(gridSize-1)*100);
|
|
25
|
+
const cbase = `hsl(${hue}, 100%, ${light}%)`;
|
|
26
|
+
const cplus = shiftCpkColor(cbase, 1.0);
|
|
27
|
+
const cminus = shiftCpkColor(cbase, -1.0);
|
|
28
|
+
|
|
29
|
+
let el = document.createElement('div');
|
|
30
|
+
el.style['background-color'] = '#' + int2hex(cminus);
|
|
31
|
+
gridEl.append(el);
|
|
32
|
+
|
|
33
|
+
el = document.createElement('div');
|
|
34
|
+
el.style['background-color'] = cbase;
|
|
35
|
+
gridEl.append(el);
|
|
36
|
+
|
|
37
|
+
el = document.createElement('div');
|
|
38
|
+
el.style['background-color'] = '#' + int2hex(cplus);
|
|
39
|
+
gridEl.append(el);
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
window.loadFile = function() {
|
|
45
|
+
var file = document.getElementById('file-load').files[0];
|
|
46
|
+
var reader = new FileReader();
|
|
47
|
+
var extension = file.name.split('.').pop();
|
|
48
|
+
|
|
49
|
+
var sx = parseInt(document.getElementById("scell-x").value) || 1;
|
|
50
|
+
var sy = parseInt(document.getElementById("scell-y").value) || 1;
|
|
51
|
+
var sz = parseInt(document.getElementById("scell-z").value) || 1;
|
|
52
|
+
|
|
53
|
+
var vdwf = parseFloat(document.getElementById("vdw-f").value) || 1;
|
|
54
|
+
|
|
55
|
+
reader.readAsText(file);
|
|
56
|
+
reader.onload = function() {
|
|
57
|
+
var mcryst = document.getElementById('molcryst-check').checked;
|
|
58
|
+
var name = file.name.split('.')[0];
|
|
59
|
+
var loaded = visualizer.loadModels(reader.result, extension, name, {
|
|
60
|
+
supercell: [sx, sy, sz],
|
|
61
|
+
molecularCrystal: mcryst,
|
|
62
|
+
vdwScaling: vdwf
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
visualizer.displayModel(Object.keys(loaded)[0]);
|
|
66
|
+
visualizer.displayed = visualizer.model.find({
|
|
67
|
+
'all': []
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
window.changeDisplayed = function(query) {
|
|
74
|
+
var select = visualizer.model.find(query);
|
|
75
|
+
visualizer.displayed = select;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
window.changeLabels = function() {
|
|
79
|
+
var val = document.getElementById('label-check').checked;
|
|
80
|
+
if (val) {
|
|
81
|
+
visualizer.displayed.addLabels((a, i) => (a.crystLabel), 'labels', (a, i) => ({
|
|
82
|
+
shift: [1.2*a.radius, 0, 0]
|
|
83
|
+
}));
|
|
84
|
+
} else {
|
|
85
|
+
visualizer.displayed.removeLabels('labels');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
window.changeEllipsoids = function() {
|
|
90
|
+
var val = document.getElementById('ellipsoid-check').checked;
|
|
91
|
+
if (val) {
|
|
92
|
+
visualizer.displayed.find({
|
|
93
|
+
'elements': 'H'
|
|
94
|
+
}).addEllipsoids((a) => {
|
|
95
|
+
return a.getArrayValue('ms');
|
|
96
|
+
}, 'ms', {
|
|
97
|
+
scalingFactor: 0.05,
|
|
98
|
+
opacity: 0.2
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
} else {
|
|
102
|
+
visualizer.displayed.removeEllipsoids('ms');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
var isosurface = null;
|
|
107
|
+
window.changeIsosurface = function() {
|
|
108
|
+
var val = document.getElementById('isosurf-check').checked;
|
|
109
|
+
|
|
110
|
+
// Create the data
|
|
111
|
+
var field = [];
|
|
112
|
+
for (let x = 0; x < 30; x += 1) {
|
|
113
|
+
field.push([]);
|
|
114
|
+
for (let y = 0; y < 30; y += 1) {
|
|
115
|
+
field[x].push([]);
|
|
116
|
+
for (let z = 0; z < 30; z += 1) {
|
|
117
|
+
var r = Math.pow(x-15, 2);
|
|
118
|
+
r += Math.pow(y-15, 2);
|
|
119
|
+
r += Math.pow(z-15, 2);
|
|
120
|
+
r = Math.sqrt(r);
|
|
121
|
+
var phi = Math.acos((z-15)/r);
|
|
122
|
+
field[x][y].push(r-Math.cos(3*phi)*0.2);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
if (val) {
|
|
129
|
+
var cell = visualizer.model.cell;
|
|
130
|
+
isosurface = new Primitives.IsosurfaceMesh(field, 7.0, cell,
|
|
131
|
+
{
|
|
132
|
+
opacityMode: Primitives.IsosurfaceMesh.RENDER_WFRAME,
|
|
133
|
+
isoMethod: Primitives.IsosurfaceMesh.ISO_SURFACE_NETS
|
|
134
|
+
});
|
|
135
|
+
visualizer.addPrimitive(isosurface);
|
|
136
|
+
isosurface.color = '#ff0000';
|
|
137
|
+
} else {
|
|
138
|
+
if (isosurface) {
|
|
139
|
+
visualizer.removePrimitive(isosurface);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
}
|
package/docs/.nojekyll
ADDED
|
File without changes
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
User interactions with a model in CrystVis-js can be customised through the definition of callbacks for *events*. This means it's possible to bind arbitrary JavaScript code
|
|
2
|
+
to the various ways in which a user can click on an atom in the model. To do this, one needs to use the `.onAtomClick()` method of a `CrystVis` object, as well as its flags.
|
|
3
|
+
|
|
4
|
+
### Defining an event
|
|
5
|
+
|
|
6
|
+
A custom event can be set by defining a callback function, then assigning that function to a specific click event. Here is an example:
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
function myCallback(atom, event) {
|
|
10
|
+
alert(atom.element);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
visualizer.onAtomClick(myCallback, CrystVis.LEFT_CLICK)
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
This code will result in binding a function that causes a popup to show with the chemical symbol of an atom's element whenever you left click on one.
|
|
17
|
+
|
|
18
|
+
### Flags
|
|
19
|
+
|
|
20
|
+
Which event a callback should be bound to is defined by the flags passed as the second argument to `.onAtomClick()`. These are the available flags:
|
|
21
|
+
|
|
22
|
+
* `CrystVis.LEFT_CLICK`
|
|
23
|
+
* `CrystVis.RIGHT_CLICK`
|
|
24
|
+
* `CrystVis.MIDDLE_CLICK`
|
|
25
|
+
* `CrystVis.CTRL_BUTTON`
|
|
26
|
+
* `CrystVis.ALT_BUTTON`
|
|
27
|
+
* `CrystVis.SHIFT_BUTTON`
|
|
28
|
+
* `CrystVis.CMD_BUTTON`
|
|
29
|
+
|
|
30
|
+
Note that `CMD_BUTTON` is only used on Macs and equivalent to `CTRL_BUTTON` on other machines. These are bit flags, so they can be combined with addition or bitwise operators. For
|
|
31
|
+
example, `CrystVis.LEFT_CLICK + CrystVis.SHIFT_BUTTON` represents a click with the shift key down. Each combinations of flags can only hold one callback function; if `null` is passed
|
|
32
|
+
instead of a callback, default behaviour is restored.
|
|
33
|
+
|
|
34
|
+
### Default behaviour
|
|
35
|
+
|
|
36
|
+
Most events by default are bound to nothing, mean, nothing will happen unless you define a specific behaviour for them. There are only three exceptions to this:
|
|
37
|
+
|
|
38
|
+
* `CrystVis.LEFT_CLICK` defaults to selecting the clicked atom
|
|
39
|
+
* `CrystVis.LEFT_CLICK + CrystVis.SHIFT_BUTTON` defaults to adding the clicked atom to selection
|
|
40
|
+
* `CrystVis.LEFT_CLICK + CrystVis.CTRL_BUTTON` defaults to switching the clicked atom in or out of the selection
|
|
41
|
+
|
|
42
|
+
To best see how the selection changes, set `.highlightSelected = true`.
|
|
43
|
+
|
|
44
|
+
### Box selection
|
|
45
|
+
|
|
46
|
+
In addition to the various events described above, there is a special behaviour. Clicking while pressing Shift on a point that does *not* have an atom allows the user to drag
|
|
47
|
+
a box around multiple atoms, for example to select them in group. This behaviour can also be customized, by setting a callback with the method `.onAtomBox()`. Here is an example:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
function boxCallback(atomview) {
|
|
51
|
+
alert(atomview.map((atom) => atom.element));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
visualizer.onAtomBox(boxCallback)
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
that will create an alert popup with a list of all the elements in the selected box.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
In CrystVis-js, it's possible to use the `.find()` method in `Model` and `ModelView` objects to retrieve atoms based on various search criteria. The `.find()` method takes as argument a *query*; these queries are structured in a way that's inspired by queries used for example in the MongoDB interface. It's worth taking a minute to learn how they work.
|
|
2
|
+
|
|
3
|
+
### Basic structure of a query
|
|
4
|
+
|
|
5
|
+
A query passed to the `.find()` method has to be an object. Typically, a query unit is structured as follows:
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
var query = {
|
|
9
|
+
"query_name": ["argument_1", "argument_2", ...]
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
where the appropriate actual name and arguments of course must be replaced. For example, one might use
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
var H_atoms = model.find({
|
|
17
|
+
"elements": ["H"]
|
|
18
|
+
})
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
to identify all hydrogen atoms within the model. The functions accepted for queries by a model are the following:
|
|
22
|
+
|
|
23
|
+
* `all` (no arguments): return all atoms in the model
|
|
24
|
+
* `indices` (`indices`): return all atoms with the given index or Array of indices
|
|
25
|
+
* `elements` (`elems`): return all atoms with the given element or one of an Array of elements
|
|
26
|
+
* `cell` (`ijk`): return atoms within the cell with indices i, j and k
|
|
27
|
+
* `box` (`x0`, `x1`): return atoms inside a box defined by two corners (points or atoms)
|
|
28
|
+
* `sphere` (`x0`, `r`): return atoms inside a sphere defined by a center (point or atom) and a radius
|
|
29
|
+
* `bonded` (`atoms`, `distance`, `exact`): return atoms within a certain number of bonds ("distance") from one or more atoms. For example, asking for all atoms within one bond from the oxygen in a water molecule will return the whole molecule. If "exact" is set to true instead, only atoms at the exact distance will be returned. In the water molecule example, this would return only the hydrogens
|
|
30
|
+
* `molecule` (`atoms`): return all atoms belonging to the same molecule as one of the atoms passed as argument
|
|
31
|
+
|
|
32
|
+
### Boolean operators
|
|
33
|
+
|
|
34
|
+
In addition to the simple functions described above, queries accept boolean operators that can be used to build more complex ones. For example one could use this query:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
var query = {
|
|
38
|
+
"$and": [{
|
|
39
|
+
"elements": [["H", "C"]]
|
|
40
|
+
}, {
|
|
41
|
+
"sphere": [[0, 0, 0], 4.0]
|
|
42
|
+
}]
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
to retrieve all atoms of either hydrogen or carbon located within a radius of 4 Angstroms from the origin of the cell. A boolean operator takes more queries as arguments, which means they can be nested further for more complex searches. The accepted boolean operators are the following:
|
|
47
|
+
|
|
48
|
+
* `$and` (`query_1`, `query_2`, ...): returns the intersection of all the passed queries
|
|
49
|
+
* `$or` (`query_1`, `query_2`, ...): returns the union of all the passed queries
|
|
50
|
+
* `$xor` (`query_1`, `query_2`, ...): return the exclusive OR of all queries (in other words, any atom that is returned by only one query but no other)
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
Copyright 2015 The Rubik Project Authors (https://github.com/googlefonts/rubik),
|
|
2
|
+
|
|
3
|
+
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
|
4
|
+
This license is copied below, and is also available with a FAQ at:
|
|
5
|
+
http://scripts.sil.org/OFL
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
-----------------------------------------------------------
|
|
9
|
+
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
|
10
|
+
-----------------------------------------------------------
|
|
11
|
+
|
|
12
|
+
PREAMBLE
|
|
13
|
+
The goals of the Open Font License (OFL) are to stimulate worldwide
|
|
14
|
+
development of collaborative font projects, to support the font creation
|
|
15
|
+
efforts of academic and linguistic communities, and to provide a free and
|
|
16
|
+
open framework in which fonts may be shared and improved in partnership
|
|
17
|
+
with others.
|
|
18
|
+
|
|
19
|
+
The OFL allows the licensed fonts to be used, studied, modified and
|
|
20
|
+
redistributed freely as long as they are not sold by themselves. The
|
|
21
|
+
fonts, including any derivative works, can be bundled, embedded,
|
|
22
|
+
redistributed and/or sold with any software provided that any reserved
|
|
23
|
+
names are not used by derivative works. The fonts and derivatives,
|
|
24
|
+
however, cannot be released under any other type of license. The
|
|
25
|
+
requirement for fonts to remain under this license does not apply
|
|
26
|
+
to any document created using the fonts or their derivatives.
|
|
27
|
+
|
|
28
|
+
DEFINITIONS
|
|
29
|
+
"Font Software" refers to the set of files released by the Copyright
|
|
30
|
+
Holder(s) under this license and clearly marked as such. This may
|
|
31
|
+
include source files, build scripts and documentation.
|
|
32
|
+
|
|
33
|
+
"Reserved Font Name" refers to any names specified as such after the
|
|
34
|
+
copyright statement(s).
|
|
35
|
+
|
|
36
|
+
"Original Version" refers to the collection of Font Software components as
|
|
37
|
+
distributed by the Copyright Holder(s).
|
|
38
|
+
|
|
39
|
+
"Modified Version" refers to any derivative made by adding to, deleting,
|
|
40
|
+
or substituting -- in part or in whole -- any of the components of the
|
|
41
|
+
Original Version, by changing formats or by porting the Font Software to a
|
|
42
|
+
new environment.
|
|
43
|
+
|
|
44
|
+
"Author" refers to any designer, engineer, programmer, technical
|
|
45
|
+
writer or other person who contributed to the Font Software.
|
|
46
|
+
|
|
47
|
+
PERMISSION & CONDITIONS
|
|
48
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
49
|
+
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
|
50
|
+
redistribute, and sell modified and unmodified copies of the Font
|
|
51
|
+
Software, subject to the following conditions:
|
|
52
|
+
|
|
53
|
+
1) Neither the Font Software nor any of its individual components,
|
|
54
|
+
in Original or Modified Versions, may be sold by itself.
|
|
55
|
+
|
|
56
|
+
2) Original or Modified Versions of the Font Software may be bundled,
|
|
57
|
+
redistributed and/or sold with any software, provided that each copy
|
|
58
|
+
contains the above copyright notice and this license. These can be
|
|
59
|
+
included either as stand-alone text files, human-readable headers or
|
|
60
|
+
in the appropriate machine-readable metadata fields within text or
|
|
61
|
+
binary files as long as those fields can be easily viewed by the user.
|
|
62
|
+
|
|
63
|
+
3) No Modified Version of the Font Software may use the Reserved Font
|
|
64
|
+
Name(s) unless explicit written permission is granted by the corresponding
|
|
65
|
+
Copyright Holder. This restriction only applies to the primary font name as
|
|
66
|
+
presented to the users.
|
|
67
|
+
|
|
68
|
+
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
|
69
|
+
Software shall not be used to promote, endorse or advertise any
|
|
70
|
+
Modified Version, except to acknowledge the contribution(s) of the
|
|
71
|
+
Copyright Holder(s) and the Author(s) or with their explicit written
|
|
72
|
+
permission.
|
|
73
|
+
|
|
74
|
+
5) The Font Software, modified or unmodified, in part or in whole,
|
|
75
|
+
must be distributed entirely under this license, and must not be
|
|
76
|
+
distributed under any other license. The requirement for fonts to
|
|
77
|
+
remain under this license does not apply to any document created
|
|
78
|
+
using the Font Software.
|
|
79
|
+
|
|
80
|
+
TERMINATION
|
|
81
|
+
This license becomes null and void if any of the above conditions are
|
|
82
|
+
not met.
|
|
83
|
+
|
|
84
|
+
DISCLAIMER
|
|
85
|
+
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
86
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
|
87
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
|
88
|
+
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
|
89
|
+
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
90
|
+
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
|
91
|
+
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
92
|
+
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
|
93
|
+
OTHER DEALINGS IN THE FONT SOFTWARE.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
Rubik Variable Font
|
|
2
|
+
===================
|
|
3
|
+
|
|
4
|
+
This download contains Rubik as both variable fonts and static fonts.
|
|
5
|
+
|
|
6
|
+
Rubik is a variable font with this axis:
|
|
7
|
+
wght
|
|
8
|
+
|
|
9
|
+
This means all the styles are contained in these files:
|
|
10
|
+
Rubik-VariableFont_wght.ttf
|
|
11
|
+
Rubik-Italic-VariableFont_wght.ttf
|
|
12
|
+
|
|
13
|
+
If your app fully supports variable fonts, you can now pick intermediate styles
|
|
14
|
+
that aren’t available as static fonts. Not all apps support variable fonts, and
|
|
15
|
+
in those cases you can use the static font files for Rubik:
|
|
16
|
+
static/Rubik-Light.ttf
|
|
17
|
+
static/Rubik-Regular.ttf
|
|
18
|
+
static/Rubik-Medium.ttf
|
|
19
|
+
static/Rubik-SemiBold.ttf
|
|
20
|
+
static/Rubik-Bold.ttf
|
|
21
|
+
static/Rubik-ExtraBold.ttf
|
|
22
|
+
static/Rubik-Black.ttf
|
|
23
|
+
static/Rubik-LightItalic.ttf
|
|
24
|
+
static/Rubik-Italic.ttf
|
|
25
|
+
static/Rubik-MediumItalic.ttf
|
|
26
|
+
static/Rubik-SemiBoldItalic.ttf
|
|
27
|
+
static/Rubik-BoldItalic.ttf
|
|
28
|
+
static/Rubik-ExtraBoldItalic.ttf
|
|
29
|
+
static/Rubik-BlackItalic.ttf
|
|
30
|
+
|
|
31
|
+
Get started
|
|
32
|
+
-----------
|
|
33
|
+
|
|
34
|
+
1. Install the font files you want to use
|
|
35
|
+
|
|
36
|
+
2. Use your app's font picker to view the font family and all the
|
|
37
|
+
available styles
|
|
38
|
+
|
|
39
|
+
Learn more about variable fonts
|
|
40
|
+
-------------------------------
|
|
41
|
+
|
|
42
|
+
https://developers.google.com/web/fundamentals/design-and-ux/typography/variable-fonts
|
|
43
|
+
https://variablefonts.typenetwork.com
|
|
44
|
+
https://medium.com/variable-fonts
|
|
45
|
+
|
|
46
|
+
In desktop apps
|
|
47
|
+
|
|
48
|
+
https://theblog.adobe.com/can-variable-fonts-illustrator-cc
|
|
49
|
+
https://helpx.adobe.com/nz/photoshop/using/fonts.html#variable_fonts
|
|
50
|
+
|
|
51
|
+
Online
|
|
52
|
+
|
|
53
|
+
https://developers.google.com/fonts/docs/getting_started
|
|
54
|
+
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Fonts/Variable_Fonts_Guide
|
|
55
|
+
https://developer.microsoft.com/en-us/microsoft-edge/testdrive/demos/variable-fonts
|
|
56
|
+
|
|
57
|
+
Installing fonts
|
|
58
|
+
|
|
59
|
+
MacOS: https://support.apple.com/en-us/HT201749
|
|
60
|
+
Linux: https://www.google.com/search?q=how+to+install+a+font+on+gnu%2Blinux
|
|
61
|
+
Windows: https://support.microsoft.com/en-us/help/314960/how-to-install-or-remove-a-font-in-windows
|
|
62
|
+
|
|
63
|
+
Android Apps
|
|
64
|
+
|
|
65
|
+
https://developers.google.com/fonts/docs/android
|
|
66
|
+
https://developer.android.com/guide/topics/ui/look-and-feel/downloadable-fonts
|
|
67
|
+
|
|
68
|
+
License
|
|
69
|
+
-------
|
|
70
|
+
Please read the full license text (OFL.txt) to understand the permissions,
|
|
71
|
+
restrictions and requirements for usage, redistribution, and modification.
|
|
72
|
+
|
|
73
|
+
You can use them freely in your products & projects - print or digital,
|
|
74
|
+
commercial or otherwise. However, you can't sell the fonts on their own.
|
|
75
|
+
|
|
76
|
+
This isn't legal advice, please consider consulting a lawyer and see the full
|
|
77
|
+
license for all details.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|