diff --git a/ui (gen4)/experiments/scale-origin.html b/ui (gen4)/experiments/scale-origin.html
new file mode 100755
index 00000000..9ada033b
--- /dev/null
+++ b/ui (gen4)/experiments/scale-origin.html
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ui (gen4)/index.html b/ui (gen4)/index.html
index 3b1ed277..37949ede 100755
--- a/ui (gen4)/index.html
+++ b/ui (gen4)/index.html
@@ -43,9 +43,9 @@
/* basic animation... */
.viewer:not(.no-transitions) .ribbon-set {
- -webkit-transition: all 0.2s ease, transform 0.2s linear;
- -moz-transition: all 0.2s ease, transform 0.2s linear;
- transition: all 0.2s ease, transform 0.2s linear;
+ -webkit-transition: all 0.2s ease, transform 0.2s linear/*, transform-origin 0s none*/;
+ -moz-transition: all 0.2s ease, transform 0.2s linear/*, transform-origin 0s none*/;
+ transition: all 0.2s ease, transform 0.2s linear/*, transform-origin 0s none*/;
}
.viewer:not(.no-transitions) .ribbon {
diff --git a/ui (gen4)/lib/jli.js b/ui (gen4)/lib/jli.js
index b3104555..b8aaf590 100755
--- a/ui (gen4)/lib/jli.js
+++ b/ui (gen4)/lib/jli.js
@@ -509,6 +509,19 @@ function makeCSSVendorAttrGetter(attr, dfl, callback){
}
+
+var getElementOrigin = makeCSSVendorAttrGetter(
+ 'transformOrigin',
+ {top: 0, left: 0},
+ function(data){
+ res = /([0-9.]*(px|%)) ([0-9.]*(px|%))/.exec(data)
+ return {
+ left: res[1].slice(-2) == 'px' ? parseFloat(res[1]) : res[1],
+ top: res[3].slice(-2) == 'px' ? parseFloat(res[3]) : res[3],
+ }
+ })
+
+
// Return a scale value for the given element(s).
// NOTE: this will only return a single scale value...
var getElementScale = makeCSSVendorAttrGetter(
@@ -519,7 +532,7 @@ var getElementScale = makeCSSVendorAttrGetter(
})
-var getElementShift = makeCSSVendorAttrGetter(
+var getElementOffset = makeCSSVendorAttrGetter(
'transform',
{left: 0, top: 0},
function(data){
@@ -544,7 +557,7 @@ function setElementTransform(elem, offset, scale, duration){
var t3d = USE_3D_TRANSFORM ? 'translate3d(0,0,0)' : ''
if(offset == null){
- offset = getElementShift(elem)
+ offset = getElementOffset(elem)
// number -- only the x coord...
} else if(typeof(offset) == typeof(1)){
offset = {
@@ -686,7 +699,7 @@ function animateElementTo(elem, to, duration, easing, speed, callback, use_trans
var start = Date.now()
var then = start + duration
- var from = getElementShift(elem)
+ var from = getElementOffset(elem)
var cur = {
top: from.top,
left: from.left
@@ -789,6 +802,11 @@ function stopAnimation(elem){
// XXX account for other transitions...
+function setElementOffset(elem, l, t){
+ return setElementTransform(elem, [l, t])
+}
+
+
function setElementScale(elem, scale){
return setElementTransform(elem, null, scale)
}
@@ -802,11 +820,30 @@ function setElementOrigin(elem, x, y, z){
return $(elem).css({
'transform-origin': value,
+ '-o-transform-origin': value,
'-ms-transform-origin': value,
+ '-moz-transform-origin': value,
'-webkit-transform-origin': value,
})
}
+// this is like setElementOrigin(..) but will compensate for element
+// shift when scaled...
+// NOTE: this will work only of translate is used for positioning...
+function shiftOriginTo(elem, l, t){
+ var o = getElementOrigin(elem)
+ var scale = getElementScale(elem)
+ var offset = getElementOffset(elem)
+
+ // calculate the offset change and compensate...
+ var cl = offset.left + ((o.left - o.left*scale) - (l - l*scale))
+ var ct = offset.top + ((o.top - o.top*scale) - (t - t*scale))
+
+ setElementOffset(elem, cl, ct)
+
+ return setElementOrigin(elem, l+'px', t+'px')
+}
+
function setTransitionEasing(elem, ease){
if(typeof(ms) == typeof(0)){
diff --git a/ui (gen4)/ribbons.js b/ui (gen4)/ribbons.js
index a23b897c..2f270e8d 100755
--- a/ui (gen4)/ribbons.js
+++ b/ui (gen4)/ribbons.js
@@ -256,25 +256,123 @@ module.RibbonsPrototype = {
// - use translate for placement of the .ribbon-set (prefered)
// - use an extra eleemnt for positioning and keep the
// .ribbon-set at (0,0)
+ //
+ // XXX do we account vor viewer offset???
setScale: function(scale, t, l){
var ribbon_set = this.viewer.find('.ribbon-set')
- var s = this.getScale()
+ var img = t == null ? this.getImage() : t
- if(t == null){
- var img = this.getImage()
- t = img.offset()
- l = t.left + (img.width()/s)/2
- t = t.top + (img.height()/s)/2
+ // XXX need to make this sync and not animate...
+ this.setOrigin(img)
+
+ setElementScale(ribbon_set, scale)
+ return this
+ },
+
+ getOrigin: function(){
+ return getElementOrigin(this.viewer.find('.ribbon-set'))
+ },
+ // Set ribbon set origin...
+ //
+ // Set origin to center of current image
+ // .setOrigin()
+ // -> ribbons
+ //
+ // Set origin to center of elment:
+ // .setOrigin(elem)
+ // -> ribbons
+ //
+ // Set origin to screen coordinates:
+ // .setOrigin(x, y)
+ // -> ribbons
+ //
+ // XXX this appears not to be scale-neutral -- it gets a different
+ // set of numbers in ribbons >0 after doing .centerRibbon(..)
+ // ...but before calling .centerRibbon(..) this does everything
+ // quite correctly...
+ //
+ // ...this mutual dependency between this and .centerRibbon(..)
+ // makes it really hards to find where exactly the problem is...
+ //
+ // XXX should this also update offset????
+ /*
+ setOrigin: function(a, b){
+ var s = this.getScale()
+ var ribbon_set = this.viewer.find('.ribbon-set')
+
+ if(typeof(a) == typeof(123) && typeof(b) == typeof(123)){
+ var t = a
+ var l = b
+
+ } else {
+ if(a == null){
+ var img = this.getImage()
+ } else {
+ var img = this.getImage(a)
+ }
+ var io = img.offset()
+ var vo = this.viewer.offset()
+
+ // get distance from center of image to top left corner of
+ // screen...
+ // NOTE: the result should be scale-neutral.
+ var l = (io.left - vo.left) + (img.width()*s)/2
+ var t = (io.top - vo.top) + (img.height()*s)/2
}
- var ro = ribbon_set.offset()
+ var rs = getElementOffset(ribbon_set)
+
+ var ot = t - rs.top
+ var ol = l - rs.left
+
+ var ro = this.getOrigin()
+
+ console.log('### origin:', ol, ot)
- var ot = t - ro.top
- var ol = l - ro.left
setElementOrigin(ribbon_set, ol+'px', ot+'px')
-
- setElementScale(ribbon_set, scale)
+
+ //setElementOffset(ribbon_set,
+ // rs.left + (ro.left - ro.left*s) - (l - l*s),
+ // rs.top + (ro.top - ro.top*s) - (t - t*s))
+
+ return this
+ },
+ */
+ setOrigin: function(a, b){
+ var ribbon_set = this.viewer.find('.ribbon-set')
+
+ if(typeof(a) == typeof(123) && typeof(b) == typeof(123)){
+ var t = a
+ var l = b
+
+ } else {
+ if(a == null){
+ var img = this.getImage()
+ } else {
+ var img = this.getImage(a)
+ }
+
+ var s = this.getScale()
+ var io = img.offset()
+ var vo = this.viewer.offset()
+
+ // get distance from center of image to top left corner of
+ // screen...
+ // NOTE: the result should be scale-neutral.
+ var l = (io.left - vo.left) + (img.width()*s)/2
+ var t = (io.top - vo.top) + (img.height()*s)/2
+ }
+
+ var rs = getElementOffset(ribbon_set)
+
+ var ot = t - rs.top
+ var ol = l - rs.left
+
+ console.log('### origin:', ol, ot)
+
+ shiftOriginTo(ribbon_set, ol, ot)
+
return this
},
@@ -1309,6 +1407,8 @@ module.RibbonsPrototype = {
// implicitly (i.e. the default)
// NOTE: this will get absolute results relative to screen, view
// scaling will have no effect...
+ //
+ // XXX split this in two...(???)
_getOffset: function(target, vertical, horizontal, image_offset, scale){
vertical = vertical == null ? 'center' : vertical
horizontal = horizontal == null ? 'center' : horizontal
@@ -1333,8 +1433,12 @@ module.RibbonsPrototype = {
var rl = ribbon.offset().left
var rst = ribbon_set.offset().top
- var W = viewer.width()
- var H = viewer.height()
+ // NOTE: not quite sure why need to multiply this by scale but
+ // without it this does not work with origin/translate but
+ // does fine with top/left offsets...
+ var W = viewer.width() * scale
+ var H = viewer.height() * scale
+
var w = image.width() * scale
var h = image.height() * scale
@@ -1368,15 +1472,25 @@ module.RibbonsPrototype = {
// center a ribbon vertically...
//
centerRibbon: function(target, offset, scale){
- offset = offset == null
- ? this._getOffset(target, null, null, null, scale)
- : offset
+ scale = scale == null ? this.getScale() : scale
+ // NOTE: when woring with origin we do not care about scale...
+ //scale = scale == null ? 1 : scale
- // vertical offset...
- this.viewer.find('.ribbon-set')
- .css({
- top: offset.top,
- })
+ offset = offset == null
+ // XXX this should not get affected by scale or origin...
+ // XXX this gives correct resolts ONLY when we got scaled when
+ // focused on ribbon 0, in other cases it's messed up...
+ ? this._getOffset(target, null, null, null, 1).top
+ : offset.top
+
+ var ot = this.getOrigin().top
+ // XXX something is still missing here...
+ // ...it's getting closer when enlarging and blows up when scale -> 0
+ offset -= (ot/scale - ot)
+
+ console.log('### offset-top:', offset)
+
+ setElementOffset(this.viewer.find('.ribbon-set'), 0, offset)
return this
},
@@ -1384,6 +1498,7 @@ module.RibbonsPrototype = {
//
centerImage: function(target, mode, offset, scale){
scale = scale == null ? this.getScale() : scale
+
offset = offset == null
? this._getOffset(target, 'center', 'center', mode, scale)
: offset
diff --git a/ui (gen4)/ui.js b/ui (gen4)/ui.js
index 77e508bc..63abe0d6 100755
--- a/ui (gen4)/ui.js
+++ b/ui (gen4)/ui.js
@@ -142,6 +142,10 @@ module.GLOBAL_KEYBOARD = {
'#3': function(){ a.fitThree() },
'#4': function(){ a.fitFour() },
'#5': function(){ a.fitFive() },
+ '#6': function(){ a.fitSix() },
+ '#7': function(){ a.fitSeven() },
+ '#8': function(){ a.fitEight() },
+ '#9': function(){ a.fitNine() },
},