Difference between revisions of "Loading Notice"

From Jmol
Jump to navigation Jump to search
(While the model is loading (after Jmol has finished loading))
(Spinner while JSmol load)
 
(9 intermediate revisions by 3 users not shown)
Line 1: Line 1:
=How to provide a 'please wait' notice while JmolApplet is loading=
+
=How to provide a 'please wait' notice while the Jmol Object is loading=
  
 
''Please, feel free to share here your tricks for showing a "please, wait" kind of notice so that users get some feedback that the JmolApplet is loading.''
 
''Please, feel free to share here your tricks for showing a "please, wait" kind of notice so that users get some feedback that the JmolApplet is loading.''
 +
 +
== Spinner while JSmol loads ==
 +
 +
This is a clean, simple method that displays an animated image (spinner) until the Jmol object
 +
has been built into the page. ([[User:AngelHerraez|AngelHerraez]])
 +
 +
You need an image like this [[File:JSmol spinner.gif]], and two lines of code:
 +
* in your CSS declarations:
 +
.jmolBox { background-image:url(JSmol_spinner.gif); background-repeat:no-repeat; background-position:center; }
 +
* in your page's JavaScript, before you call <code>Jmol.getApplet()</code>:
 +
Jmol.setAppletCss('jmolBox');
 +
 +
Note: the 'jmolBox' name can be changed to anything you wish.
  
 
== While Java and Jmol are loading ==
 
== While Java and Jmol are loading ==
.
+
 
 +
This is not easy, as you cannot put anything in the place of the applet; the browser draws the applet (even before it is loaded) on top of anything else in the page.
 +
 
 +
=== Trick #1 ===
 +
([[User:AngelHerraez|AngelHerraez]])
 +
 
 +
Here I choose to put a small JmolApplet in the homepage (here flushed top left, but could go anywhere else), so while the user reads the introduction to the site, Java and Jmol can go on loading, and when the user jumps to the content pages, Jmol will be cached and load quickly with the contents.
 +
 
 +
I insert a small DIV with a "please wait" warning and the applet; this latter does not load any molecule, just displays a "done" message using the <code>echo</code> command.
 +
I use matching colors for the DIV and applet backgrounds and texts, so the applet is not too apparent as such. The Java and Jmol logos will show up temporarily, but that is not a bad thing, as it proves that something is indeed going on.
 +
 
 +
<pre>
 +
<html>
 +
<head>
 +
<script src="Jmol.js" type="text/javascript"></script>
 +
<style type="text/css">
 +
#JmolPreload
 +
{
 +
  float:left; width:160px;
 +
  border:1px inset #333333; padding:4px; margin-right:2ex;
 +
  background-color:#FFFF80;
 +
  font-family:Arial, Helvetica, sans-serif; text-align:center;
 +
  font-size:16px;
 +
  color:#AA0000;
 +
}
 +
</style>
 +
</head>
 +
 
 +
<body>
 +
<div id="JmolPreload">
 +
  Please wait until Jmol has loaded
 +
  <script type="text/javascript">
 +
    jmolInitialize("./");
 +
    jmolSetAppletColor("#FFFF80");
 +
    jmolApplet([150,100], 'set disablePopupMenu on; set frank off; set echo middle center; font echo 19 sans; color echo [xAA0000]; echo Jmol is ready; ');
 +
  </script>
 +
</div>
 +
</body>
 +
</html>
 +
</pre>
 +
 
  
 
== While the model is loading (after Jmol has finished loading) ==
 
== While the model is loading (after Jmol has finished loading) ==
 +
 +
=== Trick #1 ===
 +
([[User:Ceroni|Sérgio Ceroni da Silva]])
  
 
jmolApplet("100%", "script pre.txt; load file.pdb; script post.txt")
 
jmolApplet("100%", "script pre.txt; load file.pdb; script post.txt")
Line 42: Line 98:
 
echo Use the available controls|to select a molecule|and change its visualization;
 
echo Use the available controls|to select a molecule|and change its visualization;
 
</pre>
 
</pre>
 +
 +
=== Trick #2 ===
 +
([[User:AngelHerraez|AngelHerraez]])
 +
 +
