Skip to content

Instantly share code, notes, and snippets.

@low-ghost
Last active August 29, 2015 14:14
Show Gist options
  • Save low-ghost/f5167bac4e550a5ba2cb to your computer and use it in GitHub Desktop.
Save low-ghost/f5167bac4e550a5ba2cb to your computer and use it in GitHub Desktop.
transitioner.js is an es6 solution to jquery addClass w/ callbacks and default to css transitions
/*
TODO build non-jquery dependent class manipulations in utils and allow passing
in a custom animation function / library
*/
class Transitioner {
constructor(){
this.fake = document.createElement("fake")
//call set end() with transition object
this.end = {
"transition" : "transitionend",
"OTransition" : "oTransitionEnd",
"MozTransition" : "transitionend",
"WebkitTransition": "webkitTransitionEnd"
}
}
get end(){ return this.transitionEnd }
set end(transitions){
//test fake element for transition support
for (let i in transitions){
if (this.fake.style[i] !== undefined){
this.transitionEnd = transitions[i]
break
}
}
}
//cache selector if not already cached.
//Available to next function calls and chains by passing false
get el(){ return this.elements; }
set el(selector){
this.elements = selector instanceof jQuery && selector || $(selector)
}
//jquery classList manipulations with animation fallback and callback support
add(element, name, t, cb = null){
if (element)
this.el = element //call setter and cache element
let fn = "addClass"
this.cbOrAnimate(this.el, fn, name, t, cb)
return this
}
remove(element, name, t, cb = null){
if (element)
this.el = element
let fn = "removeClass"
this.cbOrAnimate(this.el, fn, name, t, cb)
return this
}
toggle(element, name, t, cb = null){
if (element)
this.el = element
let fn = "toggleClass"
this.cbOrAnimate(this.el, fn, name, t, cb)
return this
}
cbOrAnimate(el, fn, name, t, cb = null){
if (this.end){
el[fn](name)
el.one(this.end, cb)
} else {
el.animate(t.properties, t.duration, function(){
el[fn](name)
if (cb)
cb()
})
}
}
}
//unnecessary but useful object manipulations for transitions
class Transition {
constructor(name, subName, properties, duration = 500, easing = "swing"){
this.name = name;
this[subName] = { properties, duration, easing }
}
addTransition(subName, properties, duration = 500, easing = "swing"){
this[subName] = { properties, duration, easing }
}
//TODO move to general utils object
copyObj(original, copy = {}){
if (original === null || typeof original !== "object")
return original
for (var prop in original) {
if (original.hasOwnProperty(prop)){
copy[prop] = (copy[prop] && typeof copy[prop] === "object") ? this.copyObj(original[prop], copy[prop])
: (copy[prop] === 0 || copy[prop]) ? copy[prop]
: original[prop]
}
}
return copy
}
extend(newTransition, original, changes){
this[newTransition] = this.copyObj(this[original], changes)
}
}
export { Transition, Transitioner }
//simple example usage not including the import statement if this were placed in another file
$(() => {
//initialize Transitioner, event string "c" and element(s)
let [$t, c, $h1] = [new Transitioner(), "currentTarget", $("h1")]
//initialize Transition with _font and add transitions
let _font = new Transition("font", "h1", { fontSize: "200px" })
_font.addTransition("h1Cb", {fontSize: "100px"})
_font.extend("h1_init", "h1Cb", { duration: 100 });
_font.extend("h1_newest", "h1Cb", { properties: { height: "999px"}})
//add class on dom load, then add another as a callback for no reason
$t.add($h1, _font.name, _font.h1_init, () => $t.remove(false, "class", _font.h1_newest))
//using event listeners (note event.currentTarget inside of arrow function
$h1.on("click", e => $t.add(e[c], _font.name, _font.h1, () =>
$t.remove(false, _font.name, _font.h1Cb )))
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment