diff --git a/ui (gen4)/features/meta.js b/ui (gen4)/features/meta.js index 57c1f028..a4efd8dc 100755 --- a/ui (gen4)/features/meta.js +++ b/ui (gen4)/features/meta.js @@ -85,7 +85,8 @@ core.ImageGridFeatures.Feature('viewer-testing', [ //'ui-direct-control-jquery', // XXX BUG: on touch down and first move this gets offset by a distance // not sure why... - 'ui-direct-control-gsap', + // ...seems to be related to scaling + //'ui-direct-control-gsap', // experimental and optional features... //'auto-single-image', diff --git a/ui (gen4)/lib/tasks.js b/ui (gen4)/lib/tasks.js index 637610e0..6d3c2e2c 100755 --- a/ui (gen4)/lib/tasks.js +++ b/ui (gen4)/lib/tasks.js @@ -80,7 +80,7 @@ module.QueueActions = actions.Actions({ // A task can be either a Promise/A+ or a function. In the case of // a function this will work sync. // - // NOTE: these and task events are partly redundent.... + // NOTE: these and task events are partly redundant.... enqueue: ['', function(a, b, c){ // normalize arguments... @@ -190,12 +190,12 @@ module.QueueActions = actions.Actions({ // 1) run until the .__ready queue is completely depleted // This can occur for very fast or sync tasks, essentially // each iteration will replenish the .__running pool until there - // are not task to run. + // are no tasks to run. // 2) load the .__running pool and exit // The first task to finish will run this again to replenish // the pool. // - // NOTE: there can be no more that one instance running at a time. + // NOTE: there can be no more than one instance running at a time. // NOTE: if .state is not 'running' this will silently exit. // // XXX need to handle retries correctly, at this point all errors just diff --git a/ui (gen4)/lib/transform.js b/ui (gen4)/lib/transform.js new file mode 100755 index 00000000..d0aa8ed0 --- /dev/null +++ b/ui (gen4)/lib/transform.js @@ -0,0 +1,539 @@ +/********************************************************************** +* +* +* +**********************************************************************/ + +define(function(require){ var module = {} + +//var DEBUG = DEBUG != null ? DEBUG : true + +var object = require('lib/object') + + + +/*********************************************************************/ + +// convert a transform string to an object... +// +// Format: +// { +// : [, ...], +// ... +// } +// +// NOTE: this does not care about the semantics of the format, just the +// general structure... +var transform2obj = function(str){ + var res = {} + str = str || '' + // parse the string... + str + // split functions... + .split(/(\w+\([^\)]*)\)/) + // remove empty strings... + .filter(function(e){ return e.trim().length > 0}) + // split each function... + .map(function(e){ return e + // split args... + .split(/\s*[\(,\s]\s*/) + // cleanup... + .filter(function(e){ return e.trim().length > 0 }) }) + // build the structure... + .forEach(function(data){ + var func = data.shift() + var args = data + + res[func] = data + }) + return res +} + +// Convert the object similar in structure to the produced by +// transform2obj(..) to a transform string... +// +// NOTE: this does not care about the actual semantics of the format, +// e.g. argument units or function names... +var obj2transform = function(obj, filter){ + // build the filters... + filter = filter || [] + var keep = filter + .filter(function(f){ return f[0] != '-' }) + var remove = filter + .filter(function(f){ return f[0] == '-' }) + .map(function(f){ return f.slice(1) }) + + return Object.keys(obj) + // keep... + .filter(function(func){ + return keep.length == 0 || keep.indexOf(func) >= 0 }) + // remove... + .filter(function(func){ + return remove.indexOf(func) < 0 }) + .map(function(func){ + return func +'('+ obj[func].join(', ') + ')' + }) + .join(' ') +} + + +// XXX BUG: passing '' to an alias will clear ALL the aliased functions... +// ...should clear only full matches... +// XXX BUG: passing '' to a multi-arg function will clear the args but +// still keep the function... +// XXX BUG: setting a single arg alias will return string results... +// .x(123) -> ['123px'] -> must be [123] +// .x() -> [123] +// .translate3d(1,2,3) +// -> [1, 2, 3] +// NOTE: both set data correctly... +// XXX move the grammar out of this... +// XXX need: +// - a way to minimize this, i.e. get only full and minimal functions... +// - a way to get what was defined as-is... +// XXX STUB: .simplify(..) should be rewritten and be configurable... +// ...preferable work on write -- set the alias that already esists +// and ignore the rest... +// XXX make aliases collect and merge data, e.g. asking for scale with +// scaleX and scaleY set should return the combination of the two +// results... +// XXX not critical yet but will need to support for completeness... +// - transformStyle +// - prespective +// - prespectiveOrigin +// - backfaceVisibility +// XXX add transitions... +// XXX add support for vendor tags... +var transformEditor = function(){ + var editor = { + // data set... + data: {}, + + // function that directly edit the data... + __direct: {}, + + + // methods... + // XXX generate this... + simplify: function(filter){ + data = this.data + + // scale... + if(data.scale + && data.scale[0] == 1 + && data.scale[1] == 1){ delete data.scale } + if((data.scaleX||[1])[0] == 1){ delete data.scaleX } + if((data.scaleY||[1])[0] == 1){ delete data.scaleY } + + // translate... + if(data.translate + && data.translate.len == 2 + && parseFloat(data.translate[0]) == 0 + && parseFloat(data.translate[1]) == 0){ delete data.translate } + if(data.translate3d + && data.translate3d.len == 3 + && parseFloat(data.translate3d[0]) == 0 + && parseFloat(data.translate3d[1]) == 1 + && parseFloat(data.translate3d[2]) == 1){ delete data.translate3d } + if(parseFloat((data.translateX||[1])[0]) == 0){ delete data.translateX } + if(parseFloat((data.translateY||[1])[0]) == 0){ delete data.translateY } + if(parseFloat((data.translateZ||[1])[0]) == 0){ delete data.translateZ } + + // XXX rotate... + + // XXX skew... + + return this.data + }, + + toString: function(){ + //return obj2transform(this.data, args2array(arguments)) + var args = args2array(arguments) + return obj2transform(this.simplify(args), args) + }, + // NOTE: this will not build the alias data... + fromString: function(str){ + this.data = transform2obj(str) + return this + }, + // XXX use vendor prefix... + toElem: function(elem){ + var origin = this.data.origin || '' + var transform = this.toString('-origin') + + elem = elem instanceof jQuery ? elem.toArray() + : elem instanceof Array ? elem + : [elem] + + elem.forEach(function(e){ + e.style.transformOrigin = origin.join ? origin.join(' ') : origin + e.style.transform = transform + }) + + return this + }, + + // get data by attr names... + get: function(){ + var that = this + var attrs = arguments[0] instanceof Array ? + arguments[0] + : args2array(arguments) + var res = {} + + attrs.forEach(function(a){ + if(!(a in that)){ + return + } + var v = that[a]() + v = v.length == 1 ? v.pop() + : v.length == 0 ? undefined + : v + res[a] = v + }) + + if(attrs.length == 1){ + return res[attrs[0]] + } + + return res + }, + + // XXX use vendor prefix... + __init__: function(str){ + this.data = {} + + if(str != null){ + if(str instanceof jQuery){ + str = str[0] + } + if(str instanceof HTMLElement){ + var origin = str.style.transformOrigin + origin = origin.length > 0 ? ' origin('+ origin +')' : '' + + str = str.style.transform + origin + } + this.fromString(str) + } + }, + } + + var func = function(name, args, neutral){ + args = args || [] + editor.__direct[name] = function(val){ + var that = this + // set... + if(val != null && val != ''){ + val = val instanceof Array ? val : [val] + var data = this.data[name] = this.data[name] || [] + var res = [] + // add units and general processing... + val.map(function(arg, i){ + // special case, if an arg is undefined do not change it... + if(arg === undefined){ + return + } + var unit = args[i] || '' + data[i] = typeof(arg) == typeof(123) + || (typeof(arg) == typeof('str') + && /^[0-9\.]+$/.test(arg)) ? arg + unit + : arg == '' ? neutral + unit + : arg + res[i] = arg + }) + return res + + // delete... + } else if(val == ''){ + delete this.data[name] + + // get... + } else { + var res = (this.data[name] || []) + // remove default unit... + .map(function(arg, i){ + var unit = args[i] || '' + return arg.slice(-unit.length) == unit + || /^[0-9\.]+$/.test(arg)? + parseFloat(arg) + : arg + }) + return res + } + } + } + + var alias = function(spec, reduce, mode){ + reduce = reduce || 'last' + // can be: + // 'first' + // 'last' + // 'all' + mode = mode || 'first' + // alias runner... + var handler = function(alias, args){ + var that = this + // we only care for the source argument and only it will get + // passed next... + // NOTE: this is the name of the called alias... + var arg = args[spec[alias]] + + var aliases = Object.keys(spec) + + var r = reduce == 'sum' ? function(a, b){ return a + b } + : reduce == 'mul' ? function(a, b){ return a * b } + : reduce == 'last' ? function(a, b){ return b != null ? b : a } + : reduce + var n = reduce == 'sum' ? 0 + : reduce == 'mul' ? 1 + : 0 + + return aliases.map(function(k, j){ + var i = spec[k] + + // get state... + if(args.length == 0){ + var res = k in that.__direct ? + that.__direct[k].call(that) + : null + return res != null ? res[i] : res + } + + // prepare arguments... + var a = [] + a[i] = mode == 'first' && j == 0 ? arg + : mode == 'last' && j == aliases.length - 1 ? arg + : reduce == 'sum' ? 0 + : reduce == 'mul' ? 1 + : arg + + // do the call... + var res = k in that.__direct ? + that.__direct[k].call(that, a) + : null + return res != null ? res[i] : res + }) + .filter(function(e){ return e != null }) + .reduce(r, n) + // XXX for some magical reason this breaks if... + // t = transformEditor($('.ribbon-set')) + // t.x() // works ok + // var x = t.data + // t.x() // now this breaks because reduce is 0... + /* + .reduce(reduce == 'sum' ? function(a, b){ return a + b } + : reduce == 'mul' ? function(a, b){ return a * b } + : reduce == 'last' ? function(a, b){ return b != null ? b : a } + : reduce, + reduce == 'mul' ? 1 + : reduce = 'sum'? 0 + : 0) + */ + } + + // setup the aliases... + var aliases = Object.keys(spec) + + mode == 'last' && aliases.reverse() + + aliases.forEach(function(k){ + var i = spec[k] + + var func = i instanceof Function ? i : handler + + // NOTE: we will pass the called alias name to the handler + // via 'this'... + var f = editor[k] + var alias = editor[k] = f ? + // wrap the original alias... + // NOTE: this will iterate the overloaded aliases... + // i.e. this will iterate the arguments (width) while + // the handler(..) will iterate the aliases... + function(){ + var args = args2array(arguments) + // XXX do a full search through the alias values and merge results... + if(args.length == 0 && k in this.__direct){ + return this.__direct[k].call(this) + } + + var a = f.apply(this, args) + var b = func.call(this, k, args) + + if(k in this.__direct){ + return this.__direct[k].call(this) + } + return b + } + : function(){ + var args = args2array(arguments) + return func.call(this, k, args) + } + + alias.isAlias = true + alias.reduce = reduce + }) + } + + // XXX get these from grammar... + func('translate', ['px', 'px'], 0) + func('translate3d', ['px', 'px', 'px'], 0) + func('translateX', ['px'], 0) + func('translateY', ['px'], 0) + func('translateZ', ['px'], 0) + alias({ translate3d: 0, translate: 0, translateX: 0, x: 0 }, 'sum') + alias({ translate3d: 1, translate: 1, translateY: 0, y: 0, }, 'sum') + alias({ translate3d: 2, translateZ: 0, z: 0, }, 'sum') + + func('scale', ['', ''], 1) + //func('scale3d', ['', '', '']) + func('scaleX', [''], 1) + func('scaleY', [''], 1) + //func('scaleZ') + alias({ scale: 0, /*scale3d: 0,*/ scaleX: 0, }, 'mul') + alias({ scale: 1, /*scale3d: 1,*/ scaleY: 0, }, 'mul') + //alias({ scale3d: 2, scaleZ: 0, }, 'mul') + + // special case: single arg scale: scale(n) -> scale(n, n) + editor._scale = editor.scale + editor.scale = function(){ + if(arguments.length == 1 + && arguments[0] != '' + && arguments[0] != '='){ + return this._scale.call(this, arguments[0], arguments[0]) + } + var res = this._scale.apply(this, arguments) + // is this correct here??? + return res.length == 2 && res[0] == res[1] ? res[0] : res + } + + func('rotate', ['deg'], 0) + func('rotate3d', ['px', 'px', 'px', 'deg'], 0) + func('rotateX', ['deg'], 0) + func('rotateY', ['deg'], 0) + func('rotateZ', ['deg'], 0) + + func('matrix') // XXX ??? + func('matrix3d', [ + '', '', '', '', + '', '', '', '', + '', '', '', '', + '', '', '', '', + ]) + + func('skew', ['', ''], 0) + func('skewX', [''], 0) + func('skewY', [''], 0) + alias({skewX: 0, skew: 0}, 'sum') + alias({skewY: 0, skew: 1}, 'sum') + + func('perspective') + + + // non-transform functions... + func('origin', ['px', 'px', 'px'], 0) + + + // proxy the undefined in aliases functions... + Object.keys(editor.__direct).forEach(function(k){ + if(!(k in editor)){ + editor[k] = function(){ + var args = args2array(arguments) + editor.__direct[k].apply(this, args.length > 0 ? [args]: []) + return editor.__direct[k].call(this) + } + } + }) + + return editor +} + + +var TransformEditor = +module.TransformEditor = +object.makeConstructor('TransformEditor', transformEditor()) + +// XXX STUB: for testing only... +window.transformEditor = TransformEditor + + +// jQuery API for the TransformEditor... +jQuery.fn.transform = function(){ + var that = this + var elem = $(this)[0] + + var args = args2array(arguments) + // normalize... + args = args.length == 0 + || typeof(args[0]) == typeof('str') ? args + : args[0].constructor === Array + || args.length == 1 ? args[0] + : args + + // load the current state... + var transform = TransformEditor(elem) + + // get state... + if(args.constructor === Array){ + if(args.length == 0){ + // XXX get all attrs... + // XXX + + return + } + + // get requested attrs... + return transform.get(args) + + // set state... + } else { + // load user inputs... + Object.keys(args).forEach(function(k){ + if(!(k in transform)){ + return + } + + transform[k].apply(transform, args[k] instanceof Array ? args[k] : [args[k]]) + }) + + transform.toElem(this) + } + + return $(this) +} + + +// shorthands... +jQuery.fn.scale = function(value){ + if(arguments.length > 0){ + return $(this).transform({scale: args2array(arguments)}) + + } else { + return $(this).transform('scale') + } +} +// get element scale... +jQuery.fn.rscale = function(){ + var res = 1 + $(this).parents().toArray().forEach(function(e){ + res *= $(e).scale() || 1 + }) + return res +} +jQuery.fn.origin = function(a, b, c){ + if(a != null && b != null){ + return $(this).transform({origin: [a, b, c == null ? 0 : c]}) + + } else if(a == '' || a instanceof Array){ + return $(this).transform({origin: a}) + + } else { + return $(this).transform('origin') + } +} + + + + +/********************************************************************** +* vim:set ts=4 sw=4 : */ +return module }) diff --git a/ui (gen4)/lib/util.js b/ui (gen4)/lib/util.js index 6a0529fd..3089dbfe 100755 --- a/ui (gen4)/lib/util.js +++ b/ui (gen4)/lib/util.js @@ -8,8 +8,6 @@ define(function(require){ var module = {} //var DEBUG = DEBUG != null ? DEBUG : true -var object = require('lib/object') - /*********************************************************************/ @@ -79,529 +77,6 @@ function(path){ /*********************************************************************/ - - -// convert a transform string to an object... -// -// Format: -// { -// : [, ...], -// ... -// } -// -// NOTE: this does not care about the semantics of the format, just the -// general structure... -var transform2obj = function(str){ - var res = {} - str = str || '' - // parse the string... - str - // split functions... - .split(/(\w+\([^\)]*)\)/) - // remove empty strings... - .filter(function(e){ return e.trim().length > 0}) - // split each function... - .map(function(e){ return e - // split args... - .split(/\s*[\(,\s]\s*/) - // cleanup... - .filter(function(e){ return e.trim().length > 0 }) }) - // build the structure... - .forEach(function(data){ - var func = data.shift() - var args = data - - res[func] = data - }) - return res -} - -// Convert the object similar in structure to the produced by -// transform2obj(..) to a transform string... -// -// NOTE: this does not care about the actual semantics of the format, -// e.g. argument units or function names... -var obj2transform = function(obj, filter){ - // build the filters... - filter = filter || [] - var keep = filter - .filter(function(f){ return f[0] != '-' }) - var remove = filter - .filter(function(f){ return f[0] == '-' }) - .map(function(f){ return f.slice(1) }) - - return Object.keys(obj) - // keep... - .filter(function(func){ - return keep.length == 0 || keep.indexOf(func) >= 0 }) - // remove... - .filter(function(func){ - return remove.indexOf(func) < 0 }) - .map(function(func){ - return func +'('+ obj[func].join(', ') + ')' - }) - .join(' ') -} - - -// XXX BUG: passing '' to an alias will clear ALL the aliased functions... -// ...should clear only full matches... -// XXX BUG: passing '' to a multi-arg function will clear the args but -// still keep the function... -// XXX BUG: setting a single arg alias will return string results... -// .x(123) -> ['123px'] -> must be [123] -// .x() -> [123] -// .translate3d(1,2,3) -// -> [1, 2, 3] -// NOTE: both set data correctly... -// XXX move the grammar out of this... -// XXX need: -// - a way to minimize this, i.e. get only full and minimal functions... -// - a way to get what was defined as-is... -// XXX STUB: .simplify(..) should be rewritten and be configurable... -// ...preferable work on write -- set the alias that already esists -// and ignore the rest... -// XXX make aliases collect and merge data, e.g. asking for scale with -// scaleX and scaleY set should return the combination of the two -// results... -// XXX not critical yet but will need to support for completeness... -// - transformStyle -// - prespective -// - prespectiveOrigin -// - backfaceVisibility -// XXX add transitions... -// XXX add support for vendor tags... -var transformEditor = function(){ - var editor = { - // data set... - data: {}, - - // function that directly edit the data... - __direct: {}, - - - // methods... - // XXX generate this... - simplify: function(filter){ - data = this.data - - // scale... - if(data.scale - && data.scale[0] == 1 - && data.scale[1] == 1){ delete data.scale } - if((data.scaleX||[1])[0] == 1){ delete data.scaleX } - if((data.scaleY||[1])[0] == 1){ delete data.scaleY } - - // translate... - if(data.translate - && data.translate.len == 2 - && parseFloat(data.translate[0]) == 0 - && parseFloat(data.translate[1]) == 0){ delete data.translate } - if(data.translate3d - && data.translate3d.len == 3 - && parseFloat(data.translate3d[0]) == 0 - && parseFloat(data.translate3d[1]) == 1 - && parseFloat(data.translate3d[2]) == 1){ delete data.translate3d } - if(parseFloat((data.translateX||[1])[0]) == 0){ delete data.translateX } - if(parseFloat((data.translateY||[1])[0]) == 0){ delete data.translateY } - if(parseFloat((data.translateZ||[1])[0]) == 0){ delete data.translateZ } - - // XXX rotate... - - // XXX skew... - - return this.data - }, - - toString: function(){ - //return obj2transform(this.data, args2array(arguments)) - var args = args2array(arguments) - return obj2transform(this.simplify(args), args) - }, - // NOTE: this will not build the alias data... - fromString: function(str){ - this.data = transform2obj(str) - return this - }, - // XXX use vendor prefix... - toElem: function(elem){ - var origin = this.data.origin || '' - var transform = this.toString('-origin') - - elem = elem instanceof jQuery ? elem.toArray() - : elem instanceof Array ? elem - : [elem] - - elem.forEach(function(e){ - e.style.transformOrigin = origin.join ? origin.join(' ') : origin - e.style.transform = transform - }) - - return this - }, - - // get data by attr names... - get: function(){ - var that = this - var attrs = arguments[0] instanceof Array ? - arguments[0] - : args2array(arguments) - var res = {} - - attrs.forEach(function(a){ - if(!(a in that)){ - return - } - var v = that[a]() - v = v.length == 1 ? v.pop() - : v.length == 0 ? undefined - : v - res[a] = v - }) - - if(attrs.length == 1){ - return res[attrs[0]] - } - - return res - }, - - // XXX use vendor prefix... - __init__: function(str){ - this.data = {} - - if(str != null){ - if(str instanceof jQuery){ - str = str[0] - } - if(str instanceof HTMLElement){ - var origin = str.style.transformOrigin - origin = origin.length > 0 ? ' origin('+ origin +')' : '' - - str = str.style.transform + origin - } - this.fromString(str) - } - }, - } - - var func = function(name, args, neutral){ - args = args || [] - editor.__direct[name] = function(val){ - var that = this - // set... - if(val != null && val != ''){ - val = val instanceof Array ? val : [val] - var data = this.data[name] = this.data[name] || [] - var res = [] - // add units and general processing... - val.map(function(arg, i){ - // special case, if an arg is undefined do not change it... - if(arg === undefined){ - return - } - var unit = args[i] || '' - data[i] = typeof(arg) == typeof(123) - || (typeof(arg) == typeof('str') - && /^[0-9\.]+$/.test(arg)) ? arg + unit - : arg == '' ? neutral + unit - : arg - res[i] = arg - }) - return res - - // delete... - } else if(val == ''){ - delete this.data[name] - - // get... - } else { - var res = (this.data[name] || []) - // remove default unit... - .map(function(arg, i){ - var unit = args[i] || '' - return arg.slice(-unit.length) == unit - || /^[0-9\.]+$/.test(arg)? - parseFloat(arg) - : arg - }) - return res - } - } - } - - var alias = function(spec, reduce, mode){ - reduce = reduce || 'last' - // can be: - // 'first' - // 'last' - // 'all' - mode = mode || 'first' - // alias runner... - var handler = function(alias, args){ - var that = this - // we only care for the source argument and only it will get - // passed next... - // NOTE: this is the name of the called alias... - var arg = args[spec[alias]] - - var aliases = Object.keys(spec) - - var r = reduce == 'sum' ? function(a, b){ return a + b } - : reduce == 'mul' ? function(a, b){ return a * b } - : reduce == 'last' ? function(a, b){ return b != null ? b : a } - : reduce - var n = reduce == 'sum' ? 0 - : reduce == 'mul' ? 1 - : 0 - - return aliases.map(function(k, j){ - var i = spec[k] - - // get state... - if(args.length == 0){ - var res = k in that.__direct ? - that.__direct[k].call(that) - : null - return res != null ? res[i] : res - } - - // prepare arguments... - var a = [] - a[i] = mode == 'first' && j == 0 ? arg - : mode == 'last' && j == aliases.length - 1 ? arg - : reduce == 'sum' ? 0 - : reduce == 'mul' ? 1 - : arg - - // do the call... - var res = k in that.__direct ? - that.__direct[k].call(that, a) - : null - return res != null ? res[i] : res - }) - .filter(function(e){ return e != null }) - .reduce(r, n) - // XXX for some magical reason this breaks if... - // t = transformEditor($('.ribbon-set')) - // t.x() // works ok - // var x = t.data - // t.x() // now this breaks because reduce is 0... - /* - .reduce(reduce == 'sum' ? function(a, b){ return a + b } - : reduce == 'mul' ? function(a, b){ return a * b } - : reduce == 'last' ? function(a, b){ return b != null ? b : a } - : reduce, - reduce == 'mul' ? 1 - : reduce = 'sum'? 0 - : 0) - */ - } - - // setup the aliases... - var aliases = Object.keys(spec) - - mode == 'last' && aliases.reverse() - - aliases.forEach(function(k){ - var i = spec[k] - - var func = i instanceof Function ? i : handler - - // NOTE: we will pass the called alias name to the handler - // via 'this'... - var f = editor[k] - var alias = editor[k] = f ? - // wrap the original alias... - // NOTE: this will iterate the overloaded aliases... - // i.e. this will iterate the arguments (width) while - // the handler(..) will iterate the aliases... - function(){ - var args = args2array(arguments) - // XXX do a full search through the alias values and merge results... - if(args.length == 0 && k in this.__direct){ - return this.__direct[k].call(this) - } - - var a = f.apply(this, args) - var b = func.call(this, k, args) - - if(k in this.__direct){ - return this.__direct[k].call(this) - } - return b - } - : function(){ - var args = args2array(arguments) - return func.call(this, k, args) - } - - alias.isAlias = true - alias.reduce = reduce - }) - } - - // XXX get these from grammar... - func('translate', ['px', 'px'], 0) - func('translate3d', ['px', 'px', 'px'], 0) - func('translateX', ['px'], 0) - func('translateY', ['px'], 0) - func('translateZ', ['px'], 0) - alias({ translate3d: 0, translate: 0, translateX: 0, x: 0 }, 'sum') - alias({ translate3d: 1, translate: 1, translateY: 0, y: 0, }, 'sum') - alias({ translate3d: 2, translateZ: 0, z: 0, }, 'sum') - - func('scale', ['', ''], 1) - //func('scale3d', ['', '', '']) - func('scaleX', [''], 1) - func('scaleY', [''], 1) - //func('scaleZ') - alias({ scale: 0, /*scale3d: 0,*/ scaleX: 0, }, 'mul') - alias({ scale: 1, /*scale3d: 1,*/ scaleY: 0, }, 'mul') - //alias({ scale3d: 2, scaleZ: 0, }, 'mul') - - // special case: single arg scale: scale(n) -> scale(n, n) - editor._scale = editor.scale - editor.scale = function(){ - if(arguments.length == 1 - && arguments[0] != '' - && arguments[0] != '='){ - return this._scale.call(this, arguments[0], arguments[0]) - } - var res = this._scale.apply(this, arguments) - // is this correct here??? - return res.length == 2 && res[0] == res[1] ? res[0] : res - } - - func('rotate', ['deg'], 0) - func('rotate3d', ['px', 'px', 'px', 'deg'], 0) - func('rotateX', ['deg'], 0) - func('rotateY', ['deg'], 0) - func('rotateZ', ['deg'], 0) - - func('matrix') // XXX ??? - func('matrix3d', [ - '', '', '', '', - '', '', '', '', - '', '', '', '', - '', '', '', '', - ]) - - func('skew', ['', ''], 0) - func('skewX', [''], 0) - func('skewY', [''], 0) - alias({skewX: 0, skew: 0}, 'sum') - alias({skewY: 0, skew: 1}, 'sum') - - func('perspective') - - - // non-transform functions... - func('origin', ['px', 'px', 'px'], 0) - - - // proxy the undefined in aliases functions... - Object.keys(editor.__direct).forEach(function(k){ - if(!(k in editor)){ - editor[k] = function(){ - var args = args2array(arguments) - editor.__direct[k].apply(this, args.length > 0 ? [args]: []) - return editor.__direct[k].call(this) - } - } - }) - - return editor -} - - -var TransformEditor = -module.TransformEditor = -object.makeConstructor('TransformEditor', transformEditor()) - -// XXX STUB: for testing only... -window.transformEditor = TransformEditor - - -// jQuery API for the TransformEditor... -jQuery.fn.transform = function(){ - var that = this - var elem = $(this)[0] - - var args = args2array(arguments) - // normalize... - args = args.length == 0 - || typeof(args[0]) == typeof('str') ? args - : args[0].constructor === Array - || args.length == 1 ? args[0] - : args - - // load the current state... - var transform = TransformEditor(elem) - - // get state... - if(args.constructor === Array){ - if(args.length == 0){ - // XXX get all attrs... - // XXX - - return - } - - // get requested attrs... - return transform.get(args) - - // set state... - } else { - // load user inputs... - Object.keys(args).forEach(function(k){ - if(!(k in transform)){ - return - } - - transform[k].apply(transform, args[k] instanceof Array ? args[k] : [args[k]]) - }) - - transform.toElem(this) - } - - return $(this) -} - - -// shorthands... -jQuery.fn.scale = function(value){ - if(arguments.length > 0){ - return $(this).transform({scale: args2array(arguments)}) - - } else { - return $(this).transform('scale') - } -} -// get element scale... -jQuery.fn.rscale = function(){ - var res = 1 - $(this).parents().toArray().forEach(function(e){ - res *= $(e).scale() || 1 - }) - return res -} -jQuery.fn.origin = function(a, b, c){ - if(a != null && b != null){ - return $(this).transform({origin: [a, b, c == null ? 0 : c]}) - - } else if(a == '' || a instanceof Array){ - return $(this).transform({origin: a}) - - } else { - return $(this).transform('origin') - } -} - - - -//--------------------------------------------------------------------- - // XXX experiment jQuery.fn._drag = function(){ var dragging = false @@ -614,7 +89,7 @@ jQuery.fn._drag = function(){ px = evt.clientX px = evt.clientY - s = elem.getscale() + s = elem.rscale() }) .on('mousemove touchmove', function(evt){ if(!dragging){ diff --git a/ui (gen4)/ribbons.js b/ui (gen4)/ribbons.js index c11c9d9b..6822dbd5 100755 --- a/ui (gen4)/ribbons.js +++ b/ui (gen4)/ribbons.js @@ -13,6 +13,7 @@ define(function(require){ var module = {} //require('ext-lib/jquery') var util = require('lib/util') +var transform = require('lib/transform') var object = require('lib/object') var data = require('data')