I'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 <[EMAIL PROTECTED]> 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 [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/mochikit?hl=en
-~----------~----~----~----~------~----~------~--~---