Created
August 20, 2014 13:30
-
-
Save jackmcmorrow/277069ce03ee96a0e420 to your computer and use it in GitHub Desktop.
Animation.js, a frame by frame animation lib
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
// Animation CLASS | |
// @author cav_dan<[email protected]> | |
// @desc | |
// Create a frame-by-frame animation that may use jQuery | |
// | |
// @args | |
// selector = $('#someid') || document.querySelector('#someid'), | |
// | |
// optionsObj = { | |
// name: string || selector.id | |
// rootFolder: string = 'path/to/images' | |
// frames: objArray = ['first.png', 'second.png'] | |
// } | |
// | |
// @example | |
// var char01 = new Animation($('#char01'), {rootFolder: 'img/char01/', frames: ['0.png', '1.png', '2.png']}); | |
// char01.init() <-- creates the DOM elements | |
// char01.animate(0, this.length) | |
*/ | |
var Animation = function(selector, optionsObj) { | |
this.selector = selector; | |
this.optionsObj = optionsObj; | |
this.frames = optionsObj.frames ? optionsObj.frames : []; | |
this.stopLoop = false; | |
this.onAnimationStart = function(){return true;}; | |
this.onAnimationEnd = function(){return true;}; | |
} | |
//Creates the DOM elements needed for the animation | |
Animation.prototype.init = function() { | |
var opts = this.optionsObj, | |
selector = this.selector, | |
framesDocFrag = document.createDocumentFragment(), | |
frames = [], | |
//Dentro de optionsObj definir uma array em frames | |
numOfFrames = opts.frames.length, | |
div, img, frameContainer; | |
if ( Array.isArray(selector) ) { | |
frameContainer = selector[0]; | |
this.el = selector[0]; | |
} else { | |
frameContainer = selector; | |
this.el = selector; | |
} | |
for (var i = 0; i <= opts.frames.length - 1; i++) { | |
div = document.createElement('div'), | |
img = document.createElement('img'); | |
div.className = 'frame'; | |
//div.style.zIndex = 100; | |
img.src = ''; | |
div.appendChild(img); | |
img.src = opts.rootFolder + opts.frames[i]; | |
//console.log(img.src); | |
opts.name = opts.name || 'animationFrame'; | |
div.id = new String(opts.name + i); | |
framesDocFrag.appendChild(div); | |
/*if (i !== 0) { | |
div.style.display = 'none'; | |
}*/ | |
if (i !== 0) { | |
div.style.display = 'none'; | |
} | |
frames.push(div); | |
frameContainer.appendChild(framesDocFrag); | |
}; | |
frameContainer.style.width = opts.width || img.clientWidth + 'px'; | |
frameContainer.style.height = opts.height || img.clientHeight + 'px'; | |
frameContainer.style.overflow = 'hidden'; | |
//frameContainer.style.zIndex = 200; | |
this.frames = frames; | |
} | |
/* | |
// @method Animate | |
// @args | |
// firstFrame = number, | |
// lastFrame = number, | |
// duration = number, | |
// isLoop = number || bool[false]; | |
// callback = func | |
*/ | |
Animation.prototype.animate = function(firstFrame, lastFrame, duration, isLoop, callback) { | |
var frames = this.frames, | |
duration = duration || 500; | |
//Verifica se passamos um callback antes do isLoop | |
if (typeof isLoop === 'function' || typeof isLoop === 'object') { | |
callback = isLoop; | |
isLoop = false; | |
} | |
this.callback = callback || false; | |
this.animating = true; | |
this.isLoop = isLoop || false; | |
if (this.callback && this.isLoop) { | |
isLoop = false; | |
console.warn("Callback can not be executed if you're looping: Loop has been turned off."); | |
} | |
this.onAnimationStart(); | |
this.inverse = false; | |
if (lastFrame < firstFrame) { | |
//console.error("Last frame can't be before the first!"); | |
//return false; | |
this.inverse = true; | |
} else if (lastFrame === firstFrame) { | |
lastFrame = frames.length - 1; | |
} else if (lastFrame > frames.length) { | |
lastFrame = frames.length; | |
} | |
//console.log('first: ' + firstFrame, '\nlast: ' + lastFrame, '\ndur: ' + duration, '\nloop?: ' + isLoop); | |
var betweenFrames; | |
this.anim = function() { | |
if (firstFrame !== 0 && lastFrame !== 0) { | |
frames[0].style.display = 'none'; | |
} | |
/*if (this.lastUsedFrame) { | |
frames[this.lastUsedFrame].style.display = 'none'; | |
}*/ | |
//console.log(this.inverse); | |
//Se for ao contrário | |
if (this.inverse) { | |
betweenFrames = Math.floor( duration / (firstFrame - lastFrame) ); | |
for (var i = firstFrame, animFrames = [], j = 0, _i = 0; i >= lastFrame; i--) { | |
//console.log( betweenFrames * _i ); | |
// j foi declarado para que apenas seja alterado durante a execução | |
// da função anônima dentro do window.setTimeout. | |
animFrames.push(frames[i]); | |
setTimeout(function(){ | |
frame = animFrames[j]; | |
if (j !== 0) { | |
animFrames[j - 1].style.display = 'none'; | |
} | |
frame.style.display = 'block'; | |
//console.info(j, frame); | |
j++; | |
}, betweenFrames * _i); | |
_i++; | |
} | |
} | |
//Sentido normal | |
else { | |
betweenFrames = Math.floor( duration / (lastFrame - firstFrame) ); | |
for (var i = firstFrame, animFrames = [], j = 0, _i = 0; i <= lastFrame; i++) { | |
//frames[i].style.display = 'none'; | |
// j foi declarado para que apenas seja alterado durante a execução | |
// da função anônima dentro do window.setTimeout. | |
animFrames.push(frames[i]); | |
setTimeout(function(){ | |
//console.log('animando'); | |
frame = animFrames[j]; | |
if (j !== 0) { | |
animFrames[j - 1].style.display = 'none'; | |
} | |
frame.style.display = 'block'; | |
//console.info(j, 'frame'); | |
j++; | |
}, betweenFrames * _i); | |
_i++; | |
}; | |
} | |
this.lastUsedFrame = lastFrame; | |
if (this.callback) { | |
this.callback(); | |
}; | |
} | |
if (this.isLoop) { | |
var that = this, | |
animationLoop = window.setInterval(function(){ | |
if (that.stopLoop) { | |
/*that.lastFrame.style.display = 'none'; | |
that.firstFrame.style.display = 'none';*/ | |
that.stopLoop = false; | |
clearInterval(animationLoop); | |
} | |
that.anim(); | |
//console.log('looping'); | |
}, duration + isLoop); | |
} else { | |
this.anim(); | |
} | |
for (var i = frames.length - 1; i >= 0; i--) { | |
if (i !== this.lastUsedFrame) { | |
frames[i].style.display = 'none'; | |
} | |
}; | |
this.onAnimationEnd(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment