diff --git a/3Dmol/3dmol.js b/3Dmol/3dmol.js index 5bc5a54ad..e3c640cfb 100644 --- a/3Dmol/3dmol.js +++ b/3Dmol/3dmol.js @@ -9,7 +9,6 @@ $3Dmol = (function(window) { var my = window['$3Dmol'] || {}; - //var $ = window['jQuery']; return my; @@ -26,7 +25,9 @@ if ( typeof module === "object" && typeof module.exports === "object" ) { leave this code in if you would like to increase the likelihood of 3Dmol.js remaining supported. */ -$.get("https://3dmol.csb.pitt.edu/track/report.cgi"); +if(!$3Dmol.notrack) { + $.get("https://3dmol.csb.pitt.edu/track/report.cgi"); +} /* shims for IE */ /* @@ -562,3 +563,83 @@ if( typeof(define) === 'function' && define.amd) { define('$3Dmol',$3Dmol); } +/* StereoViewer for stereoscopic viewing +* @constructor +* @param {string} div id +* @param {number} eyeSeparation +* +*/ + +$3Dmol.createStereoViewer = function(divId, eyeSeparation) { + var that = this; + eyeSeparation = (eyeSeparation != undefined)?eyeSeparation:6; + var element = document.getElementById(divId); + var gldiv1 = document.createElement('div'); //create two divs having half of the width and place them side by side + var gldiv2 = document.createElement('div'); + gldiv1.id = "gldiv1"; + gldiv2.id = "gldiv2"; + gldiv1.style.cssText = gldiv2.style.cssText = 'position: relative; float: left; width: 50%; height: 100%; margin: 0; padding: 0; border: 0;'; + + element.appendChild(gldiv1); + element.appendChild(gldiv2); + + this.glviewer1 = $3Dmol.createViewer($("#gldiv1"),{ + camerax: -eyeSeparation/2.0}); + + this.glviewer2 = $3Dmol.createViewer($("#gldiv2"),{ + camerax: eyeSeparation/2.0}); + + var singleClickEvent = function() { + that.glviewer1.rotate(15); + that.glviewer2.rotate(15); + that.glviewer1.render(); + that.glviewer2.render(); + }; + + var doubleClickEvent = function() { + that.glviewer1.zoom(1.05); + that.glviewer2.zoom(1.05); + }; + + var clicks = 0, DELAY = 700, timer = null; + var handleClicks = function() { //to handle single and double clicks differently + clicks++; + if (clicks == 1) { + timer = setTimeout(function() { + singleClickEvent(); + clicks = 0; + },DELAY); + } + else { + clearTimeout(timer); + doubleClickEvent(); + clicks = 0; + } + }; + element.addEventListener("click", handleClicks, false); + + this.glviewer1.linkViewer(this.glviewer2); + this.glviewer2.linkViewer(this.glviewer1); + + var methods = Object.getOwnPropertyNames(this.glviewer1) //get all methods of glviewer object + .filter(function(property) { + return typeof that.glviewer1[property] == 'function'; + }); + + for (var i = 0; i < methods.length; i++) { //create methods of the same name + this[methods[i]] = (function(method){ + return function(){ + var m1=this['glviewer1'][method].apply(this['glviewer1'],arguments); + var m2=this['glviewer2'][method].apply(this['glviewer2'],arguments); + return [m1,m2]; + }; + })(methods[i]); + } + + this.setCoordinates = function (models, data, format) { //for setting the coordinates of the models + for (var i = 0; i < models.length; i++) { + models[i].setCoordinates(data, format); + } + }; + +} diff --git a/3Dmol/glshape.js b/3Dmol/glshape.js index 29686d7bc..bc4eb26d0 100644 --- a/3Dmol/glshape.js +++ b/3Dmol/glshape.js @@ -1026,31 +1026,44 @@ $3Dmol.GLShape = (function() { var newvertices= []; var newfaces=[]; - if (volSpec.selectedRegion !== undefined) { - - var xmax = volSpec.selectedRegion[0].x, - ymax = volSpec.selectedRegion[0].y, - zmax = volSpec.selectedRegion[0].z, - xmin = volSpec.selectedRegion[0].x, - ymin = volSpec.selectedRegion[0].y, - zmin = volSpec.selectedRegion[0].z; - - for (var i = 0; i < volSpec.selectedRegion.length; i++) { - if (volSpec.selectedRegion[i].x > xmax) - xmax = volSpec.selectedRegion[i].x; - else if (volSpec.selectedRegion[i].x < xmin) - xmin = volSpec.selectedRegion[i].x; - if (volSpec.selectedRegion[i].y > ymax) - ymax = volSpec.selectedRegion[i].y; - else if (volSpec.selectedRegion[i].y < ymin) - ymin = volSpec.selectedRegion[i].y; - if (volSpec.selectedRegion[i].z > zmax) - zmax = volSpec.selectedRegion[i].z; - else if (volSpec.selectedRegion[i].z < zmin) - zmin = volSpec.selectedRegion[i].z; + if (volSpec.selectedRegion && volSpec.coords === undefined) { + volSpec.coords = volSpec.selectedRegion; //backwards compat for incorrectly documented feature + } + if (volSpec.coords !== undefined) { + + var xmax = volSpec.coords[0].x, + ymax = volSpec.coords[0].y, + zmax = volSpec.coords[0].z, + xmin = volSpec.coords[0].x, + ymin = volSpec.coords[0].y, + zmin = volSpec.coords[0].z; + + for (var i = 0; i < volSpec.coords.length; i++) { + if (volSpec.coords[i].x > xmax) + xmax = volSpec.coords[i].x; + else if (volSpec.coords[i].x < xmin) + xmin = volSpec.coords[i].x; + if (volSpec.coords[i].y > ymax) + ymax = volSpec.coords[i].y; + else if (volSpec.coords[i].y < ymin) + ymin = volSpec.coords[i].y; + if (volSpec.coords[i].z > zmax) + zmax = volSpec.coords[i].z; + else if (volSpec.coords[i].z < zmin) + zmin = volSpec.coords[i].z; + } + + var rad = 2; + if(volSpec.radius !== undefined) { + rad = volSpec.radius; //backwards compat + } + if(volSpec.selectedOffset !== undefined) { //backwards compat + rad = volSpec.selectedOffset; + } + if(volSpec.seldist !== undefined) { + rad = volSpec.seldist; } - var rad = volSpec.radius; xmin -= rad; xmax += rad; ymin -= rad; @@ -1067,8 +1080,7 @@ $3Dmol.GLShape = (function() { && verts[i].z > zmin && verts[i].z < zmax && inSelectedRegion(verts[i], - volSpec.selectedRegion, - volSpec.selectedOffset, volSpec.radius)) { + volSpec.coords, rad)) { vertexmapping.push(newvertices.length); newvertices.push(verts[i]); @@ -1123,7 +1135,7 @@ $3Dmol.GLShape = (function() { if(typeof callback =="function") callback(); } - var inSelectedRegion=function(coordinate,selectedRegion,offset,radius){ + var inSelectedRegion=function(coordinate,selectedRegion,radius){ for(var i=0;i 0) //setting a value of dist*tan(5) + camera.position.x = dist*Math.tan(Math.PI / 180.0 * 5.0) + else + camera.position.x = -dist*Math.tan(Math.PI / 180.0 * 5.0) + camera.lookAt(new $3Dmol.Vector3(0,0,rotationGroup.position.z)); + return camera.position.x + } + } return GLViewer; diff --git a/3Dmol/specs.js b/3Dmol/specs.js index e2be2be53..d81ddcc60 100644 --- a/3Dmol/specs.js +++ b/3Dmol/specs.js @@ -162,9 +162,8 @@ * @prop {boolean} wireframe - draw as wireframe, not surface * @prop {number} linewidth - width of line for wireframe rendering **No longer supported by most browsers** * @prop {number} smoothness - amount to smooth surface (default 1) - * @prop {AtomSelectionSpec} sel - selection around which to show data - * @prop {list} coords - coordinates around which to include data - * @prop {number} seldist - distance around selection/coords to include data [default = 2.0] + * @prop {list} coords - coordinates around which to include data; use viewer.selectedAtoms() to convert an AtomSelectionSpec to coordinates + * @prop {number} seldist - distance around coords to include data [default = 2.0] * @prop {boolean} clickable - if true, user can click on object to trigger callback * @prop {function} callback - function to call on click */ diff --git a/Gruntfile.js b/Gruntfile.js index 45256439b..32d9f827a 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -116,7 +116,7 @@ module.exports = function(grunt) { options : { 'compilation_level': 'SIMPLE_OPTIMIZATIONS', 'warning_level': 'DEFAULT', - 'language_in': 'ECMASCRIPT5' + 'language_in': 'ECMASCRIPT6' } }, mmtf : { @@ -128,7 +128,7 @@ module.exports = function(grunt) { options : { 'compilation_level': 'SIMPLE_OPTIMIZATIONS', 'warning_level': 'DEFAULT', - 'language_in': 'ECMASCRIPT5' + 'language_in': 'ECMASCRIPT6' } }, pako : { @@ -140,7 +140,7 @@ module.exports = function(grunt) { options : { 'compilation_level': 'SIMPLE_OPTIMIZATIONS', 'warning_level': 'DEFAULT', - 'language_in': 'ECMASCRIPT5' + 'language_in': 'ECMASCRIPT6' } }, }, diff --git a/py3Dmol/examples.ipynb b/py3Dmol/examples.ipynb index 356a45d2f..7e3bc8025 100644 --- a/py3Dmol/examples.ipynb +++ b/py3Dmol/examples.ipynb @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "collapsed": false }, @@ -359,7 +359,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 4, "metadata": { "collapsed": false }, @@ -367,24 +367,25 @@ { "data": { "text/html": [ - "
\n", + "
\n", "" ], "text/plain": [ - "" + "" ] }, - "execution_count": 11, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -411,6 +412,7 @@ "view = py3Dmol.view()\n", "view.addModel(benz,'sdf')\n", "view.setStyle({'stick':{}})\n", + "view.setStyle({'model':0},{'stick':{'colorscheme':'cyanCarbon'}})\n", "view.zoomTo()" ] }, diff --git a/tests/auto/imgs/testAddModelPDB.png b/tests/auto/imgs/testAddModelPDB.png index 1037891ff..2659f4d5a 100644 Binary files a/tests/auto/imgs/testAddModelPDB.png and b/tests/auto/imgs/testAddModelPDB.png differ diff --git a/tests/auto/imgs/test_isosurface_coords.png b/tests/auto/imgs/test_isosurface_coords.png new file mode 100644 index 000000000..5238ce7f2 Binary files /dev/null and b/tests/auto/imgs/test_isosurface_coords.png differ diff --git a/tests/auto/tests/test96.js b/tests/auto/tests/test96.js new file mode 100644 index 000000000..d7009917e --- /dev/null +++ b/tests/auto/tests/test96.js @@ -0,0 +1,19 @@ + + + var stereoViewer = new $3Dmol.createStereoViewer("gldiv", 10); + + $.get("volData/TC5b.prmtop", + function(data) { + var models = stereoViewer.addModel(data, "prmtop"); + $.get("volData/heat1.mdcrd", + function(data) { + stereoViewer.setCoordinates(models, data, "mdcrd"); + stereoViewer.setStyle({},{sphere:{}}); + stereoViewer.zoomTo(); + var dist = stereoViewer.getPerceivedDistance(); + stereoViewer.setPerceivedDistance(dist[0]-10); //useful for zooming in or out + stereoViewer.setAutoEyeSeparation(); //optional. changes the camera x value + stereoViewer.animate({loop:"forward",reps:1}); + stereoViewer.render(callback); + }); + }); diff --git a/tests/auto/tests/testAddModelPDB.js b/tests/auto/tests/testAddModelPDB.js index c7dec195f..08c689637 100644 --- a/tests/auto/tests/testAddModelPDB.js +++ b/tests/auto/tests/testAddModelPDB.js @@ -1,22 +1,9 @@ - $.get('volData/4csv.pdb', function(data) { - viewer.addModel(data,'pdb'); - viewer.setStyle({cartoon:{},stick:{}}); - viewer.zoomTo(); - viewer.render( /*no callback*/); - - //can't use jquery with binary data - $3Dmol.getbin('volData/4csv.ccp4.gz', function(data) { - var voldata = new $3Dmol.VolumeData(data, 'ccp4.gz'); - viewer.addIsosurface(voldata, {isoval: 0.25, - color: "blue", - wireframe: true, - selectedRegion: viewer.selectedAtoms({}), - selectedOffset: 3, - radius: 3.0 - }); - - viewer.render(); - }); +$.get('volData/4csv.pdb', function(data) { + viewer.addModel(data,'pdb'); + viewer.setStyle({cartoon:{},stick:{}}); + viewer.zoomTo(); + viewer.render(); + }); diff --git a/tests/auto/tests/test_isosurface_coords.js b/tests/auto/tests/test_isosurface_coords.js new file mode 100644 index 000000000..972f50875 --- /dev/null +++ b/tests/auto/tests/test_isosurface_coords.js @@ -0,0 +1,21 @@ + + + $.get('volData/4csv.pdb', function(data) { + viewer.addModel(data,'pdb'); + viewer.setStyle({cartoon:{},stick:{}}); + viewer.zoomTo(); + viewer.render( /*no callback*/); + + //can't use jquery with binary data + $3Dmol.getbin('volData/4csv.ccp4.gz', function(data) { + var voldata = new $3Dmol.VolumeData(data, 'ccp4.gz'); + viewer.addIsosurface(voldata, {isoval: 0.25, + color: "blue", + wireframe: true, + coords: viewer.selectedAtoms({}), + seldist: 3.0 + }); + + viewer.render(); + }); +}); diff --git a/tests/testgl.html b/tests/testgl.html index 667c4e930..6d858907c 100644 --- a/tests/testgl.html +++ b/tests/testgl.html @@ -107,99 +107,21 @@ $(document).ready(function() { var viewer = glviewer = $3Dmol.createViewer("gldiv"); - // viewer.addModel($('#moldata_sdf').val(), null, {keepH: true}); - // viewer.setBackgroundColor("white"); - //glviewer.setStyle({},{stick:{}}); - - - //glviewer.zoomTo(); - // glviewer.rotate(10); - //glviewer.setView([ -4.5, -0, -0, 131.0067105441296, -0.024549708693956798, -0.7053212242625087, 0.02109860663993842, -0.7081483821952366 ]); - //glviewer.render(); - //atoms = m.selectedAtoms({ }); - - //m.setStyle({resi:[34,35]},{sphere:{}}); - /*$3Dmol.download("pdb:1ubq", viewer, null, function(m) { - m.setStyle({bonds: 0}, {sphere:{radius:0.5}}); - viewer.addSurface($3Dmol.SurfaceType.VDW, {colorscheme: 'rasmol'}, {bonds: 0, invert: true}); - viewer.addSurface($3Dmol.SurfaceType.SAS, {color: 'white', opacity: 0.75}, {bonds: 0, invert: true}); - });*/ - -/* - $.get('./test_structs/4v99.cif', function(data) { - console.profile("label for profile"); - glviewer.clear(); - glviewer.addModel(data, 'cif'); - glviewer.zoomTo(); - var time = new Date(); - glviewer.setStyle({stick:{}}); - glviewer.render(); - console.log("Create: "+(new Date() - time)); - - for(var i = 0; i < 10; i++) - { - time = new Date(); - glviewer.rotate(10); - glviewer.render(); - console.log("Rotate: "+(new Date() - time)); - - } - console.profileEnd(); + $.get("auto/volData/model1.prmtop", function (data){ + var m = viewer.addModel(data, "prmtop"); + $3Dmol.getbin("auto/volData/model1_md2.nc", function(ret){ + m.setCoordinates(ret, "netcdf"); + viewer.setStyle({},{sphere:{}}); + viewer.zoomTo(); + viewer.animate({loop:"forward",reps:1}); + viewer.render(); + }, true); }); - */ - viewer.setBackgroundColor(0xffffffff); - function load_ccp4_map (viewer, url) { - var req = new XMLHttpRequest(); - req.open('GET', url, true); - req.responseType = "arraybuffer"; - req.onload = function (aEvt) { - - var map_data = new Int8Array(req.response); - var voldata = new $3Dmol.VolumeData(req.response, "ccp4.gz"); - /* viewer.addIsosurface(voldata, {isoval: 25, - color: "blue", - alpha: 0.5, - smoothness: 0}); - */ - viewer.addIsosurface(voldata, {isoval: 0.3, - color: "red", - linewidth:0.005, - wireframe: true, - smoothness: 0, - callback: - function() { - this.opacity = 0.0; - viewer.render(); - }}); - viewer.setStyle({}, {stick:{}}); - viewer.zoomTo(); - viewer.render(); - - - - }; - req.send(null); - } - //load_ccp4_map (viewer,"check/volData/4ysj.ccp4.gz"); -// $3Dmol.download('pdb:4ysj',viewer,{},function() { viewer.setStyle({'cartoon':{},'stick':{}}); viewer.render(); }); -// $3Dmol.download('pdb:1bna',viewer,{},function() { viewer.setStyle({'cartoon':{},'stick':{}}); viewer.render(); }); - /* $3Dmol.download('pdb:1ejg',viewer,{altLoc:'*'},function() { - viewer.setStyle({'stick':{color:'#34f'}}); viewer.render(); - viewer.mapAtomProperties($3Dmol.applyPartialCharges); - }); */ - - viewer.setBackgroundColor(0xffffffff); - $.get('input.pdb',function(data) { - struct1 = viewer.addModel(data); - struct1.setStyle({cartoon: {}}); - viewer.zoomTo(); - viewer.render(); }); - - }); +