From ab7f0a77e6ce0b0c923e43e03066e59561e4a734 Mon Sep 17 00:00:00 2001 From: "Alex A. Naanou" Date: Sat, 20 May 2017 03:59:11 +0300 Subject: [PATCH] cleanup and refactoring... Signed-off-by: Alex A. Naanou --- ui (gen4)/features/meta.js | 2 - ui (gen4)/features/ui-ribbons.js | 70 +++- ui (gen4)/features/ui-virtual-dom.js | 29 +- ui (gen4)/features/ui.js | 78 +---- ui (gen4)/imagegrid/ribbons.js | 457 ++++++++++++++------------- ui (gen4)/package.json | 1 + 6 files changed, 313 insertions(+), 324 deletions(-) diff --git a/ui (gen4)/features/meta.js b/ui (gen4)/features/meta.js index dbd4e23a..1b3ffdd3 100755 --- a/ui (gen4)/features/meta.js +++ b/ui (gen4)/features/meta.js @@ -78,7 +78,6 @@ core.ImageGridFeatures.Feature('viewer-testing', [ // features... 'ui-cursor', - 'ui-animation', 'ui-single-image', 'ui-partial-ribbons', @@ -112,7 +111,6 @@ core.ImageGridFeatures.Feature('viewer-testing', [ 'ui-progress', 'ui-status-log', 'ui-scale', - 'ui-animation', 'ui-bounds-indicators', 'ui-current-image-indicator', // NOTE: only one of these can be set... diff --git a/ui (gen4)/features/ui-ribbons.js b/ui (gen4)/features/ui-ribbons.js index 8dd863c4..ad7fa461 100755 --- a/ui (gen4)/features/ui-ribbons.js +++ b/ui (gen4)/features/ui-ribbons.js @@ -1,6 +1,13 @@ /********************************************************************** * * +* Features: +* - ui-ribbons-render +* - ui-ribbons-edit-render +* - ui-partial-ribbons +* - ui-animation +* manage UI non-css animations... +* * **********************************************************************/ ((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) @@ -433,9 +440,10 @@ core.ImageGridFeatures.Feature({ tag: 'ui-ribbons-render', exclusive: ['ui-render'], depends: [ - // XXX + 'base', ], suggested: [ + 'ui-animation', 'ui-ribbons-edit-render', ], @@ -743,6 +751,66 @@ core.ImageGridFeatures.Feature({ +/*********************************************************************/ +// Animation... + +// XXX at this point this does not support target lists... +// XXX shift up/down to new ribbon is not too correct... +// XXX depends on .ribbons.makeShadow(..)... +var ShiftAnimation = +module.ShiftAnimation = core.ImageGridFeatures.Feature({ + title: '', + doc: '', + + tag: 'ui-animation', + depends: [ + 'ui-ribbons-render', + ], + + config: { + // XXX make this duration... + 'shadow-animation-delay': 200, + 'shadow-animation-start-delay': 0, + }, + + handlers: [ + //['shiftImageUp.pre shiftImageDown.pre ' + // +'travelImageUp.pre travelImageDown.pre', + ['shiftImageUp.pre shiftImageDown.pre', + function(target){ + // XXX do not do target lists... + if(target != null && target.constructor === Array + // do not animate in single image mode... + && this.toggleSingleImage('?') == 'on'){ + return + } + var s = this.ribbons.makeShadow(target, true, + // XXX make this duration... + this.config['shadow-animation-delay'], + this.config['shadow-animation-start-delay']) + return function(){ s() } + }], + // NOTE: this will keep the shadow in place -- the shadow will not + // go to the mountain, the mountain will come to the shadow ;) + ['shiftImageLeft.pre shiftImageRight.pre', + function(target){ + // XXX do not do target lists... + if(target != null && target.constructor === Array + // do not animate in single image mode... + && this.toggleSingleImage('?') == 'on'){ + return + } + var s = this.ribbons.makeShadow(target, undefined, + // XXX make this duration... + this.config['shadow-animation-delay'], + this.config['shadow-animation-start-delay']) + return function(){ s() } + }], + ], +}) + + + /********************************************************************** * vim:set ts=4 sw=4 : */ return module }) diff --git a/ui (gen4)/features/ui-virtual-dom.js b/ui (gen4)/features/ui-virtual-dom.js index 180a5011..e21c6bc7 100755 --- a/ui (gen4)/features/ui-virtual-dom.js +++ b/ui (gen4)/features/ui-virtual-dom.js @@ -15,6 +15,8 @@ var features = require('lib/features') var core = require('features/core') +var ribbons = require('imagegrid/ribbons') + /*********************************************************************/ @@ -26,7 +28,9 @@ var core = require('features/core') var VirtualDOMRibbonsClassPrototype = { // XXX ??? } +VirtualDOMRibbonsClassPrototype.__proto__ = ribbons.BaseRibbons.prototype.__proto__ +// XXX make this ribbons.BaseRibbons compatible.... var VirtualDOMRibbonsPrototype = { // XXX this is a circular ref -- I do not like it... parent: null, @@ -49,29 +53,6 @@ var VirtualDOMRibbonsPrototype = { // } state: null, - - // XXX reuse these from ribbons??? - preventTransitions: function(){ - }, - restoreTransitions: function(){ - }, - elemGID: function(){ - }, - getImage: function(){ - }, - getImageByPosition: function(){ - }, - getRibbon: function(){ - }, - getVisibleImageSize: function(){ - }, - focusImage: function(){ - }, - px2vmin: function(){ - }, - // ... - - // constructors... makeView: function(state, initial){ state = state || {} @@ -362,6 +343,8 @@ var VirtualDOMRibbonsPrototype = { this.parent = parent || this.parent }, } +VirtualDOMRibbonsPrototype.__proto__ = ribbons.BaseRibbons.prototype + var VirtualDOMRibbons = module.VirtualDOMRibbons = diff --git a/ui (gen4)/features/ui.js b/ui (gen4)/features/ui.js index c5a01b7d..9be37c45 100755 --- a/ui (gen4)/features/ui.js +++ b/ui (gen4)/features/ui.js @@ -9,8 +9,6 @@ * maintain configuration state in local storage * - ui-url-hash * handle .location.hash -* - ui-animation -* manage UI non-css animations... * - ui-cursor * - ui-control * touch/mouse control mechanics @@ -48,9 +46,11 @@ var base = require('features/base') /*********************************************************************/ // Viewer (widget/interface)... // +// // This requires a 'ui-render' family feature to be present // // Expected render API is: +// XXX do we actually need this or should we directly use .ribbons.scale()??? // Get/set view scale... // .viewScale() // .viewScale('?') @@ -93,7 +93,7 @@ var base = require('features/base') // .updateRibbon(target) // -> this // -// Generic .ribbons API (introspection): +// Base .ribbons API (see: ribbons.BaseRibbons): // .ribbons.getImage(..) // -> image // @@ -231,6 +231,7 @@ module.ViewerActions = actions.Actions({ // Scaling... // // NOTE: .screenwidth / .screenheight are measured in square image blocks... + // XXX do we actually need this or should we directly use .ribbons.scale()??? get scale(){ return this.viewScale() }, set scale(s){ @@ -748,15 +749,6 @@ module.Viewer = core.ImageGridFeatures.Feature({ -/*********************************************************************/ -// User interfaces for different base features... - - -// XXX tag dialogs... -// XXX - - - /*********************************************************************/ // Utilities and Services... @@ -992,64 +984,6 @@ module.URLHash = core.ImageGridFeatures.Feature({ -/*********************************************************************/ -// Animation... - -// XXX at this point this does not support target lists... -// XXX shift up/down to new ribbon is not too correct... -// XXX depends on .ribbons... -var ShiftAnimation = -module.ShiftAnimation = core.ImageGridFeatures.Feature({ - title: '', - doc: '', - - tag: 'ui-animation', - depends: ['ui'], - - config: { - // XXX make this duration... - 'shadow-animation-delay': 200, - 'shadow-animation-start-delay': 0, - }, - - handlers: [ - //['shiftImageUp.pre shiftImageDown.pre ' - // +'travelImageUp.pre travelImageDown.pre', - ['shiftImageUp.pre shiftImageDown.pre', - function(target){ - // XXX do not do target lists... - if(target != null && target.constructor === Array - // do not animate in single image mode... - && this.toggleSingleImage('?') == 'on'){ - return - } - var s = this.ribbons.makeShadow(target, true, - // XXX make this duration... - this.config['shadow-animation-delay'], - this.config['shadow-animation-start-delay']) - return function(){ s() } - }], - // NOTE: this will keep the shadow in place -- the shadow will not - // go to the mountain, the mountain will come to the shadow ;) - ['shiftImageLeft.pre shiftImageRight.pre', - function(target){ - // XXX do not do target lists... - if(target != null && target.constructor === Array - // do not animate in single image mode... - && this.toggleSingleImage('?') == 'on'){ - return - } - var s = this.ribbons.makeShadow(target, undefined, - // XXX make this duration... - this.config['shadow-animation-delay'], - this.config['shadow-animation-start-delay']) - return function(){ s() } - }], - ], -}) - - - /*********************************************************************/ // Mouse... // @@ -1310,6 +1244,7 @@ module.Cursor = core.ImageGridFeatures.Feature({ // XXX how should multiple long interactions be handled?? // XXX revise... // +// NOTE: modifies .ribbons -- event handlers, attrs, classes... (XXX) // NOTE: for legacy stuff see: features/ui-legacy.js // // XXX add option to block click actions on focus... @@ -1317,7 +1252,6 @@ module.Cursor = core.ImageGridFeatures.Feature({ // system-wide... // XXX STUB: needs more thought.... -// XXX depends on .ribbons... var ControlActions = actions.Actions({ config: { 'control-mode': 'indirect', @@ -2109,7 +2043,7 @@ module.FailsafeDevTools = core.ImageGridFeatures.Feature({ /*********************************************************************/ -// XXX depends on .ribbons... +// NOTE: this updates the current image block CSS... var PreviewFilters module.PreviewFilters = core.ImageGridFeatures.Feature({ title: '', diff --git a/ui (gen4)/imagegrid/ribbons.js b/ui (gen4)/imagegrid/ribbons.js index f3ea63ac..3cabc883 100755 --- a/ui (gen4)/imagegrid/ribbons.js +++ b/ui (gen4)/imagegrid/ribbons.js @@ -33,7 +33,7 @@ var RIBBON = '.ribbon:not(.clone)' /*********************************************************************/ // -// This expects the following HTML structure... +// This expects/builds the following HTML structure... // // Unpopulated: // @@ -45,37 +45,43 @@ var RIBBON = '.ribbon:not(.clone)' // //
//
-//
-//
-//
+//
+//
+//
+//
+// ... +//
+//
+//
+// +// +//
+// +// +//
+//
+// +//
+// +// ... +//
// ... //
-//
-//
-// -// -//
-// -// -//
-//
-// -//
-// -// ... -//
-// ... //
//
// // // NOTE: there can be only one .ribbon-set element. +// NOTE: other elements can exist in the structure, but as long as they +// use different CSS classes they are ignored by the system, note +// that such elements may affect alignment and placement though this +// should be obvious ;) // // // /*********************************************************************/ -var RibbonsClassPrototype = { +var BaseRibbonsClassPrototype = { // utils... px2v: function(px, mode){ var ref = mode == 'vw' ? @@ -116,55 +122,9 @@ var RibbonsClassPrototype = { // this removes the extra quots... .replace(/^"(.*)"$/g, '$1')) }, - - // DOM Constructors... - // NOTE: these will return unattached objects... - createViewer: function(){ - return $('
') - .addClass('viewer') - .attr('tabindex', 0) - //.append($('
') - // .addClass('ribbon-set')) - }, - // XXX NOTE: quots removal might render this incompatible with older data formats... - createRibbon: function(gids){ - gids = gids || [] - gids = gids.constructor !== Array ? [gids] : gids - var that = this - return $(gids.map(function(gid){ - gid = gid != null ? gid+'' : gid - - return that.elemGID($('
') - .addClass('ribbon'), gid)[0] - //return $('
') - // .addClass('ribbon-container') - // .append(that.elemGID($('
') - // .addClass('ribbon'), gid))[0] - })) - }, - // XXX NOTE: quots removal might render this incompatible with older data formats... - createImage: function(gids){ - gids = gids || [] - gids = gids.constructor !== Array ? [gids] : gids - var that = this - return $(gids.map(function(gid){ - gid = gid != null ? gid+'' : gid - return that.elemGID($('
') - .addClass('image'), gid)[0] - })) - }, - createMark: function(cls, gid){ - gid = gid != null ? gid+'' : gid - return this.elemGID($('
') - .addClass(cls), gid) - }, } - - -//--------------------------------------------------------------------- - -var IntrospectiveRibbonsPrototype = { +var BaseRibbonsPrototype = { // // .viewer (jQuery object) // @@ -178,15 +138,15 @@ var IntrospectiveRibbonsPrototype = { }, // utils... - px2v: RibbonsClassPrototype.px2v, - px2vw: RibbonsClassPrototype.px2vw, - px2vh: RibbonsClassPrototype.px2vh, - px2vmin: RibbonsClassPrototype.px2vmin, - px2vmax: RibbonsClassPrototype.px2vmax, + px2v: BaseRibbonsClassPrototype.px2v, + px2vw: BaseRibbonsClassPrototype.px2vw, + px2vh: BaseRibbonsClassPrototype.px2vh, + px2vmin: BaseRibbonsClassPrototype.px2vmin, + px2vmax: BaseRibbonsClassPrototype.px2vmax, // Generic getters... - elemGID: RibbonsClassPrototype.elemGID, + elemGID: BaseRibbonsClassPrototype.elemGID, get parent(){ @@ -668,28 +628,216 @@ var IntrospectiveRibbonsPrototype = { return this.viewer.find(RIBBON).index(this.getRibbon(target)) }, + // Image info... + // + // NOTE: these are simply shorthands to image attr access... getImageRotation: function(target){ return (this.getImage(target).attr('orientation') || 0)*1 }, getImageFlip: function(target){ return (this.getImage(target).attr('flipped') || '') .split(',') .map(function(e){ return e.trim() }) - .filter(function(e){ return e != '' }) + .filter(function(e){ return e != '' }) }, + + + // UI manipulation... + + // Compensate for viewer proportioned and rotated images. + // + // This will set the margins so as to make the rotated image offset the + // same space as it is occupying visually... + // + // NOTE: this is not needed for square image blocks. + // NOTE: if an image block is square, this will remove the margins. + // + // XXX this does the same job as features/ui-single-image.js' .updateImageProportions(..) + _calcImageProportions: function(image, W, H, w, h, o){ + image = image instanceof jQuery ? image[0] : image + + //var s = (!w || !h) ? getComputedStyle(image) : null + //w = w || parseFloat(s.width) + //h = h || parseFloat(s.height) + //w = this.px2vmin(w || image.offsetWidth) + //h = this.px2vmin(h || image.offsetHeight) + w = w || image.offsetWidth + h = h || image.offsetHeight + + // non-square image... + if(w != h){ + W = W || this.viewer.innerWidth() + H = H || this.viewer.innerHeight() + o = o || image.getAttribute('orientation') || 0 + + var viewer_p = W > H ? 'landscape' : 'portrait' + + // NOTE: we need to use the default (CSS) value when + // possible, to avoid sizing issues... + var dfl_w = image.style.width == '' + var dfl_h = image.style.height == '' + + var image_p = w > h ? 'landscape' : 'portrait' + + // when the image is turned 90deg/270deg and its + // proportions are the same as the screen... + if((o == 90 || o == 270) && image_p == viewer_p){ + return { + width: dfl_h ? '' : (this.px2vmin(h) + 'vmin'), + height: dfl_w ? '' : (this.px2vmin(w) + 'vmin'), + margin: this.px2vmin(-((w - h)/2)) +'vmin '+ this.px2vmin((w - h)/2) + 'vmin', + } + + } else if((o == 0 || o == 180) && image_p != viewer_p){ + return { + width: dfl_h ? '' : (this.px2vmin(h) + 'vmin'), + height: dfl_w ? '' : (this.px2vmin(w) + 'vmin'), + margin: '', + } + } + + // square image... + } else { + return { + width: '', + height: '', + margin: '', + } + } + }, + correctImageProportionsForRotation: function(images, W, H){ + var that = this + W = W || this.viewer.innerWidth() + H = H || this.viewer.innerHeight() + + var images = images || this.viewer.find(IMAGE) + + return $(images).each(function(i, e){ + var data = that._calcImageProportions(this, W, H) + + data + && $(this).css(data) + }) + }, + + // center a ribbon vertically... + // + // Center current ribbon... + // .centerRibbon() + // -> Ribbons + // + // Center specific ribbon... + // .centerRibbon(image) + // .centerRibbon(ribbon) + // -> Ribbons + // + centerRibbon: function(target){ + var ribbon = this.getRibbon(target) + var locator = this.getRibbonLocator() + + if(locator.length == 0 || ribbon.length == 0){ + return this + } + + var t = ribbon[0].offsetTop + var h = ribbon[0].offsetHeight + + locator.transform({ x: 0, y: this.px2vh(-(t + h/2)) + 'vh', z: 0 }) + + return this + }, + + // center an image horizontally... + // + // Center current ribbon/image... + // .centerImage() + // -> Ribbons + // + // Center specific image... + // .centerImage(image) + // .centerImage(image, 'center') + // -> Ribbons + // + // Center ribbon before/after an image... + // .centerImage(image, 'before') + // .centerImage(image, 'after') + // -> Ribbons + // + centerImage: function(target, mode){ + target = this.getImage(target) + var ribbon = this.getRibbon(target) + + if(ribbon.length == 0){ + return this + } + + var l = target[0].offsetLeft + var w = target[0].offsetWidth + + var image_offset = mode == 'before' ? 0 + : mode == 'after' ? w + : w/2 + + ribbon.transform({x: -this.px2vmin(l + image_offset) + 'vmin', y: 0, z: 0}) + + return this }, } -var IntrospectiveRibbons = -module.IntrospectiveRibbons = -object.makeConstructor('IntrospectiveRibbons', - RibbonsClassPrototype, - IntrospectiveRibbonsPrototype) +var BaseRibbons = +module.BaseRibbons = +object.makeConstructor('BaseRibbons', + BaseRibbonsClassPrototype, + BaseRibbonsPrototype) //--------------------------------------------------------------------- -// NOTE: this is a low level interface, not a set of actions... +var RibbonsClassPrototype = { + // DOM Constructors... + // NOTE: these will return unattached objects... + createViewer: function(){ + return $('
') + .addClass('viewer') + .attr('tabindex', 0) + //.append($('
') + // .addClass('ribbon-set')) + }, + // XXX NOTE: quots removal might render this incompatible with older data formats... + createRibbon: function(gids){ + gids = gids || [] + gids = gids.constructor !== Array ? [gids] : gids + var that = this + return $(gids.map(function(gid){ + gid = gid != null ? gid+'' : gid + + return that.elemGID($('
') + .addClass('ribbon'), gid)[0] + //return $('
') + // .addClass('ribbon-container') + // .append(that.elemGID($('
') + // .addClass('ribbon'), gid))[0] + })) + }, + // XXX NOTE: quots removal might render this incompatible with older data formats... + createImage: function(gids){ + gids = gids || [] + gids = gids.constructor !== Array ? [gids] : gids + var that = this + return $(gids.map(function(gid){ + gid = gid != null ? gid+'' : gid + return that.elemGID($('
') + .addClass('image'), gid)[0] + })) + }, + createMark: function(cls, gid){ + gid = gid != null ? gid+'' : gid + return this.elemGID($('
') + .addClass(cls), gid) + }, +} +RibbonsClassPrototype.__proto__ = BaseRibbonsClassPrototype + var RibbonsPrototype = { // XXX clone: function(){ @@ -2337,147 +2485,6 @@ var RibbonsPrototype = { return this.flipImage(target, 'horizontal', reference) }, - // UI manipulation... - - // Compensate for viewer proportioned and rotated images. - // - // This will set the margins so as to make the rotated image offset the - // same space as it is occupying visually... - // - // NOTE: this is not needed for square image blocks. - // NOTE: if an image block is square, this will remove the margins. - // - // XXX this does the same job as features/ui-single-image.js' .updateImageProportions(..) - _calcImageProportions: function(image, W, H, w, h, o){ - image = image instanceof jQuery ? image[0] : image - - //var s = (!w || !h) ? getComputedStyle(image) : null - //w = w || parseFloat(s.width) - //h = h || parseFloat(s.height) - //w = this.px2vmin(w || image.offsetWidth) - //h = this.px2vmin(h || image.offsetHeight) - w = w || image.offsetWidth - h = h || image.offsetHeight - - // non-square image... - if(w != h){ - W = W || this.viewer.innerWidth() - H = H || this.viewer.innerHeight() - o = o || image.getAttribute('orientation') || 0 - - var viewer_p = W > H ? 'landscape' : 'portrait' - - // NOTE: we need to use the default (CSS) value when - // possible, to avoid sizing issues... - var dfl_w = image.style.width == '' - var dfl_h = image.style.height == '' - - var image_p = w > h ? 'landscape' : 'portrait' - - // when the image is turned 90deg/270deg and its - // proportions are the same as the screen... - if((o == 90 || o == 270) && image_p == viewer_p){ - return { - width: dfl_h ? '' : (this.px2vmin(h) + 'vmin'), - height: dfl_w ? '' : (this.px2vmin(w) + 'vmin'), - margin: this.px2vmin(-((w - h)/2)) +'vmin '+ this.px2vmin((w - h)/2) + 'vmin', - } - - } else if((o == 0 || o == 180) && image_p != viewer_p){ - return { - width: dfl_h ? '' : (this.px2vmin(h) + 'vmin'), - height: dfl_w ? '' : (this.px2vmin(w) + 'vmin'), - margin: '', - } - } - - // square image... - } else { - return { - width: '', - height: '', - margin: '', - } - } - }, - correctImageProportionsForRotation: function(images, W, H){ - var that = this - W = W || this.viewer.innerWidth() - H = H || this.viewer.innerHeight() - - var images = images || this.viewer.find(IMAGE) - - return $(images).each(function(i, e){ - var data = that._calcImageProportions(this, W, H) - - data - && $(this).css(data) - }) - }, - - // center a ribbon vertically... - // - // Center current ribbon... - // .centerRibbon() - // -> Ribbons - // - // Center specific ribbon... - // .centerRibbon(image) - // .centerRibbon(ribbon) - // -> Ribbons - // - centerRibbon: function(target){ - var ribbon = this.getRibbon(target) - var locator = this.getRibbonLocator() - - if(locator.length == 0 || ribbon.length == 0){ - return this - } - - var t = ribbon[0].offsetTop - var h = ribbon[0].offsetHeight - - locator.transform({ x: 0, y: this.px2vh(-(t + h/2)) + 'vh', z: 0 }) - - return this - }, - - // center an image horizontally... - // - // Center current ribbon/image... - // .centerImage() - // -> Ribbons - // - // Center specific image... - // .centerImage(image) - // .centerImage(image, 'center') - // -> Ribbons - // - // Center ribbon before/after an image... - // .centerImage(image, 'before') - // .centerImage(image, 'after') - // -> Ribbons - // - centerImage: function(target, mode){ - target = this.getImage(target) - var ribbon = this.getRibbon(target) - - if(ribbon.length == 0){ - return this - } - - var l = target[0].offsetLeft - var w = target[0].offsetWidth - - var image_offset = mode == 'before' ? 0 - : mode == 'after' ? w - : w/2 - - ribbon.transform({x: -this.px2vmin(l + image_offset) + 'vmin', y: 0, z: 0}) - - return this - }, - // Fit image to view... // // If n is given this will fit n images (default: 1) @@ -2539,15 +2546,13 @@ var RibbonsPrototype = { return this }, } - -RibbonsPrototype.__proto__ = IntrospectiveRibbonsPrototype - +RibbonsPrototype.__proto__ = BaseRibbonsPrototype var Ribbons = module.Ribbons = object.makeConstructor('Ribbons', - RibbonsClassPrototype, - RibbonsPrototype) + RibbonsClassPrototype, + RibbonsPrototype) diff --git a/ui (gen4)/package.json b/ui (gen4)/package.json index 73dfd71a..919357fc 100755 --- a/ui (gen4)/package.json +++ b/ui (gen4)/package.json @@ -26,6 +26,7 @@ "ig-features": "^2.0.0", "ig-object": "^1.0.1", "openseadragon": "^2.1.0", + "preact": "^8.1.0", "react": "^15.5.4", "react-dom": "^15.5.4", "requirejs": "^2.1.23",