static/tiles.js
changeset 28 c239c5c3beda
parent 27 1e79b4cc8f1b
child 29 605f4459a294
--- a/static/tiles.js	Mon Jul 07 04:36:03 2008 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,614 +0,0 @@
-// our initial (col, row) position
-var g_x, g_y;
-
-// how many pixels (wide, high) the viewport is
-var g_w, g_h;
-
-// how (wide, high) a tile is
-var g_tw, g_th;
-
-// half of viewport width/height
-var g_w_half, g_h_half;
-
-// the Draggable substrate, we get our current offset from this
-var g_draggable;
-
-// random debugging crap
-var g_debug, g_debug_enabled;
-
-// our current zoom level
-var g_z;
-
-// minimum and maximum zoom levels
-var g_z_min, g_z_max;
-
-// the viewport and substrate divs
-var viewp, subs;
-
-// the timeout used to call check_tiles
-var g_timeout;
-
-// a flag that signifies if we have updated the map due to being idle (not moving for 100ms)
-var g_idle;
-
-// a list of tiles for each zoom level
-var g_tiles;
-
-// any target that we were given in the URL
-var g_target;
-
-// called with info about the viewport
-function init () {
-    g_debug_enabled = false;
-    fullscreen = false;
-
-    viewp = $("viewport");
-    subs = $("substrate");
-
-    // were we anchored to some particular location?
-    g_target = document.location.hash.replace("#", "");
-   
-    // create the draggable
-    g_draggable = new Draggable("substrate", {
-        starteffect: null, 
-        endeffect: null,
-        onStart: viewport_scroll_start,
-        onDrag: viewport_scroll_move,
-        onEnd: viewport_scroll_done
-    });
-
-    // double-click listener
-    Event.observe(subs, "dblclick", viewport_dblclick);
-
-    // mouse wheel
-    Event.observe(subs, "mousewheel", viewport_mousewheel);
-    Event.observe(subs, "DOMMouseScroll", viewport_mousewheel);     // mozilla
-
-    // window size changes
-    Event.observe(document, "resize", update_viewport_size);
-
-    // should we do debugging?
-    if (g_debug_enabled) {
-        g_debug = document.createElement("pre");
-        g_debug.style.height = "100px";
-        g_debug.style.overflow = "auto";
-        debug("Debug output...");
-
-        $('wrapper').appendChild(g_debug);
-    }
-}
-
-/*
- * Initialize this for viewing the given image parameters
- */
-
-var g_opt_key, g_opt_value, g_refresh;
-function load (x, y, tw, th, z, z_min, z_max, opt_key, opt_value, refresh) {
-    // variable setup
-    g_x = x;
-    g_y = y;
-    g_tw = tw;
-    g_th = th;
-    g_z = z;
-    g_z_min = z_min;
-    g_z_max = z_max;
-    g_opt_key = opt_key;
-    g_opt_value = opt_value;
-    g_refresh = refresh;
-    
-    g_idle = true;
-
-    g_tiles = [];
-    
-    viewp = $("viewport");
-    subs = $("substrate");
-}
-
-function _onload () {
-    // create the zoom-level divs
-    for (var zl = g_z_min; zl <= g_z_max; zl++) {
-        zl_div = document.createElement("div");
-        zl_div.id = "zl_" + zl;
-        zl_div.style.position = "relative";
-
-        subs.appendChild(zl_div);
-
-        g_tiles[zl] = [];
-    }
-
-    if (g_target.indexOf("goto") == 0) {
-        var asdf = g_target.split("_", 4);
-        var x_w = asdf[1].split(":", 2);
-        var y_h = asdf[2].split(":", 2);
-        
-        update_zoom_level(
-            parseInt(asdf[3]) - g_z
-        );
-        
-        update_viewport_size(true);
-        
-        g_w = parseInt(x_w[1]);
-        g_h = parseInt(y_h[1]);
-
-        scroll_center_to(
-            parseInt(x_w[0]),
-            parseInt(y_h[0])
-        );
-
-        check_tiles();
-        
-        // no fullscreen for goto mode
-        return;
-
-    } else {
-        if (g_target == "fullscreen")
-            fullscreen = true;
-
-        // scroll to the initial position
-        scroll_to(g_x*g_tw, g_y*g_th);
-        
-        // adjust the zoom buttons
-        update_zoom_level(0);
-    }
-    
-    if (fullscreen)
-        viewport_fullscreen();
-    else  {
-        // load the viewport size and then the tiles
-        update_viewport_size(false);
-    }
-}
-
-Event.observe(window, "load", _onload);
-
-function unload () {
-    $("substrate").innerHTML = "";
-    g_tiles = [];
-}
-
-
-function debug (str) {
-    if (g_debug_enabled)
-        g_debug.textContent = (str + "\n") + g_debug.textContent;
-}
-
-// viewport-oriented stuff
-
-/*
- * update the screen size stuff based on the actual viewport size
- */
-function update_viewport_size (no_load) {
-    g_w = viewp.getWidth();
-    g_h = viewp.getHeight();
-
-    g_w_half = Math.floor(g_w/2);
-    g_h_half = Math.floor(g_h/2);
-    
-    if (!no_load)
-        check_tiles();
-}
-
-function viewport_fullscreen () {
-    viewp.style.position = "absolute";
-    viewp.style.top = "0px";
-    viewp.style.left = "0px";
-//    viewp.style.bottom = "0px";
-//    viewp.style.right = "0px";
-    viewp.style.width = "100%";
-    viewp.style.height = "100%";
-    viewp.style.borderWidth = 0;
-
-    update_viewport_size(false);
-}
-
-// pixel-oriented stuff, related to where the view is scrolled to
-
-/*
- * scroll the view to a given (x, y) pixel offset from the top-left corner
- */
-function scroll_to (x, y) {
-    subs.style.top = "-" + y + "px";
-    subs.style.left = "-" + x + "px";
-}
-
-function scroll_center_to (x, y) {
-    return scroll_to(
-        x - g_w_half,
-        y - g_h_half
-    );
-}
-
-/*
- * Move the view dx pixels to the right, and dy pixels to the bottom in a fancy animated fashion
- */
-function move (dx, dy) {
-    new Effect.Move(subs, {
-        x: -dx,
-        y: -dy,
-        duration: 0.5,  // pretty quick
-        afterFinish: check_tiles
-    });
-}
-
-/*
- * return the current horizontal scroll offset in pixels from the left edge
- */
-function scroll_x () {
-    return -parseInt(subs.style.left);
-}
-
-/*
- * return the current vertical scroll offset in pixels from the top edge
- */
-function scroll_y () {
-    return -parseInt(subs.style.top);
-}
-
-/*
- * scale co-ordinates by a zoom factor, if we zoom in (dz > 0), n will become larger, and if we zoom out (dz < 0), n will become smaller
- */
-function scaleByZoomDelta (n, dz) {
-    if (dz > 0)
-        return n << dz;
-    else
-        return n >> -dz;
-}
-
-/*
- * From the given offset, calcuate the new_offset that would be needed for the
- * pixel at (offset+half) to be at (new_offset+half) after the given zoom delta
- * has been applied
- */
-function align_center(offset, half, delta) {
-    return scaleByZoomDelta(offset + half, delta) - half;
-}
-
-/*
- * change the zoom level. A positive value zooms out, a negative vlaue zooms in.
- */
-function zoom (delta) {
-    return zoom_center_to(
-        scroll_x() + g_w_half,
-        scroll_y() + g_h_half, 
-        delta
-    );
-}
-
-/*
- * Zoom in/out such that the given co-ord (in current co-ord values) will be in the center of the screen
- */
-function zoom_center_to (x, y, delta) {
-    return zoom_to(
-        scaleByZoomDelta(x, delta) - g_w_half,
-        scaleByZoomDelta(y, delta) - g_h_half,
-        delta
-     );
-}
-
-/*
- * Zoom in/out such that the given co-ord (in target co-ord values) will be in the top-left corner
- */
-function zoom_to (x, y, delta) {
-    if (!update_zoom_level(delta))
-        return false;
-
-    // scroll to a new position such that the center co-ordinate is correct
-    scroll_to(x, y);
-    
-    // update view
-    update_after_timeout();
-
-    return true;
-}
-
-/*
- * Return the (x, y) co-ord of the event inside the viewport
- */
-function event_offset (e) {
-    var offset = viewp.cumulativeOffset();
-
-    return {
-        x: e.pointerX() - offset.left, 
-        y: e.pointerY() - offset.top
-    };
-}
-
-/*
- * Double-click handler
- */
-function viewport_dblclick (e) {
-    var offset = event_offset(e);
-    
-    if (!zoom_center_to(
-        scroll_x() + offset.x,
-        scroll_y() + offset.y,
-        1
-    )) {
-        // if we're already zoomed in, move o/
-        move(offset.x - g_w_half, offset.y - g_h_half);
-    }
-
-}
-
-// zoom control stuff
-
-/*
- * Mouse wheel handler
- */
-function viewport_mousewheel (e) {
-    // this works in very weird ways, so it's based on code from http://adomas.org/javascript-mouse-wheel/ (stupid person didn't include any license)
-    var delta;
-
-    if (e.wheelDelta) {  // IE + Opera
-        delta = e.wheelDelta;
-//        if (window.opera)   // Opera, but apparently not newer versions?
-//            delta = -delta;
-    } else if (e.detail) {  // Mozilla
-        delta = -e.detail;
-    } else {
-        return;
-    }
-
-    if (e.preventDefault)
-        e.preventDefault();
-    
-    // delta > 0 : scroll up, zoom in
-    // delta < 0 : scroll down, zoom out
-    delta = delta < 0 ? -1 : 1;
-
-    // Firefox's DOMMouseEvent's pageX/Y attributes are broken. layerN is for mozilla, offsetN for IE, seems to work
-    var x = parseInt(e.target.style.left) + (e.layerX ? e.layerX : e.offsetX);
-    var y = parseInt(e.target.style.top) + (e.layerY ? e.layerY : e.offsetY);
-    var dx = x - scroll_x();
-    var dy = y - scroll_y();
-
-    zoom_to(
-        scaleByZoomDelta(x, delta) - dx, 
-        scaleByZoomDelta(y, delta) - dy, 
-        delta
-    );
-
-//  if ( )    
-//        debug("scrollzoom from x=" + x + " y=" + y);
-}
-
-var g_zoom_timer;
-
-/*
- * Updates the zoom level with the given delta. Returns true/false if it's valid or not
- */
-function update_zoom_level (delta) {
-    var oz = g_z;
-    var z = g_z + delta;
-    
-    // is the new zoom level valid?
-    if (z < g_z_min || z > g_z_max)
-        return false;
-    
-    // hmm...
-    if (g_zoom_timer) {
-        clearTimeout(g_zoom_timer);
-        g_zoom_timer = null;
-    }
-
-    g_z = z;
-    
-    // now update the zoomlevel div's z-indexes
-    zoom_showhide_fillers(false);
-    var zi = 10;
-    var i;
-    
-    // preferr the current one over the new one
-    $("zl_" + z).style.zIndex = 11;
-    $("zl_" + oz).style.zIndex = 10;
-    
-    $("zl_" + z).show();
-    $("zl_" + oz).show();
-
-    // resize them
-    for (zi = Math.min(z, oz); zi <= Math.max(z, oz); zi++) {
-        dz = z - zi;
-
-        w = scaleByZoomDelta(g_tw, dz);
-        h = scaleByZoomDelta(g_th, dz);
-
-        tiles = g_tiles[zi];
-        tiles_len = tiles.length;
-
-        for (i = 0; i < tiles_len; i++) {
-            t = tiles[i];
-            ts = t.style;
-
-            ts.width = w;
-            ts.height = h;
-            ts.top = h*t.__row;
-            ts.left = w*t.__col;
-        }
-    }
-    
-    if (z != oz)
-        g_zoom_timer = setTimeout(function () { $("zl_" + oz).hide()}, 1000);
-    
-    return true;
-}
-
-/*
- * Hide the filler layers, i.e. the ones that aren't the current zoom level
- */
-function zoom_showhide_fillers (show) {
-    for (var zi = g_z_min; zi <= g_z_max; zi++)
-        if (zi != g_z)
-            if (show)
-                $("zl_" + zi).show();
-            else 
-                $("zl_" + zi).hide();
-}
-
-// tile-oriented stuff
-
-/*
- * Return the URL to the given tile, taking the current zoom level into account
- */
-function build_url (col, row) {
-    var x = col*g_tw;
-    var y = row*g_th;
-    
-    // two-bit hash (0-4)
-    var h = ((col%2)<<1 | (row%2)) + 1;
-
-    var u = "http://" + /* "tile" + h + "." + */ document.location.host + "/tile?x=" + x + "&y=" + y + "&z=" + g_z + "&sw=" + g_w + "&sh=" + g_h;
-
-    if (g_refresh)
-        u += "&ts=" + new Date().getTime();
-
-    if (g_opt_key && g_opt_value)
-        u += "&" + g_opt_key + "=" + g_opt_value;
-
-    return u;
-}
-
-/*
- * Loads the given tile, assuming that it hasn't been loaded yet
- */
-function load_tile (id, col, row) {
-    if (col < 0 || row < 0)
-        return;
-
-    e = document.createElement("img");
-    e.src = build_url(col, row);
-    e.id = id;
-    e.title = "(" + col + ", " + row + ")"
-    e.style.top = g_th * row;
-    e.style.left = g_tw * col;
-    e.style.display = "none";
-    Event.observe(e, "load", _tile_loaded);
-    e.__col = col;
-    e.__row = row;
-
-    $("zl_" + g_z).appendChild(e);
-    g_tiles[g_z].push(e);
-}
-
-function _tile_loaded (e) {
-    this.style.display = "block";
-
-}
-
-/*
- * Updates the tile to the current time/zoom level
- */
-function touch_tile (tile, col, row) {
-    if (g_refresh)
-        tile.src = build_url(col, row);
-}
-
-/*
- * Compute which tiles are currently visible, and load/touch all of them.
- *
- * If we are standing still, will schedule another call in two seconds
- */
-function check_tiles () {
-    var x = scroll_x();
-    var y = scroll_y();
-    var w = g_w;
-    var h = g_h;
-    
-    var start_col = Math.floor(x/g_tw);
-    var start_row = Math.floor(y/g_th);
-    var end_col = Math.floor((x + w)/g_tw);
-    var end_row = Math.floor((y + h)/g_th);
-
-//    debug("Visible area: (" + x + ", " + y + ") -> (" + (x+w) + ", " + (y+h) + "), visible tiles: (" + start_col + ", " + start_row + ") -> (" + end_col + ", " + end_row + ")");
-
-    var id, t;
-
-    for (col = start_col; col <= end_col; col++) {
-        for (row = start_row; row <= end_row; row++) {
-            id = "tile_" + g_z + "_" + col + "_" + row;
-            t = $(id);
-
-            if (t)
-                touch_tile(t, col, row);
-            else
-                load_tile(id, col, row);
-        }
-    }
-
-/* XXX: fix this...
-    // update the link-to-this-page thing
-    document.location.hash = "#goto_" + (x + g_w_half) + ":" + g_w + "_" + (y + g_h_half) + ":" + g_h + "_" + g_z;
-*/    
-}
-
-// delayed updates
-
-/*
- * Call check_tiles in 100ms, unless we are called again
- */
-function update_after_timeout () {
-    g_idle = false;
-
-    if (g_timeout)
-        clearTimeout(g_timeout);
-
-    g_timeout = setTimeout(_update_timeout, 100);  
-}
-
-function update_timeout_cancel () {
-    if (g_timeout) {
-        debug("Cancel timeout");
-        clearTimeout(g_timeout);
-    }
-}
-
-function _update_timeout () {
-    g_idle = true;
-
-    check_tiles();
-}
-/*
- * call check_tiles if it hasn't been called due to update_after_timeout
- */
-function update_now () {
-    if (g_timeout)
-        clearTimeout(g_timeout);
-    
-    if (!g_idle)
-        check_tiles();
-}
-
-// scrolling
-
-/*
- * called on scroll start
- */
-var g_scroll_x, g_scroll_y;
-function viewport_scroll_start () {
-    g_scroll_x = scroll_x();
-    g_scroll_y = scroll_y();
-}
-
-function viewport_scroll_move () {
-    update_after_timeout();
-
-    // may still want some kind of code like this later
-    // possibly: update once we scroll over 100px, regardless of if we're still or not
-/*    
-    var x = scroll_x();
-    var y = scroll_y();
-
-    var dx = Math.abs(g_scroll_x - x);
-    var dy = Math.abs(g_scroll_y - y)
-
-    if (dx > 100 || dy > 100) {
-        debug("scrolled dx=" + dx + " dy=" + dy + " pixels, update in 100ms");
-
-        update_after_timeout();
-    }
-*/
-}
-
-function viewport_scroll_done() {
-    update_now();
-}
-