While Jmol is busy (e.g. loading a file or calculating an isosurface), the display is not updated. Therefore, it is important that if you put a "please wait" message using <code>echo</code>, you follow it with a <code>refresh</code> command; that way, the message will be shown and stay there until Jmol finishes its task (often, you will need to remove the message then).
 +
 +
Example:
 +
<pre>
 +
echo "Molecule is loading";
 +
refresh;
 +
load myMolecule.xyz;
 +
echo;
 +
</pre>
 +
 +
Example:
 +
<pre>
 +
echo "Calculating surface...";
 +
refresh;
 +
isosurface mySurface molecular;
 +
echo;
 +
</pre>
 +
=How to preload Java and the Jmol Applet in background=
 +
The long time it takes for Java and Jmol to load leads to a the need to let users know what is going on as described in the section above. In certain web page designs, it is possible to preload Java and the applet(s) while the user takes care of other housekeeping functions so that when they are needed, they are present and there is no need for the user to be advised of the delay.  For example, if the user needs to log in or needs to search a catalog of molecules prior to displaying one, the time required for those processes can be used to preload Java and the applet(s) so that when it comes time to display the molecule, it looks instantanious.
 +
 +
While interesting in concept, the execution of this task is not trivial because Oracle (formerly Sun) leaves it to each browser to create the Jave plugin for their own browser so how they behave varies from browser to browser and is annoyingly inconsistant. There are two parts to a preload. One is to load the java machine, the other is to load the applet. Of the two, loading the machine takes much longer. In the methods described below, we frequently run into the problem of he applet being unloaded when we don't want it to be. As annoying as that is, the java machine remains loaded and that is what makes up the bulk of the delay. A replacement applet can be created quite quickly, so while not perfect, the method may be "good enough". I am hoping that in time, we will gather enough data in this "corner" that preloading can be built into the javascript interface, either by default, or at least as an option, but we need to find a robust way to do it first.
 +
==Using display: none and visibility: hidden to hide applet during the preload==
 +
The most obvious solution to this task is to hide the applet in the initial HTML, then use DHTML (eg javascript and possibly AJAX) to carry out the house keeping and then unhide the applet at the point it is actually needed. The problem is that both IE and Firefox defer the loading of of java applets that are hidden, either with "display: none" or "visibility: hidden". Once they are unhidden the load begins but you are back to needing a "Please Wait" notice.  Currently, once applet(s) are loaded in IE, they can be hidden and they will stay loaded, ready for instant use. In Firefox, hiding an applet causes it to be unloaded.
 +
==Using Z-Index to hide the applet behind other content during the preload==
 +
Another thought thought is to put the applet behind a 2d image if the molecule and then when the 3d applet is loaded, hide the 2d and let the 3d show through. It turns out that this can currently be done in Firefox but not in IE. The reason for that is that the IE applet is implemented by running the applet in an operating system window which is precisely positiononed over the entire browswer window. As such it can not participate in the z-index scheme of the objects displayed in the browser itself.
 +
==Using absolute positioning to keep the applet out of view during the preload==
 +
A third strategy involves creating and absolututely positioned element and scrolling it off the left side of the screen using a sufficently large, negative value for the "left" style attribute. When needed, it can be positioned where needed.  This concept worked seemed to work in both IE and Firefox until I tried to insert it into the document flow using DHTML. Both IE and Firefox unload and then reload the applet when you attempt to move it within the document structure. As long as you can position it absolutely, this strategy can work, but you must be sure to include an "onresize" event because anything that would cause the document to "reflow" will require the absolute position to the applet to be re-established
 +
==Using a 1 pixel applet to preload==
 +
The most least elegant but most successful solution is to create a 1 pixel by 1 pixel applet and then altering the size when you are ready for it. This works in both IE and Firefox and avoids all of the "gotchas" with the prior methods but there are a few obstacles required to pull it off. The only real downside is that a sharp eyed user might be annoyed by the out of place pixel, but it is pretty inocuous. The steps required are as follows:<ol><li>Reduce the minimum applet size to 1 pixel using the command _jmol.allowedJmolSize=[1, 2048, 1]; before creating the applets. This command sets the minimum size of the applet to 1 pixel by 1 pixel; the maximum size to 2048x2048 and the default size to 1x1. Note that this is an internal command (signified by the leading underscore) and is not guaranteed not to break in future releases of Jmol.<li>Due to what I consider to be a bug in the applet, you must initialize the applet(s) using a size of zero. This will force the use of the default size, which we set in the previous step, which will achieve the 1x1 applet size desired. Using a size of 1 will incorrectly be interpreted as 100% by 100%.<li>When you are ready to use the applet, you can use the function jmolResizeApplet(width,height[,target]) however this updates the style of the applet. I have been directly updating the width and height properties of the applet object itself. In theory, using the API is the better choice for future compatibility, but at least for now, both methods seem to work.

Latest revision as of 16:38, 24 January 2016

How to provide a 'please wait' notice while the Jmol Object is loading

Please, feel free to share here your tricks for showing a "please, wait" kind of notice so that users get some feedback that the JmolApplet is loading.

Spinner while JSmol loads

This is a clean, simple method that displays an animated image (spinner) until the Jmol object has been built into the page. (AngelHerraez)

You need an image like this JSmol spinner.gif, and two lines of code:

  • in your CSS declarations:
.jmolBox { background-image:url(JSmol_spinner.gif); background-repeat:no-repeat; background-position:center; }
  • in your page's JavaScript, before you call Jmol.getApplet():
Jmol.setAppletCss('jmolBox');

Note: the 'jmolBox' name can be changed to anything you wish.

While Java and Jmol are loading

This is not easy, as you cannot put anything in the place of the applet; the browser draws the applet (even before it is loaded) on top of anything else in the page.

Trick #1

(AngelHerraez)

Here I choose to put a small JmolApplet in the homepage (here flushed top left, but could go anywhere else), so while the user reads the introduction to the site, Java and Jmol can go on loading, and when the user jumps to the content pages, Jmol will be cached and load quickly with the contents.

I insert a small DIV with a "please wait" warning and the applet; this latter does not load any molecule, just displays a "done" message using the echo command. I use matching colors for the DIV and applet backgrounds and texts, so the applet is not too apparent as such. The Java and Jmol logos will show up temporarily, but that is not a bad thing, as it proves that something is indeed going on.

<html>
<head>
<script src="Jmol.js" type="text/javascript"></script>
<style type="text/css">
#JmolPreload 
{ 
  float:left; width:160px; 
  border:1px inset #333333; padding:4px; margin-right:2ex;
  background-color:#FFFF80;
  font-family:Arial, Helvetica, sans-serif; text-align:center; 
  font-size:16px; 
  color:#AA0000; 
}
</style>
</head>

<body>
<div id="JmolPreload">
  Please wait until Jmol has loaded
  <script type="text/javascript">
    jmolInitialize("./");
    jmolSetAppletColor("#FFFF80");
    jmolApplet([150,100], 'set disablePopupMenu on; set frank off; set echo middle center; font echo 19 sans; color echo [xAA0000]; echo Jmol is ready; ');
  </script>
</div>
</body>
</html>


While the model is loading (after Jmol has finished loading)

Trick #1

(Sérgio Ceroni da Silva)

jmolApplet("100%", "script pre.txt; load file.pdb; script post.txt")

pre.txt

zap;
set echo middle center;
font echo 18 sanserif bold;
color echo navy;
echo Molecule loading||It will take a few seconds,|depending on molecule complexity|and your connection speed||Please wait...;
delay 0.1;


post.txt

wireframe off;
spacefill off;
set hoverDelay 0.1;
set echo middle center;
font echo 14 sanserif bold;
color echo background [xA6CAF0];
color echo navy;
echo Molecule loaded||Click here to turn off this warning|and then use the available controls|to select parts of the molecule|and change its visualization;
set echo middle script "set echo off";


simpler post.txt

set echo middle center;
font echo 16 sanserif bold;
color echo navy;
echo Use the available controls|to select a molecule|and change its visualization;

Trick #2

(AngelHerraez)

While Jmol is busy (e.g. loading a file or calculating an isosurface), the display is not updated. Therefore, it is important that if you put a "please wait" message using echo, you follow it with a refresh command; that way, the message will be shown and stay there until Jmol finishes its task (often, you will need to remove the message then).

Example:

echo "Molecule is loading";
refresh;
load myMolecule.xyz;
echo;

Example:

