|
View:
New views
6 Messages
—
Rating Filter:
Alert me
|
|
|
Seven new functions for MochiKit.VisualBelow are the diffs from Visual.js which include four new functions for sliding elements on/off to the left/right and two for sliding pairs of elements together, one on and one off, and one for sliding pairs of elements in a direction relative to their position in the DOM. The diffs also include the changes I discussed in my previous post about issues with slideDown and blindDown. I have tested these on divs whose width are 100% of the browser window on both Firefox 3rc2 and Safari 3.1.1. I have not tested with any variation of IE. I also have not tested with divs with a smaller than 100% width though there's nothing to suggest it won't work right. Index: Visual.js =================================================================== --- Visual.js (revision 1383) +++ Visual.js (working copy) @@ -1431,14 +1431,16 @@ scaleContent: false, scaleX: false, scaleFrom: 0, - scaleMode: {originalHeight: s.getElementHeight(element), - originalWidth: s.getElementWidth(element)}, restoreAfterFinish: true, - afterSetupInternal: function (effect) { + beforeSetupInternal: function (effect) { elemClip = d.makeClipping(effect.element); - s.setStyle(effect.element, {height: '0px'}); s.showElement(effect.element); + effect.options.scaleMode = {originalHeight: s.getElementHeight(element), + originalWidth: s.getElementWidth(element)}; }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {height: '0px'}); + }, afterFinishInternal: function (effect) { d.undoClipping(effect.element, elemClip); } @@ -1582,18 +1584,20 @@ scaleContent: false, scaleX: false, scaleFrom: 0, - scaleMode: {originalHeight: s.getElementHeight(element), - originalWidth: s.getElementWidth(element)}, restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = {originalHeight: s.getElementHeight(element), + originalWidth: s.getElementWidth(element)}; + }, afterSetupInternal: function (effect) { d.makePositioned(effect.element); d.makePositioned(effect.element.firstChild); if (/Opera/.test(navigator.userAgent)) { s.setStyle(effect.element, {top: ''}); } - elemClip = d.makeClipping(effect.element); s.setStyle(effect.element, {height: '0px'}); - s.showElement(effect.element); }, afterUpdateInternal: function (effect) { s.setStyle(effect.element.firstChild, @@ -1665,7 +1669,450 @@ }, options); return new MochiKit.Visual.Scale(element, 0, options); }; +/** @id MochiKit.Visual.slideOnLeft */ +MochiKit.Visual.slideOnLeft = function (element, /* optional */ options) { + /*** + Slide an element on moving from right to left. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOnLeft must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + left: element.style.left, + innerWidth: element.firstChild.style.width + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 0, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element) + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, { + width: '0px', + left: effect.dims[1] + }); + s.setStyle(effect.element.firstChild, { + width: scaleMode.originalWidth + }); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {left: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element, { + left: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + d.undoClipping(effect.element, elemClip); + // IE will crash if child is undoPositioned first + if (/MSIE/.test(navigator.userAgent)) { + d.undoPositioned(effect.element); + d.undoPositioned(effect.element.firstChild); + } else { + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + } + s.setStyle(effect.element, { + height: originalStyle.height, + width: originalStyle.width, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + width: originalStyle.innerWidth + }); + } + }, options); + + return new MochiKit.Visual.Scale(element, 100, options); +} + +/** @id MochiKit.Visual.slideOnRight */ +MochiKit.Visual.slideOnRight = function (element, /* optional */ options) { + /*** + + Slide an element on moving from left to right. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOnRight must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + innerRight: element.firstChild.style.right, + innerWidth: element.firstChild.style.width + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 0, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element) + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {width: '0px'}); + s.setStyle(effect.element.firstChild, { + width: scaleMode.originalWidth, + right: effect.dims[1] + }); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {left: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element.firstChild, { + right: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + d.undoClipping(effect.element, elemClip); + // IE will crash if child is undoPositioned first + if (/MSIE/.test(navigator.userAgent)) { + d.undoPositioned(effect.element); + d.undoPositioned(effect.element.firstChild); + } else { + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + } + s.setStyle(effect.element, { + height: originalStyle.height, + width: originalStyle.width + }); + s.setStyle(effect.element.firstChild, { + right: originalStyle.innerRight, + width: originalStyle.innerWidth + }); + } + }, options); + + return new MochiKit.Visual.Scale(element, 100, options); +} + +/** @id MochiKit.Visual.slideOffLeft */ +MochiKit.Visual.slideOffLeft = function (element, /* optional */ options) { + /*** + + Slide an element off moving from right to left. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOffLeft must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + right: element.style.right, + left: element.style.left, + innerRight: element.firstChild.style.right + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 100, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element), + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {left: '0px'}); + s.setStyle(effect.element.firstChild, {width: scaleMode.originalWidth}); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {right: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element.firstChild, { + right: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + s.hideElement(effect.element); + d.undoClipping(effect.element, elemClip); + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + s.setStyle(effect.element, { + width: originalStyle.width, + height: originalStyle.height, + right: originalStyle.right, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + right: originalStyle.innerRight + }); + } + }, options); + return new MochiKit.Visual.Scale(element, 0, options); +}; + +/** @id MochiKit.Visual.slideOffRight */ +MochiKit.Visual.slideOffRight = function (element, /* optional */ options) { + /*** + + Slide an element off moving from left to right. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOffRight must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + right: element.style.right, + left: element.style.left, + innerWidth: element.firstChild.style.width + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 100, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element), + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {left: '0px'}); + s.setStyle(effect.element.firstChild, {width: scaleMode.originalWidth}); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {right: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element, { + left: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + s.hideElement(effect.element); + d.undoClipping(effect.element, elemClip); + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + s.setStyle(effect.element, { + width: originalStyle.width, + height: originalStyle.height, + right: originalStyle.right, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + width: originalStyle.innerWidth + }); + } + }, options); + return new MochiKit.Visual.Scale(element, 0, options); +}; + +/** @id MochiKit.Visual.slidePairLeft */ +MochiKit.Visual.slidePairLeft = function (elements, /* optional */ options) { + /*** + + Slide the first element off and the second element off from right to left. + + ***/ + if (elements[0] != elements[1]) { + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var v = MochiKit.Visual; + elements = [d.getElement(elements[0]), d.getElement(elements[1])]; + var parent = elements[1].parentNode; + var originalStyle = { + position: [ + elements[0].style.position, + elements[1].style.position + ], + parentWidth: parent.style.width, + parentHeight: parent.style.height + }; + options = b.update({ + beforeSetupInternal: function (effect) { + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.effects[0].element.parentNode, { + width: Math.max(s.getElementWidth(effect.effects[0].element), + s.getElementWidth(effect.effects[1].element)), + height: Math.max(s.getElementHeight(effect.effects[0].element), + s.getElementHeight(effect.effects[1].element)) + }); + s.setStyle(effect.effects[0].element, {position: 'absolute'}); + s.setStyle(effect.effects[1].element, {position: 'absolute'}); + }, + afterFinishInternal: function (effect) { + s.setStyle(effect.effects[0].element, { + position: originalStyle.position[0] + }); + s.setStyle(effect.effects[1].element, { + position: originalStyle.position[1] + }); + s.setStyle(parent, { + width: originalStyle.parentWidth, + height: originalStyle.parentHeight + }); + } + }, options); + return new v.Parallel( + [v.slideOffLeft(elements[0]), v.slideOnLeft(elements[1])], + options); + } else { + return null; + } +} + +/** @id MochiKit.Visual.slidePairRight */ +MochiKit.Visual.slidePairRight = function (elements, /* optional */ options) { + /*** + + Slide the first element off and the second element off from left to right. + + ***/ + if (elements[0] != elements[1]) { + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + elements = [d.getElement(elements[0]), d.getElement(elements[1])]; + var parent = elements[1].parentNode; + var originalStyle = { + position: [ + elements[0].style.position, + elements[1].style.position + ], + parentWidth: parent.style.width, + parentHeight: parent.style.height + }; + options = b.update({ + beforeSetupInternal: function (effect) { + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.effects[0].element.parentNode, { + width: Math.max(s.getElementWidth(effect.effects[0].element), + s.getElementWidth(effect.effects[1].element)), + height: Math.max(s.getElementHeight(effect.effects[0].element), + s.getElementHeight(effect.effects[1].element)) + }); + s.setStyle(effect.effects[0].element, {position: 'absolute'}); + s.setStyle(effect.effects[1].element, {position: 'absolute'}); + }, + afterFinishInternal: function (effect) { + s.setStyle(effect.effects[0].element, { + position: originalStyle.position[0] + }); + s.setStyle(effect.effects[1].element, { + position: originalStyle.position[1] + }); + s.setStyle(parent, { + width: originalStyle.parentWidth, + height: originalStyle.parentHeight + }); + } + }, options); + return new MochiKit.Visual.Parallel( + [slideOffRight(elements[0]), slideOnRight(elements[1])], + options); + } else { + return null; + } +} + +/** @id MochiKit.Visual.slidePairRight */ +MochiKit.Visual.slidePair = function (elements, /* optional */ options) { + /*** + + Slide the first element on and the second element off. Direction is based + on relative position of the two elements in the child node list. It assumes + both are siblings. + + ***/ + if (elements[0] != elements[1]) { + for (sibling = elements[0].nextSibling; + sibling && sibling != elements[1]; + sibling = sibling.nextSibling) { + } + if (sibling == elements[1]) { + return MochiKit.Visual.slidePairRight(elements, options); + } else { + return MochiKit.Visual.slidePairLeft(elements, options); + } + } else { + return null; + } +} + + // Bug in opera makes the TD containing this element expand for a instance // after finish /** @id MochiKit.Visual.squish */ @@ -1995,6 +2442,13 @@ "shake", "slideDown", "slideUp", + "slideOnLeft", + "slideOnRight", + "slideOffLeft", + "slideOffRight", + "slidePairLeft", + "slidePairRight", + "slidePair", "squish", "grow", "shrink", --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "MochiKit" group. To post to this group, send email to mochikit@... To unsubscribe from this group, send email to mochikit-unsubscribe@... For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~----------~----~----~----~------~----~------~--~--- |
|
|
Re: Seven new functions for MochiKit.VisualOk, had a couple visual glitches that are now fixed with the patch below: Index: Visual.js =================================================================== --- Visual.js (revision 1383) +++ Visual.js (working copy) @@ -1431,14 +1431,16 @@ scaleContent: false, scaleX: false, scaleFrom: 0, - scaleMode: {originalHeight: s.getElementHeight(element), - originalWidth: s.getElementWidth(element)}, restoreAfterFinish: true, - afterSetupInternal: function (effect) { + beforeSetupInternal: function (effect) { elemClip = d.makeClipping(effect.element); - s.setStyle(effect.element, {height: '0px'}); s.showElement(effect.element); + effect.options.scaleMode = {originalHeight: s.getElementHeight(element), + originalWidth: s.getElementWidth(element)}; }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {height: '0px'}); + }, afterFinishInternal: function (effect) { d.undoClipping(effect.element, elemClip); } @@ -1582,18 +1584,20 @@ scaleContent: false, scaleX: false, scaleFrom: 0, - scaleMode: {originalHeight: s.getElementHeight(element), - originalWidth: s.getElementWidth(element)}, restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = {originalHeight: s.getElementHeight(element), + originalWidth: s.getElementWidth(element)}; + }, afterSetupInternal: function (effect) { d.makePositioned(effect.element); d.makePositioned(effect.element.firstChild); if (/Opera/.test(navigator.userAgent)) { s.setStyle(effect.element, {top: ''}); } - elemClip = d.makeClipping(effect.element); s.setStyle(effect.element, {height: '0px'}); - s.showElement(effect.element); }, afterUpdateInternal: function (effect) { s.setStyle(effect.element.firstChild, @@ -1666,6 +1670,452 @@ return new MochiKit.Visual.Scale(element, 0, options); }; +/** @id MochiKit.Visual.slideOnLeft */ +MochiKit.Visual.slideOnLeft = function (element, /* optional */ options) { + /*** + + Slide an element on moving from right to left. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOnLeft must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + left: element.style.left, + innerWidth: element.firstChild.style.width + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 0, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element) + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, { + width: '0px', + left: effect.dims[1] + }); + s.setStyle(effect.element.firstChild, { + width: scaleMode.originalWidth + }); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {left: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element, { + left: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + d.undoClipping(effect.element, elemClip); + // IE will crash if child is undoPositioned first + if (/MSIE/.test(navigator.userAgent)) { + d.undoPositioned(effect.element); + d.undoPositioned(effect.element.firstChild); + } else { + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + } + s.setStyle(effect.element, { + height: originalStyle.height, + width: originalStyle.width, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + width: originalStyle.innerWidth + }); + } + }, options); + + return new MochiKit.Visual.Scale(element, 100, options); +} + +/** @id MochiKit.Visual.slideOnRight */ +MochiKit.Visual.slideOnRight = function (element, /* optional */ options) { + /*** + + Slide an element on moving from left to right. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOnRight must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + left: element.firstChild.style.left, + innerRight: element.firstChild.style.right, + innerWidth: element.firstChild.style.width + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 0, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element) + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, { + width: '0px', + left: '0px' + }); + s.setStyle(effect.element.firstChild, { + width: scaleMode.originalWidth, + right: effect.dims[1] + }); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element.firstChild, { + right: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + d.undoClipping(effect.element, elemClip); + // IE will crash if child is undoPositioned first + if (/MSIE/.test(navigator.userAgent)) { + d.undoPositioned(effect.element); + d.undoPositioned(effect.element.firstChild); + } else { + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + } + s.setStyle(effect.element, { + height: originalStyle.height, + width: originalStyle.width, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + right: originalStyle.innerRight, + width: originalStyle.innerWidth + }); + } + }, options); + + return new MochiKit.Visual.Scale(element, 100, options); +} + +/** @id MochiKit.Visual.slideOffLeft */ +MochiKit.Visual.slideOffLeft = function (element, /* optional */ options) { + /*** + + Slide an element off moving from right to left. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOffLeft must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + right: element.style.right, + left: element.style.left, + innerRight: element.firstChild.style.right + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 100, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element), + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {left: '0px'}); + s.setStyle(effect.element.firstChild, {width: scaleMode.originalWidth}); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {right: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element.firstChild, { + right: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + s.hideElement(effect.element); + d.undoClipping(effect.element, elemClip); + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + s.setStyle(effect.element, { + width: originalStyle.width, + height: originalStyle.height, + right: originalStyle.right, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + right: originalStyle.innerRight + }); + } + }, options); + return new MochiKit.Visual.Scale(element, 0, options); +}; + +/** @id MochiKit.Visual.slideOffRight */ +MochiKit.Visual.slideOffRight = function (element, /* optional */ options) { + /*** + + Slide an element off moving from left to right. + It must have a single inner child to work correctly + + ***/ + if (!element.hasChildNodes()) { + throw "MochiKit.Visual.slideOffRight must be used on a element with a child"; + } + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var elemClip; + element = d.getElement(element); + d.removeEmptyTextNodes(element); + + /* don't want s.getElementWidth/Height, want the raw values for full restore */ + var originalStyle = { + height: element.style.height, + width: element.style.width, + right: element.style.right, + left: element.style.left, + innerWidth: element.firstChild.style.width + }; + + options = b.update({ + scaleContent: false, + scaleY: false, + scaleFrom: 100, + restoreAfterFinish: true, + beforeSetupInternal: function (effect) { + elemClip = d.makeClipping(effect.element); + s.showElement(effect.element); + scaleMode = { + originalHeight: s.getElementHeight(effect.element), + originalWidth: s.getElementWidth(effect.element), + }; + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.element, {left: '0px'}); + s.setStyle(effect.element.firstChild, {width: scaleMode.originalWidth}); + d.makePositioned(effect.element); + d.makePositioned(effect.element.firstChild); + if (/Opera/.test(navigator.userAgent)) { + s.setStyle(effect.element, {right: ''}); + } + }, + afterUpdateInternal: function (effect) { + s.setStyle(effect.element, { + left: (effect.dims[1] - s.getElementWidth(effect.element)) + 'px' + }); + }, + afterFinishInternal: function (effect) { + s.hideElement(effect.element); + d.undoClipping(effect.element, elemClip); + d.undoPositioned(effect.element.firstChild); + d.undoPositioned(effect.element); + s.setStyle(effect.element, { + width: originalStyle.width, + height: originalStyle.height, + right: originalStyle.right, + left: originalStyle.left + }); + s.setStyle(effect.element.firstChild, { + width: originalStyle.innerWidth + }); + } + }, options); + return new MochiKit.Visual.Scale(element, 0, options); +}; + +/** @id MochiKit.Visual.slidePairLeft */ +MochiKit.Visual.slidePairLeft = function (elements, /* optional */ options) { + /*** + + Slide the first element off and the second element off from right to left. + + ***/ + if (elements[0] != elements[1]) { + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + var v = MochiKit.Visual; + elements = [d.getElement(elements[0]), d.getElement(elements[1])]; + var parent = elements[1].parentNode; + var originalStyle = { + position: [ + elements[0].style.position, + elements[1].style.position + ], + parentWidth: parent.style.width, + parentHeight: parent.style.height + }; + options = b.update({ + beforeSetupInternal: function (effect) { + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.effects[0].element.parentNode, { + width: Math.max(s.getElementWidth(effect.effects[0].element), + s.getElementWidth(effect.effects[1].element)), + height: Math.max(s.getElementHeight(effect.effects[0].element), + s.getElementHeight(effect.effects[1].element)) + }); + s.setStyle(effect.effects[0].element, {position: 'absolute'}); + s.setStyle(effect.effects[1].element, {position: 'absolute'}); + }, + afterFinishInternal: function (effect) { + s.setStyle(effect.effects[0].element, { + position: originalStyle.position[0] + }); + s.setStyle(effect.effects[1].element, { + position: originalStyle.position[1] + }); + s.setStyle(parent, { + width: originalStyle.parentWidth, + height: originalStyle.parentHeight + }); + } + }, options); + return new v.Parallel( + [v.slideOffLeft(elements[0]), v.slideOnLeft(elements[1])], + options); + } else { + return null; + } +} + +/** @id MochiKit.Visual.slidePairRight */ +MochiKit.Visual.slidePairRight = function (elements, /* optional */ options) { + /*** + + Slide the first element off and the second element off from left to right. + + ***/ + if (elements[0] != elements[1]) { + var d = MochiKit.DOM; + var b = MochiKit.Base; + var s = MochiKit.Style; + elements = [d.getElement(elements[0]), d.getElement(elements[1])]; + var parent = elements[1].parentNode; + var originalStyle = { + position: [ + elements[0].style.position, + elements[1].style.position + ], + parentWidth: parent.style.width, + parentHeight: parent.style.height + }; + options = b.update({ + beforeSetupInternal: function (effect) { + }, + afterSetupInternal: function (effect) { + s.setStyle(effect.effects[0].element.parentNode, { + width: Math.max(s.getElementWidth(effect.effects[0].element), + s.getElementWidth(effect.effects[1].element)), + height: Math.max(s.getElementHeight(effect.effects[0].element), + s.getElementHeight(effect.effects[1].element)) + }); + s.setStyle(effect.effects[0].element, {position: 'absolute'}); + s.setStyle(effect.effects[1].element, {position: 'absolute'}); + }, + afterFinishInternal: function (effect) { + s.setStyle(effect.effects[0].element, { + position: originalStyle.position[0] + }); + s.setStyle(effect.effects[1].element, { + position: originalStyle.position[1] + }); + s.setStyle(parent, { + width: originalStyle.parentWidth, + height: originalStyle.parentHeight + }); + } + }, options); + return new MochiKit.Visual.Parallel( + [slideOffRight(elements[0]), slideOnRight(elements[1])], + options); + } else { + return null; + } +} + +/** @id MochiKit.Visual.slidePairRight */ +MochiKit.Visual.slidePair = function (elements, /* optional */ options) { + /*** + + Slide the first element on and the second element off. Direction is based + on relative position of the two elements in the child node list. It assumes + both are siblings. + + ***/ + if (elements[0] != elements[1]) { + for (sibling = elements[0].nextSibling; + sibling && sibling != elements[1]; + sibling = sibling.nextSibling) { + } + if (sibling == elements[1]) { + return MochiKit.Visual.slidePairLeft(elements, options); + } else { + return MochiKit.Visual.slidePairRight(elements, options); + } + } else { + return null; + } +} + + // Bug in opera makes the TD containing this element expand for a instance // after finish /** @id MochiKit.Visual.squish */ @@ -1995,6 +2445,13 @@ "shake", "slideDown", "slideUp", + "slideOnLeft", + "slideOnRight", + "slideOffLeft", + "slideOffRight", + "slidePairLeft", + "slidePairRight", + "slidePair", "squish", "grow", "shrink", --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "MochiKit" group. To post to this group, send email to mochikit@... To unsubscribe from this group, send email to mochikit-unsubscribe@... For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~----------~----~----~----~------~----~------~--~--- |
|
|
Re: Seven new functions for MochiKit.VisualI've added the original patch to Trac #312: http://trac.mochikit.com/ticket/312 New functionality in MochiKit.Visual is low priority right now, so I moved it to version 1.5. I also think more generic helper functions are needed to make new functions like these most compact and readable. Perhaps the best ideas from MochiKit.Animator should be included? Cheers, /Per On Tue, Jun 10, 2008 at 8:28 PM, Michael Bond <mikejbond@...> wrote: > > Ok, had a couple visual glitches that are now fixed with the patch > below: > > Index: Visual.js > =================================================================== > --- Visual.js (revision 1383) > +++ Visual.js (working copy) > @@ -1431,14 +1431,16 @@ > scaleContent: false, > scaleX: false, > scaleFrom: 0, > - scaleMode: {originalHeight: s.getElementHeight(element), > - originalWidth: s.getElementWidth(element)}, > restoreAfterFinish: true, > - afterSetupInternal: function (effect) { > + beforeSetupInternal: function (effect) { > elemClip = d.makeClipping(effect.element); > - s.setStyle(effect.element, {height: '0px'}); > s.showElement(effect.element); > + effect.options.scaleMode = {originalHeight: > s.getElementHeight(element), > + originalWidth: s.getElementWidth(element)}; > }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.element, {height: '0px'}); > + }, > afterFinishInternal: function (effect) { > d.undoClipping(effect.element, elemClip); > } > @@ -1582,18 +1584,20 @@ > scaleContent: false, > scaleX: false, > scaleFrom: 0, > - scaleMode: {originalHeight: s.getElementHeight(element), > - originalWidth: s.getElementWidth(element)}, > restoreAfterFinish: true, > + beforeSetupInternal: function (effect) { > + elemClip = d.makeClipping(effect.element); > + s.showElement(effect.element); > + scaleMode = {originalHeight: s.getElementHeight(element), > + originalWidth: s.getElementWidth(element)}; > + }, > afterSetupInternal: function (effect) { > d.makePositioned(effect.element); > d.makePositioned(effect.element.firstChild); > if (/Opera/.test(navigator.userAgent)) { > s.setStyle(effect.element, {top: ''}); > } > - elemClip = d.makeClipping(effect.element); > s.setStyle(effect.element, {height: '0px'}); > - s.showElement(effect.element); > }, > afterUpdateInternal: function (effect) { > s.setStyle(effect.element.firstChild, > @@ -1666,6 +1670,452 @@ > return new MochiKit.Visual.Scale(element, 0, options); > }; > > +/** @id MochiKit.Visual.slideOnLeft */ > +MochiKit.Visual.slideOnLeft = function (element, /* optional */ > options) { > + /*** > + > + Slide an element on moving from right to left. > + It must have a single inner child to work correctly > + > + ***/ > + if (!element.hasChildNodes()) { > + throw "MochiKit.Visual.slideOnLeft must be used on a element > with a child"; > + } > + var d = MochiKit.DOM; > + var b = MochiKit.Base; > + var s = MochiKit.Style; > + var elemClip; > + element = d.getElement(element); > + d.removeEmptyTextNodes(element); > + > + /* don't want s.getElementWidth/Height, want the raw values for > full restore */ > + var originalStyle = { > + height: element.style.height, > + width: element.style.width, > + left: element.style.left, > + innerWidth: element.firstChild.style.width > + }; > + > + options = b.update({ > + scaleContent: false, > + scaleY: false, > + scaleFrom: 0, > + restoreAfterFinish: true, > + beforeSetupInternal: function (effect) { > + elemClip = d.makeClipping(effect.element); > + s.showElement(effect.element); > + scaleMode = { > + originalHeight: s.getElementHeight(effect.element), > + originalWidth: s.getElementWidth(effect.element) > + }; > + }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.element, { > + width: '0px', > + left: effect.dims[1] > + }); > + s.setStyle(effect.element.firstChild, { > + width: scaleMode.originalWidth > + }); > + d.makePositioned(effect.element); > + d.makePositioned(effect.element.firstChild); > + if (/Opera/.test(navigator.userAgent)) { > + s.setStyle(effect.element, {left: ''}); > + } > + }, > + afterUpdateInternal: function (effect) { > + s.setStyle(effect.element, { > + left: (effect.dims[1] - > s.getElementWidth(effect.element)) + 'px' > + }); > + }, > + afterFinishInternal: function (effect) { > + d.undoClipping(effect.element, elemClip); > + // IE will crash if child is undoPositioned first > + if (/MSIE/.test(navigator.userAgent)) { > + d.undoPositioned(effect.element); > + d.undoPositioned(effect.element.firstChild); > + } else { > + d.undoPositioned(effect.element.firstChild); > + d.undoPositioned(effect.element); > + } > + s.setStyle(effect.element, { > + height: originalStyle.height, > + width: originalStyle.width, > + left: originalStyle.left > + }); > + s.setStyle(effect.element.firstChild, { > + width: originalStyle.innerWidth > + }); > + } > + }, options); > + > + return new MochiKit.Visual.Scale(element, 100, options); > +} > + > +/** @id MochiKit.Visual.slideOnRight */ > +MochiKit.Visual.slideOnRight = function (element, /* optional */ > options) { > + /*** > + > + Slide an element on moving from left to right. > + It must have a single inner child to work correctly > + > + ***/ > + if (!element.hasChildNodes()) { > + throw "MochiKit.Visual.slideOnRight must be used on a element > with a child"; > + } > + var d = MochiKit.DOM; > + var b = MochiKit.Base; > + var s = MochiKit.Style; > + var elemClip; > + element = d.getElement(element); > + d.removeEmptyTextNodes(element); > + > + /* don't want s.getElementWidth/Height, want the raw values for > full restore */ > + var originalStyle = { > + height: element.style.height, > + width: element.style.width, > + left: element.firstChild.style.left, > + innerRight: element.firstChild.style.right, > + innerWidth: element.firstChild.style.width > + }; > + > + options = b.update({ > + scaleContent: false, > + scaleY: false, > + scaleFrom: 0, > + restoreAfterFinish: true, > + beforeSetupInternal: function (effect) { > + elemClip = d.makeClipping(effect.element); > + s.showElement(effect.element); > + scaleMode = { > + originalHeight: s.getElementHeight(effect.element), > + originalWidth: s.getElementWidth(effect.element) > + }; > + }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.element, { > + width: '0px', > + left: '0px' > + }); > + s.setStyle(effect.element.firstChild, { > + width: scaleMode.originalWidth, > + right: effect.dims[1] > + }); > + d.makePositioned(effect.element); > + d.makePositioned(effect.element.firstChild); > + }, > + afterUpdateInternal: function (effect) { > + s.setStyle(effect.element.firstChild, { > + right: (effect.dims[1] - > s.getElementWidth(effect.element)) + 'px' > + }); > + }, > + afterFinishInternal: function (effect) { > + d.undoClipping(effect.element, elemClip); > + // IE will crash if child is undoPositioned first > + if (/MSIE/.test(navigator.userAgent)) { > + d.undoPositioned(effect.element); > + d.undoPositioned(effect.element.firstChild); > + } else { > + d.undoPositioned(effect.element.firstChild); > + d.undoPositioned(effect.element); > + } > + s.setStyle(effect.element, { > + height: originalStyle.height, > + width: originalStyle.width, > + left: originalStyle.left > + }); > + s.setStyle(effect.element.firstChild, { > + right: originalStyle.innerRight, > + width: originalStyle.innerWidth > + }); > + } > + }, options); > + > + return new MochiKit.Visual.Scale(element, 100, options); > +} > + > +/** @id MochiKit.Visual.slideOffLeft */ > +MochiKit.Visual.slideOffLeft = function (element, /* optional */ > options) { > + /*** > + > + Slide an element off moving from right to left. > + It must have a single inner child to work correctly > + > + ***/ > + if (!element.hasChildNodes()) { > + throw "MochiKit.Visual.slideOffLeft must be used on a element > with a child"; > + } > + var d = MochiKit.DOM; > + var b = MochiKit.Base; > + var s = MochiKit.Style; > + var elemClip; > + element = d.getElement(element); > + d.removeEmptyTextNodes(element); > + > + /* don't want s.getElementWidth/Height, want the raw values for > full restore */ > + var originalStyle = { > + height: element.style.height, > + width: element.style.width, > + right: element.style.right, > + left: element.style.left, > + innerRight: element.firstChild.style.right > + }; > + > + options = b.update({ > + scaleContent: false, > + scaleY: false, > + scaleFrom: 100, > + restoreAfterFinish: true, > + beforeSetupInternal: function (effect) { > + elemClip = d.makeClipping(effect.element); > + s.showElement(effect.element); > + scaleMode = { > + originalHeight: s.getElementHeight(effect.element), > + originalWidth: s.getElementWidth(effect.element), > + }; > + }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.element, {left: '0px'}); > + s.setStyle(effect.element.firstChild, {width: > scaleMode.originalWidth}); > + d.makePositioned(effect.element); > + d.makePositioned(effect.element.firstChild); > + if (/Opera/.test(navigator.userAgent)) { > + s.setStyle(effect.element, {right: ''}); > + } > + }, > + afterUpdateInternal: function (effect) { > + s.setStyle(effect.element.firstChild, { > + right: (effect.dims[1] - > s.getElementWidth(effect.element)) + 'px' > + }); > + }, > + afterFinishInternal: function (effect) { > + s.hideElement(effect.element); > + d.undoClipping(effect.element, elemClip); > + d.undoPositioned(effect.element.firstChild); > + d.undoPositioned(effect.element); > + s.setStyle(effect.element, { > + width: originalStyle.width, > + height: originalStyle.height, > + right: originalStyle.right, > + left: originalStyle.left > + }); > + s.setStyle(effect.element.firstChild, { > + right: originalStyle.innerRight > + }); > + } > + }, options); > + return new MochiKit.Visual.Scale(element, 0, options); > +}; > + > +/** @id MochiKit.Visual.slideOffRight */ > +MochiKit.Visual.slideOffRight = function (element, /* optional */ > options) { > + /*** > + > + Slide an element off moving from left to right. > + It must have a single inner child to work correctly > + > + ***/ > + if (!element.hasChildNodes()) { > + throw "MochiKit.Visual.slideOffRight must be used on a > element with a child"; > + } > + var d = MochiKit.DOM; > + var b = MochiKit.Base; > + var s = MochiKit.Style; > + var elemClip; > + element = d.getElement(element); > + d.removeEmptyTextNodes(element); > + > + /* don't want s.getElementWidth/Height, want the raw values for > full restore */ > + var originalStyle = { > + height: element.style.height, > + width: element.style.width, > + right: element.style.right, > + left: element.style.left, > + innerWidth: element.firstChild.style.width > + }; > + > + options = b.update({ > + scaleContent: false, > + scaleY: false, > + scaleFrom: 100, > + restoreAfterFinish: true, > + beforeSetupInternal: function (effect) { > + elemClip = d.makeClipping(effect.element); > + s.showElement(effect.element); > + scaleMode = { > + originalHeight: s.getElementHeight(effect.element), > + originalWidth: s.getElementWidth(effect.element), > + }; > + }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.element, {left: '0px'}); > + s.setStyle(effect.element.firstChild, {width: > scaleMode.originalWidth}); > + d.makePositioned(effect.element); > + d.makePositioned(effect.element.firstChild); > + if (/Opera/.test(navigator.userAgent)) { > + s.setStyle(effect.element, {right: ''}); > + } > + }, > + afterUpdateInternal: function (effect) { > + s.setStyle(effect.element, { > + left: (effect.dims[1] - > s.getElementWidth(effect.element)) + 'px' > + }); > + }, > + afterFinishInternal: function (effect) { > + s.hideElement(effect.element); > + d.undoClipping(effect.element, elemClip); > + d.undoPositioned(effect.element.firstChild); > + d.undoPositioned(effect.element); > + s.setStyle(effect.element, { > + width: originalStyle.width, > + height: originalStyle.height, > + right: originalStyle.right, > + left: originalStyle.left > + }); > + s.setStyle(effect.element.firstChild, { > + width: originalStyle.innerWidth > + }); > + } > + }, options); > + return new MochiKit.Visual.Scale(element, 0, options); > +}; > + > +/** @id MochiKit.Visual.slidePairLeft */ > +MochiKit.Visual.slidePairLeft = function (elements, /* optional */ > options) { > + /*** > + > + Slide the first element off and the second element off from right > to left. > + > + ***/ > + if (elements[0] != elements[1]) { > + var d = MochiKit.DOM; > + var b = MochiKit.Base; > + var s = MochiKit.Style; > + var v = MochiKit.Visual; > + elements = [d.getElement(elements[0]), > d.getElement(elements[1])]; > + var parent = elements[1].parentNode; > + var originalStyle = { > + position: [ > + elements[0].style.position, > + elements[1].style.position > + ], > + parentWidth: parent.style.width, > + parentHeight: parent.style.height > + }; > + options = b.update({ > + beforeSetupInternal: function (effect) { > + }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.effects[0].element.parentNode, { > + width: > Math.max(s.getElementWidth(effect.effects[0].element), > + > s.getElementWidth(effect.effects[1].element)), > + height: > Math.max(s.getElementHeight(effect.effects[0].element), > + > s.getElementHeight(effect.effects[1].element)) > + }); > + s.setStyle(effect.effects[0].element, {position: > 'absolute'}); > + s.setStyle(effect.effects[1].element, {position: > 'absolute'}); > + }, > + afterFinishInternal: function (effect) { > + s.setStyle(effect.effects[0].element, { > + position: originalStyle.position[0] > + }); > + s.setStyle(effect.effects[1].element, { > + position: originalStyle.position[1] > + }); > + s.setStyle(parent, { > + width: originalStyle.parentWidth, > + height: originalStyle.parentHeight > + }); > + } > + }, options); > + return new v.Parallel( > + [v.slideOffLeft(elements[0]), > v.slideOnLeft(elements[1])], > + options); > + } else { > + return null; > + } > +} > + > +/** @id MochiKit.Visual.slidePairRight */ > +MochiKit.Visual.slidePairRight = function (elements, /* optional */ > options) { > + /*** > + > + Slide the first element off and the second element off from left > to right. > + > + ***/ > + if (elements[0] != elements[1]) { > + var d = MochiKit.DOM; > + var b = MochiKit.Base; > + var s = MochiKit.Style; > + elements = [d.getElement(elements[0]), > d.getElement(elements[1])]; > + var parent = elements[1].parentNode; > + var originalStyle = { > + position: [ > + elements[0].style.position, > + elements[1].style.position > + ], > + parentWidth: parent.style.width, > + parentHeight: parent.style.height > + }; > + options = b.update({ > + beforeSetupInternal: function (effect) { > + }, > + afterSetupInternal: function (effect) { > + s.setStyle(effect.effects[0].element.parentNode, { > + width: > Math.max(s.getElementWidth(effect.effects[0].element), > + > s.getElementWidth(effect.effects[1].element)), > + height: > Math.max(s.getElementHeight(effect.effects[0].element), > + > s.getElementHeight(effect.effects[1].element)) > + }); > + s.setStyle(effect.effects[0].element, {position: > 'absolute'}); > + s.setStyle(effect.effects[1].element, {position: > 'absolute'}); > + }, > + afterFinishInternal: function (effect) { > + s.setStyle(effect.effects[0].element, { > + position: originalStyle.position[0] > + }); > + s.setStyle(effect.effects[1].element, { > + position: originalStyle.position[1] > + }); > + s.setStyle(parent, { > + width: originalStyle.parentWidth, > + height: originalStyle.parentHeight > + }); > + } > + }, options); > + return new MochiKit.Visual.Parallel( > + [slideOffRight(elements[0]), slideOnRight(elements[1])], > + options); > + } else { > + return null; > + } > +} > + > +/** @id MochiKit.Visual.slidePairRight */ > +MochiKit.Visual.slidePair = function (elements, /* optional */ > options) { > + /*** > + > + Slide the first element on and the second element off. Direction > is based > + on relative position of the two elements in the child node list. > It assumes > + both are siblings. > + > + ***/ > + if (elements[0] != elements[1]) { > + for (sibling = elements[0].nextSibling; > + sibling && sibling != elements[1]; > + sibling = sibling.nextSibling) { > + } > + if (sibling == elements[1]) { > + return MochiKit.Visual.slidePairLeft(elements, options); > + } else { > + return MochiKit.Visual.slidePairRight(elements, options); > + } > + } else { > + return null; > + } > +} > + > + > // Bug in opera makes the TD containing this element expand for a > instance > // after finish > /** @id MochiKit.Visual.squish */ > @@ -1995,6 +2445,13 @@ > "shake", > "slideDown", > "slideUp", > + "slideOnLeft", > + "slideOnRight", > + "slideOffLeft", > + "slideOffRight", > + "slidePairLeft", > + "slidePairRight", > + "slidePair", > "squish", > "grow", > "shrink", > > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "MochiKit" group. To post to this group, send email to mochikit@... To unsubscribe from this group, send email to mochikit-unsubscribe@... For more options, visit this group at http://groups.google.com/group/mochikit?hl=en -~----------~----~----~----~------~----~------~--~--- |