Skip to content

Instantly share code, notes, and snippets.

@azinman
Created June 3, 2011 05:38
Show Gist options
  • Save azinman/1005921 to your computer and use it in GitHub Desktop.
Save azinman/1005921 to your computer and use it in GitHub Desktop.
Apply CSS transformations, remembering the past history. Useful for undoable animations/transitions.
// Undo-able CSS transformations on DOM objects
// Requires jQuery
// MIT Licensed
// Author: Aaron Zinman <aaron@azinman.com>
// Part of Defuse: http://defuse.media.mit.edu
// Tested in Safari, soon testing in: Chrome and Firefox
if (window.defuse == null) defuse = {animation:{}};
/**
* Applies a series of CSS transformation (contained in the cssObj dictionary)
* to the jQuery $selector. Takes a snapshot of the current CSS properties to be overriden
* so that the previous state may be restored.
*
* $selector: The jQuery selector
* cssObj: A dictionary of css values
* disableCssTransition: If set to true, current CSS-based transitions will be temporarily turned
* off, to be restored to their previous value after unless a new value is in
* cssObj.
*/
defuse.animation.css = function($selector, cssObj, disableCssTransition) {
// Save these settings on each element
$selector.each(function() {
// CSS settings for what we're about to change
var currentSettings = {};
var $this = $(this);
_.each(cssObj, function(value, prop) {
currentSettings[prop] = $this.css(prop);
});
// Save those settings on the DOM object
var history = $this.data("cssHistory");
if (history == null) {
$this.data("cssHistory", [currentSettings]);
} else {
history.push(currentSettings);
$this.data("cssHistory", history);
}
// Save the current transition state if necessary
var previousTransition = $this.css("-webkit-transition");
if (disableCssTransition) {
$this.css({"-webkit-transition": "none",
"-moz-transition": "none"});
}
// Apply changes
$this.css(cssObj);
// Restory previous css transition state, if it wasn't one of the things changes
if (disableCssTransition && cssObj["-webkit-transition"] == undefined) {
setTimeout(function() { $this.css({"-webkit-transition": previousTransition || "none",
"-moz-transition": previousTransition || "none"}) }, 1);
}
});
};
/**
* Undo the last group of css transformations for elements in $selector, as applied by
* defuse.animation.css.
*
* $selector: jQuery selector of objects to restore
* disableCssTransition: If set to true, current CSS-based transitions will be temporarily turned
* off, to be restored to their previous value after unless a new value is in
* cssObj.
*/
defuse.animation.undoCss = function($selector, disableCssTransition) {
$selector.each(function() {
$this = $(this);
// Get history
var history = $this.data("cssHistory");
if (history == null || history.length == 0) return;
var lastChanges = history.pop();
if (history.length == 0) {
$this.removeData("cssHistory");
} else {
$this.data("cssHistory", history);
}
// Possibly temporarily disable css transitions
if (disableCssTransition) {
var previousTransition = $this.css("-webkit-transition");
$this.css({"-webkit-transition": "none",
"-moz-transition": "none"});
}
// Rollback changes
$this.css(lastChanges);
// Restory previous css transition state, if it wasn't one of the things changes
if (disableCssTransition && lastChanges["-webkit-transition"] == undefined) {
setTimeout(function() { $this.css({"-webkit-transition": previousTransition || "none",
"-moz-transition": previousTransition || "none"}) }, 1);
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment