Capturing Snapshots

Snapshots are great for capturing features of a simulation for detailed discussions, inclusion in homework problems or a book, or even sharing on social media.

Snapshot at time ${time}.
Now we can capture images of our simulations.

Adding snapshots is a great opportunity to foray into custom elements1. We added the canvas-snapshooter element, and the snapshot-caption element. Together these define a button to take a snapshot, and the caption for that snapshot.

Snapshots are absolutely positioned above the other content. They can also be minimized, and dragged to reposition them anywhere on the page.

We see how it all comes together if we look at the figure containing the visualization. Keep in mind that we also pass "results" to the Schrödinger simulation. The simulation knows to display itself in this figure, and to listen for "results" snapshot events.

  <figure class="center" id="results">
      <!-- Results canvas will be inserted here -->
      <div class="buttonContainer">
          <button id="start">▶<br/>Play</button>
          <button id="stop">■<br/>Stop</button>
          <button data-bc="true" class="launcher">↺<br/>Restart</button>
          <canvas-snapshooter target="results">
              <snapshot-caption>Snapshot at time ${time}.</snapshot-caption>

          Now we can capture images of our simulations.

The caption is evaluated as a JavaScript template when each snapshot is generated. In this case we have a global variable, time, on the page so ${time} is replaced with the time value for each snapshot. The caption identifies how far into the simulation the image was captured.

A snapshot showing partial reflection.

We can clean this up a bit. Looking at the code, dt = 5.0E-07, we see that there are at most 6 decimal places of significance. Figures beyond this are simply numerical noise from the imprecise representation of decimal fractions as a binary number.

JavaScript templates let us embed any JavaScript expression, so we can use ${time.toFixed(6)} to finesse the displayed time value.

      <snapshot-caption>Snapshot at time ${time.toFixed(6)}.</snapshot-caption>
A little finesse make a noticeable difference.

We can even go a little further. As the Schrödinger solver evolves, time will be moved to an internal state, and no longer be available as a global variable. We will be sure to keep time available through a getter. Our caption will then be something like this:

  <snapshot-caption>Snapshot at time ${renderer.getTime().toFixed(6)}.</snapshot-caption>

Snapshot at time ${renderer.getTime().toFixed(6)}.
The button is loosely coupled to the rendering, we can put it anywhere.
Creative Commons License
This work is licensed under a Creative Commons Attribution 4.0 International License.
  1. Custom elements have been around for a while, but now they are broadly supported.