diff --git a/ui (gen4)/data.js b/ui (gen4)/data.js index ecd21e64..2a019700 100755 --- a/ui (gen4)/data.js +++ b/ui (gen4)/data.js @@ -935,6 +935,7 @@ module.DataPrototype = { // base, should we use last as a base for right shifting??? // ...another way to go could be using current as a reference // XXX test vertical.. + // XXX should this be called .placeImage(..)??? shiftImage: function(from, target, mode){ from = from == null ? this.current : from from = from == 'current' ? this.current : from @@ -1004,17 +1005,31 @@ module.DataPrototype = { order.splice(t+i, 0, this.order.splice(f, 1)[0]) // update ribbons... - for(k in ribbons){ - var e = ribbons[k].splice(f, 1)[0] - ribbons[k].splice(t+i, 0, e) - // remove the null/undefined if it was just inserted... - // NOTE: this needs to be done as splice inserts the 3'rd - // argument explicitly regardless of it's value, - // this if not done we'll end up with undefined - // inserted into a sparse ribbon which will be - // considered as an element... - if(e == null){ - delete ribbons[k][t+i] + for(var k in ribbons){ + var r = ribbons[k] + + var e = r.splice(f, 1)[0] + + // NOTE: for some magical reason L.slice(n, .., x) will + // append x to L rather than place it at position + // n, if L.length < n + // ...this we can't use .splice(..) for cases when + // inserting after the last element of the array... + if(r.length > t+i){ + r.splice(t+i, 0, e) + + // remove the null/undefined if it was just inserted... + // NOTE: this needs to be done as splice inserts the 3'rd + // argument explicitly regardless of it's value, + // this if not done we'll end up with undefined + // inserted into a sparse ribbon which will be + // considered as an element... + if(e == null){ + delete r[t+i] + } + + } else if(e != null){ + r[t+i] = e } } } diff --git a/ui (gen4)/experiments/scale-origin.html b/ui (gen4)/experiments/scale-origin.html index 5c0b2457..dfe0cb8c 100755 --- a/ui (gen4)/experiments/scale-origin.html +++ b/ui (gen4)/experiments/scale-origin.html @@ -81,6 +81,7 @@ function setOffset(l, t){ function setScale(s){ setElementScale($('.block'), s) + // compensate for point scale... setElementScale($('.point'), 1/s) setElementScale($('.point-old'), 1/s) } @@ -111,6 +112,7 @@ function setOrigin(l, t, no_comp){ } + // Center a block to a point... // // If not coordinates are given then center to element origin... @@ -121,44 +123,21 @@ function setOrigin(l, t, no_comp){ // supported keywords: // 'screen' // 'elem' +// +// XXX need to make this independent of current position... +// ...this is to prevent it from getting the wrong target coords +// during animations.. function centerBlock(l, t, scale){ var block = $('.block') - var s = getElementScale(block) + var container = $('.container') - scale = scale == 'screen' ? 1 - : scale == 'elem' ? s - : s + var offset = getRelativeOffset(container, block, { + top: t, + left: l, + scale: scale, + }) - var offset = getElementOffset(block) - - var bo = block.offset() - var co = $('.container').offset() - - var W = $('.container').width() - var H = $('.container').height() - - var o = getElementOrigin(block) - - // normalize the l,t to element scale... - if(l != null && t != null){ - - var w = block.width() - var h = block.height() - o = { - // target offset scale... - top: t*scale - // set origin to top left corner of element (compensate - // for scaling)... - + (h - h*s) / (w / o.left), - left: l*scale - + (w - w*s) / (h / o.left), - } - } - - var dl = offset.left + (W/2 - offset.left) - o.left - var dt = offset.top + (H/2 - offset.top) - o.top - - setOffset(dl, dt) + setOffset(offset.left, offset.top) } diff --git a/ui (gen4)/lib/jli.js b/ui (gen4)/lib/jli.js index 730e65ed..327e4748 100755 --- a/ui (gen4)/lib/jli.js +++ b/ui (gen4)/lib/jli.js @@ -550,6 +550,73 @@ var getElementTransitionDuration = makeCSSVendorAttrGetter( parseInt) +// Get relative offset... +// +// This is like jQuery.offset() but takes into account: +// - scale +// - origin +// - actual relative offset +// +// point can be: +// - { +// top: , +// left: , +// [scale: 'screen'|'elem'|,] +// } +// - 'origin' (default) +// +// This expects: +// - the block is directly nested in the container +// - the block can be scaled +// - the block has an origin set +// +function getRelativeOffset(container, block, point){ + point = point == null ? {} : point + var l = point.left + var t = point.top + var scale = point.scale + + // get the input data... + var s = getElementScale(block) + var o = getElementOrigin(block) + // get only the value we need... + var W = container.width() + var H = container.height() + // we need this to make everything relative to the container... + var co = container.offset() + var offset = getElementOffset(block) + var bo = block.offset() + + scale = scale == 'screen' ? 1 + : scale == 'elem' ? s + : scale + + // normalize the l,t to element scale... + if(l != null && t != null){ + + // get only the value we need... + // NOTE: width and height are used to calculate the correction + // due to origin/scale... + var w = block.width() + var h = block.height() + o = { + // target offset scale... + top: t*scale + // set origin to top left corner of element (compensate + // for scaling)... + + (h - h*s) / (h / o.top), + left: l*scale + + (w - w*s) / (w / o.left), + } + } + + return { + top: offset.top + (H/2 - offset.top) - o.top, + left: offset.left + (W/2 - offset.left) - o.left, + } +} + + // NOTE: at this point this works only on the X axis... function setElementTransform(elem, offset, scale, duration){ elem = $(elem) diff --git a/ui (gen4)/ribbons.js b/ui (gen4)/ribbons.js index 2f270e8d..37ef121d 100755 --- a/ui (gen4)/ribbons.js +++ b/ui (gen4)/ribbons.js @@ -1488,6 +1488,14 @@ module.RibbonsPrototype = { // ...it's getting closer when enlarging and blows up when scale -> 0 offset -= (ot/scale - ot) + /* + var ribbon_set = this.viewer.find('.ribbon-set') + // XXX this needs the correct origin set before centering... + // XXX at scale this does not center corretly if ribbon is offset... + // ...calling it multiple times gets it closer and closer... + var offset = getRelativeOffset(this.viewer, ribbon_set).top + */ + console.log('### offset-top:', offset) setElementOffset(this.viewer.find('.ribbon-set'), 0, offset) diff --git a/ui (gen4)/viewer.js b/ui (gen4)/viewer.js index de1597be..9434d959 100755 --- a/ui (gen4)/viewer.js +++ b/ui (gen4)/viewer.js @@ -403,6 +403,11 @@ actions.Actions(Client, { // XXX is there a 'last' special case here??? var t = data.getImage(gid, r) if(t == null){ + var f = data.getImage('first', r) + // nothing found -- empty ribbon? + if(f == null){ + continue + } ribbons.centerImage(data.getImage('first', r), 'before') } else { ribbons.centerImage(t, 'after')