Skip to main content

Seadragon Ajax - Coordinate System

Seadragon Ajax uses a normalized coordinate system similar to Silverlight Deep Zoom, allowing application logic to remain independent of image resolution. The top-left of the image is always at the origin (0, 0) while the width of the image is always 1. The height of the image is dependant on the aspect ratio, so an image which is half as tall as it is wide will have a height of 0.5.

It's important to note that as you pan and zoom around an image, the viewport – not the image – is what moves. That is, the image's bounds in the normalized coordinate system are constant (as defined above), while the viewport's bounds are variable. This is again similar to Silverlight Deep Zoom.

To convert between normalized coordinates (points) and screen coordinates (pixels), you can use conversion functions defined in the Viewport class. We did this in the example below to show the position of your mouse and the dimensions of the viewport, in both pixels (relative to the viewer) and points. As always, you can learn more by checking out the API reference.


Source Code

<!DOCTYPE html>
    <script type="text/javascript"

    <script type="text/javascript">
      var PRECISION = 2;   // number of decimal places
      var viewer = null;
      function init() {
        viewer = new Seadragon.Viewer("container");
        viewer.addEventListener("open", showViewport);
        viewer.addEventListener("animation", showViewport);
        Seadragon.Utils.addEvent(viewer.elmt, "mousemove",
      function showMouse(event) {
        // getMousePosition() returns position relative to page,
        // while we want the position relative to the viewer
        // element. so subtract the difference.
        var pixel = Seadragon.Utils.getMousePosition(event).minus

          = toString(pixel, true);
        if (!viewer.isOpen()) {
        var point = viewer.viewport.pointFromPixel(pixel);

          = toString(point, true);
      function showViewport(viewer) {
        if (!viewer.isOpen()) {
        var sizePoints = viewer.viewport.getBounds().getSize();
        var sizePixels = viewer.viewport.getContainerSize();
        // or = viewer.viewport.deltaPixelsFromPoints(sizePoints);

          = toString(sizePoints, false);
          = toString(sizePixels, false);
      function toString(point, useParens) {
        var x = point.x;
        var y = point.y;
        if (x % 1 || y % 1) {     // if not an integer,
          x = x.toFixed(PRECISION); // then restrict number of
          y = y.toFixed(PRECISION); // decimal places
        if (useParens) {
          return "(" + x + ", " + y + ")";
        } else {
          return x + " x " + y;
      Seadragon.Utils.addEvent(window, "load", init);

    <style type="text/css">
        width: 500px;
        height: 400px;
        background-color: black;
        border: 1px solid black;
        color: white;  /* for error messages, etc. */
        width: 500px;
        border: none;
        margin: 1em 0em;
      #output td
        width: 50%;
      #output .outputLabel
        font-weight: bold;


    <table id="output">
        <th class="name"> </th>
        <th class="value">Pixels</th>

        <th class="value">Points</th>
        <th>Mouse position</th>

        <td id="mousePixels">-</td>
        <td id="mousePoints">-</td>

        <th>Viewport dimensions</th>
        <td id="viewportSizePixels">-</td>
        <td id="viewportSizePoints">-</td>

    <div id="container"></div>