Fixes #3511: capitalize objects.
[wolnelektury.git] / apps / wolnelektury_core / static / js / picture.js
index 7cbb675..2464220 100644 (file)
@@ -1,63 +1,42 @@
 
 (function($) {
   $.widget('wl.pictureviewer', {
-
+    
     options: {
-      steps: 6, // steps of zoom
-      max: -1, // max zoom in percent
+      step: 20, // step in % of initial image
       plus_button: undefined,
       minus_button: undefined,
-      height: 500, // height to scale to initially
     },
-
+    ORIGINAL_LOADING: 0, 
+    ORIGINAL_AVAILABLE: 1, 
+    ORIGINAL_SHOWN: 2,
 
     _create: function() {
       var self = this;
-      /* Calibrate */
-      self._zoom = 0;
-
-      // the initial thumbnailed picture
-
-
-      var img = self.element.find('img.initial').get(0);
-
       self.initial_size = [ 
-       img.naturalWidth,
-       img.naturalHeight
+       self.element.data('width'),
+       self.element.data('height') 
       ];
+      self.original_size = [
+       self.element.data('original-width'),
+       self.element.data('original-height')
+      ];
+      self._zoom = 0;
+      self._ratio = 1.0;
 
-      self.element.width(self.initial_size[0]);
-      self.element.height(self.initial_size[1]);
+      self.original = $('<img src="'+ self.element.attr('data-original-url') +'">');
       
-      self.initial_position = self.element.offset();
-
-      var original = self.element.find('img.original').get(0);
-      self._original = false;
-      self.original_loeaded = undefined; // callback
-      self._original_loaded = false;
-
-      self.spinner = $("#spinner").progressSpin();
-
-      $(original).load(function() {
-       self._original_loaded = true;
-       self.spinner.stop();
-       var cb = self.original_loaded;
-       self.original_loaded = undefined;
-       if (cb)
-         cb()
-      });
-      
-      if (self.options.max <= 0) {
-       self.options.max = original.naturalWidth
-         * 100 / self.initial_size[0];
-      }
-
-      self.element.css({
-       'margin': 0,
-      });
+      self._original_avaialble = self.ORIGINAL_LOADING;
+      function original_loaded() {
+       self._original_avaialble = self.ORIGINAL_AVAILABLE;
+       self.options.plus_button.removeClass('inactive');
+       self.options.minus_button.removeClass('inactive');
+       console.log("Original image available, sizes initial: " + self.initial_size + ", original: " + self.original_size);
+      };
+      self.original.load(original_loaded);
 
-      self.element.offset(self.initial_position);
-      self.element.draggable({containment:"parent"});
+      self.element.width(self.initial_size[0]);
+      self.element.height(self.initial_size[1]);
 
       if (self.options.plus_button)
        self.options.plus_button.click(
        self.options.minus_button.click(
          function(ev) { self.zoom(-1); });
 
+      self._initial_mark = null;
+      function clean_initial_mark() {
+       if (self._initial_mark) {
+         self._initial_mark.remove();
+         self._initial_mark = null;
+       }
+      }
+      var initial_hash = window.location.hash;
+      if (initial_hash) {
+       var mk = null,
+        objectPrefix = '#object-',
+        themePrefix = '#theme-';
+       if (initial_hash.substr(0, objectPrefix.length) === objectPrefix) {
+         $("[href=#picture-objects]").trigger('click');
+       } else if (initial_hash.substr(0, themePrefix.length) === themePrefix) {
+         $("[href=#picture-themes]").trigger('click');
+       }
+       mk = $("[href=" + initial_hash + "]").eq(0);
+       self._initial_mark = self.createMark({
+         label: mk.text(),
+         coords: mk.data('coords')
+       });
+      }      
+
+
       self.options.areas_links.hover(function() {
+       clean_initial_mark();
        $this = $(this);
        var coords = $this.data("coords");
        this._picture_mark = self.createMark({
-         label: $this.text(),
+//       label: $this.text(),
          coords: coords,
        });
       }, function() {
        $(this._picture_mark).remove();
        this._picture_mark = undefined;
+      }).click(function(ev) {
+       ev.preventDefault();
+       var $mark = self.element.find('.mark').eq(0);
+       var markPos = $mark.offset();
+       markPos = [markPos.left, markPos.top];
+       var markSize = [ $mark.width(), $mark.height() ]
+       var wSize = [ window.innerWidth, window.innerHeight ];
+       window.scrollTo(
+         markPos[0] + markSize[0]/2 - wSize[0]/2,
+         markPos[1] + markSize[1]/2 - wSize[1]/2       
+       );
+       
       });
+
+      
+
       return self;
     },
 
-    natural_size: function() { 
-      var img = this.element.find('img').get(0);
-      return [ img.naturalWidth, img.naturalHeight ] 
+    currentSize: function() {
+      return [this.element.width(), this.element.height() ];
     },
 
     currentZoom: function() { return this._zoom; },
 
     initOriginal: function() {
-      var self = this;
-      function subst_original() {
-       self.element.find("img.initial").remove();
-       self.element.find("img.loading").removeClass("loading");
-       self._original = true;
-      }
-      if (!this._original) {
-       if (this._original_loaded) {
-         return subst_original();
-       } else {
-         self.original_loaded = subst_original;
-         self.spinner.start();
-       }
-      }
-
+      if (this._original_avaialble > this.ORIGINAL_LOADING && 
+         this._original_avaialble < this.ORIGINAL_SHOWN) {
+       this.element.css({'background-image': 'url('+ this.original.attr('src')+')', 'background-size':  this.initial_size[0]+'px'});
+       this._original_avaialble = this.ORIGINAL_SHOWN;
+      };
     },
 
     zoom: function(steps) {
     zoomForStep: function(step) {
       // 0 => initial
       // max_step-1 => max %
-      return 100 + (this.options.max - 100) / this.options.steps * step
+      if (step < 0) step = 0;
+      var zoomperc = 100 + step * this.options.step;
+      if (zoomperc * this.initial_size[0] > this.original_size[0] * 100) {
+       zoomperc = this.original_size[0] * 100 / this.initial_size[0];
+      };
+      return zoomperc;
     },
 
     zoomTo: function(level) {
-      if (level < 0 || level > this.options.steps)
-       return;
       var ratio = this.zoomForStep(level) / 100;
       var new_width  = ratio * this.initial_size[0];
       var new_height = ratio * this.initial_size[1];
+      var cs = this.currentSize();
+      if (new_width == cs[0]) 
+       return;
+
       var target = {
-       'width': new_width,
-       'left': Math.max(0, 
-                        this.initial_position.left 
-                        - (new_width - this.initial_size[0])/2),
-       'top': Math.max(0, 
-                       this.initial_position.top 
-                       - (new_height - this.initial_size[1])/2),
+       'width': new_width + 'px',
+       'height': new_height + 'px',
+       'background-size': new_width + 'px',
       };
 
       this._zoom = level;
-      this.element.animate(target, 200); // default duration=400
+      this._ratio = ratio;
+
+      this.element.css(target);
+      if (this._initial_mark) {
+       this._initial_mark = this.redrawMark(this._initial_mark);
+      }
+
     },
 
     allowedPosition: function(off) {
       return undefined;
 
     },
-
+    redrawMark: function(mark) {
+      var $mark = $(mark);
+      var $newmark = this.createMark($mark.data('mark'));
+      $mark.remove();
+      return $newmark;
+    },
     // mark
     // {
     //  label: "...",
     //  coords: [x, y, w, h]
     // }
     createMark: function(mark) {
+      if (mark.label === undefined)
+       mark.label = '';
       var $mark = $('<div class="mark"><div class="label">' + 
                    mark.label + '</div></div>');
-      var ratio = this.zoomForStep(this.currentZoom()) *
-       this.initial_size[0] / (100 * this.natural_size()[0]);
+      var cs = this.currentSize()
+      var ratio = cs[0] / this.original_size[0];
       var scale = function (v) { 
        return v * ratio; 
       }
       if (mark.coords[1][0] < 0 || mark.coords[1][1] < 0) { // whole
-       var s = self.natural_size();
+       var s = this.original_size;
        if (mark.coords[1][0] < 0) mark.coords[1][0] = s[0];
        if (mark.coords[1][1] < 0) mark.coords[1][1] = s[1];
       }
       $mark.width(coords[1][0] - coords[0][0]);
       $mark.height(coords[1][1] - coords[0][1]);
       $mark.css({left: coords[0][0], top: coords[0][1]});
+
+      $mark.data('mark', mark);
       return $mark.get(0);
     },
   });
-}(jQuery));
 
 
-$(document).ready(function(){
-  $(".picture-wrap").pictureviewer({
-    plus_button: $(".toolbar .button.plus"),
-    minus_button: $(".toolbar .button.minus"),
-    areas_links: $("#picture-objects a, #picture-themes a"),
-  });
-
+$(document).ready(function() {
   $.highlightFade.defaults.speed = 3000;
 
-  $('.toolbar a.dropdown').each(function() {
+  $('#menu .dropdown').each(function() {
     $t = $(this);
     $($t.attr('href')).hide().insertAfter(this);
   });
 
-  $('.toolbar a.dropdown').toggle(function() {
-    $(this).addClass('selected');
-    $($(this).attr('href')).slideDown('fast');
-  }, function() {
-    $(this).removeClass('selected');
-    $($(this).attr('href')).slideUp('fast');
+  $(".picture-wrap").pictureviewer({
+    plus_button: $(".button.plus"),
+    minus_button: $(".button.minus"),
+    areas_links: $("#picture-objects a, #picture-themes a"),
   });
 
-
 });
 
+}(jQuery));