Skip to content

Instantly share code, notes, and snippets.

@timo22345
Created January 10, 2015 09:54
Show Gist options
  • Save timo22345/b9074b26bdfb13a69863 to your computer and use it in GitHub Desktop.
Save timo22345/b9074b26bdfb13a69863 to your computer and use it in GitHub Desktop.
kof_animationFrame_test
<html><head>
<meta charset="utf-8" />
<title> - jsFiddle demo</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<style type="text/css">
#test {
background: blue;
width: 200px;
height: 150px;
margin-left: 50px;
}
</style>
<script type="text/javascript">//<![CDATA[
$(window).load(function(){
// From: http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
(function() {
var lastTime = 0;
var vendors = ['webkit', 'moz'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
/**
* An even better animation frame.
*
* @copyright Oleg Slobodskoi 2013
* @website https://github.com/kof/animationFrame
* @license MIT
*/
;(function(window) {
'use strict'
var nativeRequestAnimationFrame,
nativeCancelAnimationFrame
// Grab the native request and cancel functions.
;(function() {
var i,
vendors = ['webkit', 'moz', 'ms', 'o'],
top
// Test if we are within a foreign domain. Use raf from the top if possible.
try {
// Accessing .name will throw SecurityError within a foreign domain.
window.top.name
top = window.top
} catch(e) {
top = window
}
nativeRequestAnimationFrame = top.requestAnimationFrame
nativeCancelAnimationFrame = top.cancelAnimationFrame || top.cancelRequestAnimationFrame
// Grab the native implementation.
for (i = 0; i < vendors.length && !nativeRequestAnimationFrame; i++) {
nativeRequestAnimationFrame = top[vendors[i] + 'RequestAnimationFrame']
nativeCancelAnimationFrame = top[vendors[i] + 'CancelAnimationFrame'] ||
top[vendors[i] + 'CancelRequestAnimationFrame']
}
// Test if native implementation works.
// There are some issues on ios6
// http://shitwebkitdoes.tumblr.com/post/47186945856/native-requestanimationframe-broken-on-ios-6
// https://gist.github.com/KrofDrakula/5318048
nativeRequestAnimationFrame && nativeRequestAnimationFrame(function() {
AnimationFrame.hasNative = true
})
}())
/**
* Animation frame constructor.
*
* Options:
* - `useNative` use the native animation frame if possible, defaults to true
* - `frameRate` pass a custom frame rate
*
* @param {Object|Number} options
*/
function AnimationFrame(options) {
if (!(this instanceof AnimationFrame)) return new AnimationFrame(options)
options || (options = {})
// Its a frame rate.
if (typeof options == 'number') options = {frameRate: options}
options.useNative != null || (options.useNative = true)
this.options = options
this.frameRate = options.frameRate || AnimationFrame.FRAME_RATE
this._frameLength = 1000 / this.frameRate
this._isCustomFrameRate = this.frameRate !== AnimationFrame.FRAME_RATE
this._timeoutId = null
this._callbacks = {}
this._lastTickTime = 0
this._tickCounter = 0
}
/**
* Default frame rate used for shim implementation. Native implementation
* will use the screen frame rate, but js have no way to detect it.
*
* If you know your target device, define it manually.
*
* @type {Number}
* @api public
*/
AnimationFrame.FRAME_RATE = 60
/**
* Replace the globally defined implementation or define it globally.
*
* @param {Object|Number} [options]
* @api public
*/
AnimationFrame.shim = function(options) {
var animationFrame = new AnimationFrame(options)
window.requestAnimationFrame = function(callback) {
return animationFrame.request(callback)
}
window.cancelAnimationFrame = function(id) {
return animationFrame.cancel(id)
}
return animationFrame
}
/**
* Crossplatform Date.now()
*
* @return {Number} time in ms
* @api public
*/
AnimationFrame.now = Date.now || function() {
return (new Date).getTime()
}
/**
* Replacement for PerformanceTiming.navigationStart for the case when
* performance.now is not implemented.
*
* https://developer.mozilla.org/en-US/docs/Web/API/PerformanceTiming.navigationStart
*
* @type {Number}
* @api public
*/
AnimationFrame.navigationStart = AnimationFrame.now()
/**
* Crossplatform performance.now()
*
* https://developer.mozilla.org/en-US/docs/Web/API/Performance.now()
*
* @return {Number} relative time in ms
* @api public
*/
AnimationFrame.perfNow = function() {
if (window.performance && window.performance.now) return window.performance.now()
return AnimationFrame.now() - AnimationFrame.navigationStart
}
/**
* Is native animation frame implemented. The right value is set during feature
* detection step.
*
* @type {Boolean}
* @api public
*/
AnimationFrame.hasNative = false
/**
* Request animation frame.
* We will use the native RAF as soon as we know it does works.
*
* @param {Function} callback
* @return {Number} timeout id or requested animation frame id
* @api public
*/
AnimationFrame.prototype.request = function(callback) {
var self = this,
delay
// Alawys inc counter to ensure it never has a conflict with the native counter.
// After the feature test phase we don't know exactly which implementation has been used.
// Therefore on #cancel we do it for both.
++this._tickCounter
if (AnimationFrame.hasNative && self.options.useNative && !this._isCustomFrameRate) {
return nativeRequestAnimationFrame(callback)
}
if (!callback) throw new TypeError('Not enough arguments')
if (this._timeoutId == null) {
// Much faster than Math.max
// http://jsperf.com/math-max-vs-comparison/3
// http://jsperf.com/date-now-vs-date-gettime/11
delay = this._frameLength + this._lastTickTime - AnimationFrame.now()
if (delay < 0) delay = 0
this._timeoutId = window.setTimeout(function() {
var id
self._lastTickTime = AnimationFrame.now()
self._timeoutId = null
++self._tickCounter
for (id in self._callbacks) {
if (self._callbacks[id]) {
if (AnimationFrame.hasNative && self.options.useNative) {
nativeRequestAnimationFrame(self._callbacks[id])
} else {
self._callbacks[id](AnimationFrame.perfNow())
}
delete self._callbacks[id]
}
}
}, delay)
}
this._callbacks[this._tickCounter] = callback
return this._tickCounter
}
/**
* Cancel animation frame.
*
* @param {Number} timeout id or requested animation frame id
*
* @api public
*/
AnimationFrame.prototype.cancel = function(id) {
if (AnimationFrame.hasNative && this.options.useNative) nativeCancelAnimationFrame(id)
delete this._callbacks[id]
}
// Support commonjs wrapper, amd define and plain window.
if (typeof exports == 'object' && typeof module == 'object') {
module.exports = AnimationFrame
} else if (typeof define == 'function' && define.amd) {
define(function() { return AnimationFrame })
} else {
window.AnimationFrame = AnimationFrame
}
}(window));
(function(window) {
var animationFrame = new AnimationFrame(40);
var offset = 0;
var mover = function(){
if (offset > 100) {
offset = 0;
}
$("#test").css("margin-left", offset);
offset += 1;
animationFrame.request(mover);
}
animationFrame.request(mover);
}(window));
});//]]>
</script>
</head>
<body>
<div id="test" style="margin-left: 94px;">Test</div>
</body></html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment