index.html 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
  6. <title>Mol* Proteopedia Wrapper</title>
  7. <style>
  8. * {
  9. margin: 0;
  10. padding: 0;
  11. box-sizing: border-box;
  12. }
  13. #app {
  14. position: absolute;
  15. left: 160px;
  16. top: 100px;
  17. width: 600px;
  18. height: 600px;
  19. border: 1px solid #ccc;
  20. }
  21. #controls {
  22. position: absolute;
  23. width: 130px;
  24. top: 10px;
  25. left: 10px;
  26. }
  27. #controls > button {
  28. display: block;
  29. width: 100%;
  30. text-align: left;
  31. }
  32. #controls > hr {
  33. margin: 5px 0;
  34. }
  35. #controls > input, #controls > select {
  36. width: 100%;
  37. display: block;
  38. }
  39. #volume-streaming-wrapper {
  40. position: absolute;
  41. top: 100px;
  42. left: 780px;
  43. width: 300px;
  44. }
  45. </style>
  46. <link rel="stylesheet" type="text/css" href="molstar.css" />
  47. <script type="text/javascript" src="./index.js"></script>
  48. </head>
  49. <body>
  50. <div id='controls'>
  51. <h3>Source</h3>
  52. <input type='text' id='url' placeholder='url' style='width: 400px' />
  53. <input type='text' id='assemblyId' placeholder='assembly id' />
  54. <select id='format'>
  55. <option value='cif' selected>CIF</option>
  56. <option value='pdb'>PDB</option>
  57. </select>
  58. <input type='checkbox' id='isBinary' style="display: inline-block; width: auto" /> <label for="isBinary"> Binary</label><br />
  59. </div>
  60. <div id="app"></div>
  61. <div id="volume-streaming-wrapper"></div>
  62. <script>
  63. // it might be a good idea to define these colors in a separate script file
  64. var CustomColors = [0x00ff00, 0x0000ff];
  65. // create an instance of the plugin
  66. var PluginWrapper = new MolStarProteopediaWrapper();
  67. console.log('Wrapper version', MolStarProteopediaWrapper.VERSION_MAJOR, MolStarProteopediaWrapper.VERSION_MINOR);
  68. function $(id) { return document.getElementById(id); }
  69. var pdbId = '1cbs', assemblyId= 'preferred', isBinary = true;
  70. var url = 'https://www.ebi.ac.uk/pdbe/entry-files/download/' + pdbId + '.bcif'
  71. var format = 'cif';
  72. $('url').value = url;
  73. $('url').onchange = function (e) { url = e.target.value; }
  74. $('assemblyId').value = assemblyId;
  75. $('assemblyId').onchange = function (e) { assemblyId = e.target.value; }
  76. $('format').value = format;
  77. $('format').onchange = function (e) { format = e.target.value; }
  78. $('isBinary').checked = isBinary;
  79. $('isBinary').onchange = function (e) { isBinary = !!e.target.checked; };
  80. function loadAndSnapshot(params) {
  81. PluginWrapper.load(params).then(() => {
  82. setTimeout(() => snapshot = PluginWrapper.plugin.state.getSnapshot({ canvas3d: false /* do not save spinning state */ }), 500);
  83. });
  84. }
  85. var representationStyle = {
  86. // sequence: { coloring: 'proteopedia-custom' }, // or just { }
  87. hetGroups: { kind: 'ball-and-stick' }, // or 'spacefill
  88. water: { hide: true },
  89. snfg3d: { hide: false }
  90. };
  91. PluginWrapper.init('app' /** or document.getElementById('app') */, {
  92. customColorList: CustomColors
  93. });
  94. PluginWrapper.setBackground(0xffffff);
  95. loadAndSnapshot({ url: url, format: format, isBinary: isBinary, assemblyId: assemblyId, representationStyle: representationStyle });
  96. PluginWrapper.toggleSpin();
  97. PluginWrapper.events.modelInfo.subscribe(function (info) {
  98. console.log('Model Info', info);
  99. listHetGroups(info);
  100. });
  101. addControl('Load Asym Unit', () => loadAndSnapshot({ url: url, format: format, isBinary }));
  102. addControl('Load Assembly', () => loadAndSnapshot({ url: url, format: format, isBinary, assemblyId: assemblyId }));
  103. addSeparator();
  104. addHeader('Representation');
  105. addControl('Custom Chain Colors', () => PluginWrapper.updateStyle({ sequence: { coloring: 'proteopedia-custom' } }, true));
  106. addControl('Default Chain Colors', () => PluginWrapper.updateStyle({ sequence: { } }, true));
  107. addControl('HET Spacefill', () => PluginWrapper.updateStyle({ hetGroups: { kind: 'spacefill' } }, true));
  108. addControl('HET Ball-and-stick', () => PluginWrapper.updateStyle({ hetGroups: { kind: 'ball-and-stick' } }, true));
  109. addControl('Hide 3DSNFG', () => PluginWrapper.updateStyle({ snfg3d: { hide: true } }, true));
  110. addControl('Show 3DSNFG', () => PluginWrapper.updateStyle({ snfg3d: { hide: false } }, true));
  111. addControl('Hide Water', () => PluginWrapper.updateStyle({ water: { hide: true } }, true));
  112. addControl('Show Water', () => PluginWrapper.updateStyle({ water: { hide: false } }, true));
  113. addSeparator();
  114. addHeader('Camera');
  115. addControl('Reset Position', () => PluginWrapper.camera.resetPosition());
  116. addControl('Toggle Spin', () => PluginWrapper.camera.toggleSpin());
  117. // Same as "wheel icon" and Viewport options
  118. // addControl('Clip', () => PluginWrapper.viewport.setSettings({ clip: [33, 66] }));
  119. // addControl('Reset Clip', () => PluginWrapper.viewport.setSettings({ clip: [1, 100] }));
  120. addSeparator();
  121. addHeader('Animation');
  122. // adjust this number to make the animation faster or slower
  123. // requires to "restart" the animation if changed
  124. PluginWrapper.animate.modelIndex.targetFps = 30;
  125. addControl('Play To End', () => PluginWrapper.animate.modelIndex.onceForward());
  126. addControl('Play To Start', () => PluginWrapper.animate.modelIndex.onceBackward());
  127. addControl('Play Palindrome', () => PluginWrapper.animate.modelIndex.palindrome());
  128. addControl('Play Loop', () => PluginWrapper.animate.modelIndex.loop());
  129. addControl('Stop', () => PluginWrapper.animate.modelIndex.stop());
  130. addSeparator();
  131. addHeader('Misc');
  132. addControl('Apply Evo Cons Style', () => PluginWrapper.coloring.evolutionaryConservation());
  133. addControl('Apply Evo Cons Colors', () => PluginWrapper.coloring.evolutionaryConservation({ sequence: true, het: false, keepStyle: true }));
  134. addControl('Default Visuals', () => PluginWrapper.updateStyle());
  135. addSeparator();
  136. addHeader('HET Groups');
  137. addControl('Reset', () => PluginWrapper.hetGroups.reset());
  138. addHetGroupsContainer();
  139. addSeparator();
  140. addHeader('Exp. Data');
  141. addControl('Init', () => PluginWrapper.experimentalData.init($('volume-streaming-wrapper')));
  142. addControl('Remove', () => PluginWrapper.experimentalData.remove());
  143. addSeparator();
  144. addHeader('State');
  145. var snapshot;
  146. addControl('Set Snapshot', () => {
  147. // const options = { data: true, behavior: false, animation: false, interactivity: false, canvas3d: false, camera: false, cameraTransition: false };
  148. snapshot = PluginWrapper.plugin.state.getSnapshot(/** options */);
  149. // console.log(JSON.stringify(snapshot, null, 2));
  150. });
  151. addControl('Restore Snapshot', () => {
  152. if (!snapshot) return;
  153. PluginWrapper.snapshot.set(snapshot);
  154. });
  155. addControl('Download State', () => {
  156. PluginWrapper.snapshot.download('molj');
  157. });
  158. addControl('Download Session', () => {
  159. PluginWrapper.snapshot.download('molx');
  160. });
  161. ////////////////////////////////////////////////////////
  162. function addHetGroupsContainer() {
  163. var div = document.createElement('div');
  164. div.id = 'het-groups';
  165. $('controls').appendChild(div);
  166. }
  167. function addControl(label, action) {
  168. var btn = document.createElement('button');
  169. btn.onclick = action;
  170. btn.innerText = label;
  171. $('controls').appendChild(btn);
  172. }
  173. function addSeparator() {
  174. var hr = document.createElement('hr');
  175. $('controls').appendChild(hr);
  176. }
  177. function addHeader(header) {
  178. var h = document.createElement('h3');
  179. h.innerText = header;
  180. $('controls').appendChild(h);
  181. }
  182. function listHetGroups(info) {
  183. var div = $('het-groups');
  184. div.innerHTML = '';
  185. info.hetResidues.forEach(function (r) {
  186. var l = document.createElement('button');
  187. l.innerText = r.name;
  188. l.onclick = function () {
  189. PluginWrapper.hetGroups.focusFirst(r.name, { doNotLabelWaters: true });
  190. };
  191. div.appendChild(l);
  192. });
  193. }
  194. </script>
  195. </body>
  196. </html>