// effects.js - version 0.2 - Spry Pre-Release 1.6.1 // // Copyright (c) 2006. Adobe Systems Incorporated. // All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Adobe Systems Incorporated nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. /////////////////////////////////////////////////////////////////////////////////////// // // This file is used in an advanced demo to examplify the Spry Effects functionalities // and interoperability between them. To read more details about different Spry Effects // and their detailed options please see our detailed samples: // // http://labs.adobe.com/technologies/spry/samples/#effects // // We had to write the following custom objects and functions to achieve our demo goal: // // Spry.Effect.FadeBlind // - A custom cluster effect which group together a Fade and a Blind Effect // // Spry.Effect.FadeSlide // - A custom cluster effect which group together a Fade and a Blind Effect // // Observer // - A custom observer attached to every effect that will run in page. This observer // was designed to run any effect a second time in the opposite direction and // revert at the end any CSS changes that where changed by the effect on the target // element // // runEffect() // - A custom function that will prepare and run a given effect on a target element // // ExampleHelpText() // - A custom function designed to change the content text of an element. // /////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////// // // Global Variables // //////////////////////////////////////////////////// // list of effects already run to be reused var effects = {}; // latest effect ran var prevEffect = false; // CSS initial properties for the elements on which we apply the effects var initialElements = []; // list of style properties to be monitored var saveStyle = ['position', 'width', 'height', 'opacity', 'filter', 'top', 'left', 'backgroundColor', 'visibility', 'display']; //////////////////////////////////////////////////// // // Cluster Effects // //////////////////////////////////////////////////// /* * FadeBlind * Custom Cluster effect that fade in/out and blind in/out simultanous an element * by running in parallel the Fade() and Blind() predefined clusters */ Spry.Effect.FadeBlind = function(element, options) { Spry.Effect.Cluster.call(this, options); this.name = 'FadeBlind'; var duration = 1000; var doToggle = false; var from = 100; var to = 0; if (options) { if (options.duration) duration = options.duration; if (options.toggle) doToggle = options.toggle; if (options.from) from = options.from; if (options.to) to = options.to; } var options = {duration: duration, from: from, to: to, toggle: doToggle}; var blind = new Spry.Effect.Blind(element, options); this.addParallelEffect(blind); var options = {duration: duration, from: from, to: to, toggle: doToggle}; var fade = new Spry.Effect.Fade(element, options); this.addParallelEffect(fade); }; Spry.Effect.FadeBlind.prototype = new Spry.Effect.Cluster(); Spry.Effect.FadeBlind.prototype.constructor = Spry.Effect.FadeBlind; /* * FadeSlide * Custom Cluster effect that fade in/out and slide simultaneous an element * by running in parallel the Fade() and Slide() predefined clusters */ Spry.Effect.FadeSlide = function(element, options) { Spry.Effect.Cluster.call(this, options); this.name = 'FadeSlide'; var duration = 1000; var doToggle = false; var from = 100; var to = 0; if (options) { if (options.duration) duration = options.duration; if (options.toggle) doToggle = options.toggle; if (options.from) from = options.from; if (options.to) to = options.to; } var options = {duration: duration, from: from, to: to, toggle: doToggle}; var slide = new Spry.Effect.Slide(element, options); this.addParallelEffect(slide); var options = {duration: duration, from: from, to: to, toggle: doToggle}; var fade = new Spry.Effect.Fade(element, options); this.addParallelEffect(fade); }; Spry.Effect.FadeSlide.prototype = new Spry.Effect.Cluster(); Spry.Effect.FadeSlide.prototype.constructor = Spry.Effect.FadeSlide; /////////////////////////////////////////////////////////////// // // Generic Observer // // The observer will save the initial element state, // restore the effect and the element to their original // states when the effect finished or canceled. // /////////////////////////////////////////////////////////////// var Observer = {}; /* * Observer.onPreEffect(obj) * Before running an effect forward the initial CSS values are saved. * We will use later these when the animation will finish or is canceled * to restore the animated element to be ready for the next effect. * This function is automatically called by the effect. * Parameters: * obj - the running effect that calls this function */ Observer.onPreEffect = function(obj){ if (obj.direction && obj.direction == Spry.forwards){ saveElement(obj.element); if (obj.name == 'Slide' || obj.name == 'FadeSlide'){ saveElement(document.getElementById('content_box')); } } }; /* * Observer.onCancel(obj) * When an effect is canceled this function will restore the element CSS. * Also we toggle the effect so the next time will run to go forward again. * This function is automatically called by the effect. * Parameters: * obj - the running effect that calls this function */ Observer.onCancel = function(obj){ if (obj.direction == Spry.forwards){ obj.doToggle(); } restoreElement(obj.element); if (obj.name == 'Slide' || obj.name == 'FadeSlide'){ var el = document.getElementById('content_box') restoreElement(el); } }; /* * Observer.onPostEffect(obj) * When a forward effect finish the effect is restarted to toggle the effect. * We will use a small timeout to make sure the effect properly finish the * animation in forward direction. * After the second run will restore the element CSS * This function is automatically called by the effect. * Parameters: * obj - the running effect that calls this function */ Observer.onPostEffect = function(obj){ if (obj.direction == Spry.forwards) setTimeout(function(){obj.start()}, 150); else restoreElement(obj.element); }; ///////////////////////////////////////////////// // // Utilities functions // ///////////////////////////////////////////////// /* * ExampleHelpText * change the content text of the text_pane div with the new one received * Parameters: * helpText - the new text to be displayed into the text_pane element * */ function ExampleHelpText(helpText) { document.getElementById("text_pane").innerHTML='
'+helpText+'
'; }; /* * ReloadDocument() * reload the current page from the server * */ function ReloadDocument() { window.location.reload(true); }; /* * saveElement(el) * Save into the global array of 'initialElements' some CSS properties * of the given element that where altered by the animation running. * Parameters: * el - the DOM element for which to save the CSS properties */ var saveElement = function(el){ if (!initialElements[el.id]) { initialElements[el.id] = {}; for (var i = 0; i < saveStyle.length; i++) { initialElements[el.id][saveStyle[i]] = Spry.Effect.getStyleProp(el, saveStyle[i]); } } }; /* * restoreElement(el) * Restore from the global array 'initialElements' some CSS properties * of the given element to prepare it for the next effect to run. * Parameters: * el - the DOM element for which to restore the CSS properties */ var restoreElement = function(el){ for (var i = 0; i < saveStyle.length; i++) el.style[saveStyle[i]] = initialElements[el.id][saveStyle[i]]; }; /* * runEffect() * This is the dispatcher that will instantiate, if not already done, * the given 'effect' with a list of 'options' to run on a given target 'element'. * * The observer defined above will also be attached to the effect to * initially save the unaltered 'element' properties, automatically restart * the animation in backward direction and restore the saved properties at the end. * * The 'effect' is than started and the text from the text_pane is changed * with the 'helpText' * * The "new Spry.Effect[effect]" is a generic way of initializing a given 'effect'. * The Spry samples are describing for each effect what is the specific code * to be included in page and the complete list of supported options. An online version * of the Spry Effects samples could be accessed here: * * http://labs.adobe.com/technologies/spry/samples/#effects * * The function will return false to prevent the href of tag to be followed by the browser. * * Parameters: * effect - the name of the effect to run * element - the element id from page to run this effect on * options - the options necessary for the effect to run * helptext - the new status page to be displayed */ var runEffect = function(effect, element, options, helptext){ if (prevEffect && effects[prevEffect].isRunning){ effects[prevEffect].cancel(); setTimeout(function(){runEffect(effect, element, options, helptext)}, 150); return false; } if (!effects[effect]){ effects[effect] = new Spry.Effect[effect](element, options); if (effect != 'Highlight' && effect != 'Shake' && effect != 'Pulsate') effects[effect].addObserver(Observer); } effects[effect].start(); if (helptext) ExampleHelpText(helptext); prevEffect = effect; return false; };