echo "Calculating surface..."; 
refresh;
isosurface mySurface molecular;
echo;

How to preload Java and the Jmol Applet in background

The long time it takes for Java and Jmol to load leads to a the need to let users know what is going on as described in the section above. In certain web page designs, it is possible to preload Java and the applet(s) while the user takes care of other housekeeping functions so that when they are needed, they are present and there is no need for the user to be advised of the delay. For example, if the user needs to log in or needs to search a catalog of molecules prior to displaying one, the time required for those processes can be used to preload Java and the applet(s) so that when it comes time to display the molecule, it looks instantanious.

While interesting in concept, the execution of this task is not trivial because Oracle (formerly Sun) leaves it to each browser to create the Jave plugin for their own browser so how they behave varies from browser to browser and is annoyingly inconsistant. There are two parts to a preload. One is to load the java machine, the other is to load the applet. Of the two, loading the machine takes much longer. In the methods described below, we frequently run into the problem of he applet being unloaded when we don't want it to be. As annoying as that is, the java machine remains loaded and that is what makes up the bulk of the delay. A replacement applet can be created quite quickly, so while not perfect, the method may be "good enough". I am hoping that in time, we will gather enough data in this "corner" that preloading can be built into the javascript interface, either by default, or at least as an option, but we need to find a robust way to do it first.

Using display: none and visibility: hidden to hide applet during the preload

The most obvious solution to this task is to hide the applet in the initial HTML, then use DHTML (eg javascript and possibly AJAX) to carry out the house keeping and then unhide the applet at the point it is actually needed. The problem is that both IE and Firefox defer the loading of of java applets that are hidden, either with "display: none" or "visibility: hidden". Once they are unhidden the load begins but you are back to needing a "Please Wait" notice. Currently, once applet(s) are loaded in IE, they can be hidden and they will stay loaded, ready for instant use. In Firefox, hiding an applet causes it to be unloaded.

Using Z-Index to hide the applet behind other content during the preload

Another thought thought is to put the applet behind a 2d image if the molecule and then when the 3d applet is loaded, hide the 2d and let the 3d show through. It turns out that this can currently be done in Firefox but not in IE. The reason for that is that the IE applet is implemented by running the applet in an operating system window which is precisely positiononed over the entire browswer window. As such it can not participate in the z-index scheme of the objects displayed in the browser itself.

Using absolute positioning to keep the applet out of view during the preload

A third strategy involves creating and absolututely positioned element and scrolling it off the left side of the screen using a sufficently large, negative value for the "left" style attribute. When needed, it can be positioned where needed. This concept worked seemed to work in both IE and Firefox until I tried to insert it into the document flow using DHTML. Both IE and Firefox unload and then reload the applet when you attempt to move it within the document structure. As long as you can position it absolutely, this strategy can work, but you must be sure to include an "onresize" event because anything that would cause the document to "reflow" will require the absolute position to the applet to be re-established

Using a 1 pixel applet to preload

The most least elegant but most successful solution is to create a 1 pixel by 1 pixel applet and then altering the size when you are ready for it. This works in both IE and Firefox and avoids all of the "gotchas" with the prior methods but there are a few obstacles required to pull it off. The only real downside is that a sharp eyed user might be annoyed by the out of place pixel, but it is pretty inocuous. The steps required are as follows:

  1. Reduce the minimum applet size to 1 pixel using the command _jmol.allowedJmolSize=[1, 2048, 1]; before creating the applets. This command sets the minimum size of the applet to 1 pixel by 1 pixel; the maximum size to 2048x2048 and the default size to 1x1. Note that this is an internal command (signified by the leading underscore) and is not guaranteed not to break in future releases of Jmol.
  2. Due to what I consider to be a bug in the applet, you must initialize the applet(s) using a size of zero. This will force the use of the default size, which we set in the previous step, which will achieve the 1x1 applet size desired. Using a size of 1 will incorrectly be interpreted as 100% by 100%.
  3. When you are ready to use the applet, you can use the function jmolResizeApplet(width,height[,target]) however this updates the style of the applet. I have been directly updating the width and height properties of the applet object itself. In theory, using the API is the better choice for future compatibility, but at least for now, both methods seem to work.

Contributors

Ted, AngelHerraez, Ceroni