Last active
October 25, 2016 17:07
-
-
Save shshaw/8e9262bffb2627e59de79433a305da7e to your computer and use it in GitHub Desktop.
Listener Reactive Animation Helper [WIP]
This file contains hidden or 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
<button>Click me</button> | |
<script>console.clear();</script> |
This file contains hidden or 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
// Micro jQuery-like wrapper using native DOM methods. | |
function $$(selector, context){ | |
if ( !(this instanceof $$) ) { return new $$(selector, context); } | |
if ( selector ) { | |
var els = ( typeof selector === 'string' ? | |
(context || document).querySelectorAll(selector) : | |
selector instanceof Node || selector === window ? | |
[selector] : selector ), | |
length = this.length = els.length, | |
i = 0; | |
for ( ; i < length; i++ ) { this[i] = els[i]; } | |
} | |
return this; | |
} | |
var fn = $$.prototype = $$.fn = Object.create(Array.prototype); | |
fn.constructor = $$, | |
fn.each = fn.forEach; | |
function createMethod(method, property){ | |
return function(){ | |
var args = arguments, target; | |
this.each(function(el){ | |
target = ( property ? el[property] : el ); | |
target[method].apply(target,args); | |
}); | |
return this; | |
} | |
} | |
fn.addClass = createMethod('add','classList'); | |
fn.removeClass = createMethod('remove','classList'); | |
fn.attr = createMethod('setAttribute'); | |
fn.addEventListener = fn.on = createMethod('addEventListener'); | |
fn.removeEventListener = fn.off = createMethod('removeEventListener'); | |
/*////////////////////////////////////////*/ | |
/* Main functionality */ | |
var listeners = {}; | |
var customEvents = { | |
PointerPosition: { | |
'mousemove': function(){} | |
}, | |
PointerX: {}, | |
PointerY: {}, | |
Scroll: {}, | |
ScrollX: {}, | |
ScrollY: {} | |
}; | |
// Return a Listener instance | |
function Listener(target, event, opts) { | |
if (!(this instanceof Listener)) { return new Listener(target, event, opts); } | |
listeners[event] = listeners[event] || []; | |
listeners[event].push(this); | |
if ( typeof opts == 'function' ) { | |
// If opts is a function, it's simply a callback to register. | |
this.add(opts); | |
} else { | |
// Otherwise, we may need add some logic to track values, apply styles, etc, based on the options. | |
} | |
this.target = $$(target); | |
if ( customEvents[event] ) { | |
// Use custom Event logic. | |
} else if ( this.target ) { | |
// Add standard event listener of trigger function. | |
this.target.addEventListener(event, this.trigger.bind(this)); | |
} | |
} | |
// Listener instance methods | |
Listener.prototype = { | |
target: null, | |
opts: { | |
}, | |
add: function(callback){ | |
this.callbacks = this.callbacks || []; | |
this.callbacks.push(callback); | |
}, // Add an additional callback to this listener. | |
remove: function(callback){}, // Remove a callback from this listener. | |
active: true, | |
on: function(){ this.active = true; }, // Callbacks are called when event is triggered. | |
off: function(){ this.active = false; }, // Callbacks are not called when event is triggered. | |
// Trigger the event with specific data. | |
trigger: function(){ | |
if ( !this.active ) { return; } // on/off functionality | |
var args = arguments, | |
i = 0, | |
len = this.callbacks.length; | |
for (; i < len; i++) { this.callbacks[i].apply(this, args); } | |
}, | |
// Recording & playback | |
record: function(time){}, // Begin recording all event data for a set period of time. | |
stopRecord: function(){}, // Stop recording. | |
getRecordingData: function(){}, // Return recording data to be saved. | |
setRecordingData: function(){}, // Manually set the recording data. | |
play: function(){}, // Replays the recorded data, likely using the trigger method & requestAnimationFrame | |
pause: function(){}, | |
stop: function(){}, | |
restart: function(){} | |
}; | |
/*////////////////////////////////////////*/ | |
/* Global Methods */ | |
Listener.trigger = function(event, data, target){}; // Trigger an event, custom or otherwise, optionally with a target | |
Listener.record = function(time){}; // Start recording all registered listener activity | |
Listener.stopRecord = function(){}; // Stop recording | |
Listener.getRecordingData = function(){}; | |
Listener.setRecordingData = function(){}; | |
Listener.play = function(){}; // Replays the recorded data, likely using the trigger method & requestAnimationFrame | |
Listener.pause = function(){}; | |
Listener.stop = function(){}; | |
Listener.restart = function(){}; | |
/*////////////////////////////////////////*/ | |
var myListener = Listener('button', 'click', function(){ | |
alert('clicked!'); | |
}); | |
console.log(myListener); | |
/*////////////////////////////////////////*/ | |
/* Usage examples */ | |
/* | |
Listeners.add(target, event, callback); | |
Listeners.remove(target, event, callback); | |
Listeners.record(); // Begin recording any event triggers that have listeners | |
setTimeout(Listeners.stopRecord, 1000); // Stop recording after 1 second | |
Listeners.trigger(event, customEventData); // Manually trigger an event with specific data | |
Listener.add(element, { | |
‘PointerX': { | |
property: ‘translateX’, | |
range: [‘-50%’,’50%’], | |
relative: ‘viewport’ | |
}, | |
‘PointerY': { | |
property: ‘translateY’, | |
range: [‘-10%’,’10%’], | |
relative: ‘viewport’ | |
}, | |
}); | |
Listeners.record(1); // Record events for 1 second. | |
Listeners.play(loop); // Replay the recorded data, trigger callback with updated parameters every requestAnimationFrame, optionally looping the playback | |
*/ | |
/*////////////////////////////////////////*/ | |
// Possible helpers | |
function AnimationLoop(){ | |
var animations = [], | |
animating = true, | |
frame; | |
function animate(){ | |
if ( frame ) { return; } | |
if ( animating ) { frame = requestAnimationFrame(animate); } | |
var i = animations.length; | |
while ( i-- ) { | |
if ( !animations[i] || animations[i]() === false ) { animations.splice(i, 1); } | |
} | |
frame = null; | |
}; | |
function add(){ | |
animations.push.apply(animations,arguments); | |
}; | |
add.apply(null,arguments); | |
animate(); | |
return { | |
animations: animations, | |
add: add, | |
stop: function(){ animating = false; }, | |
start: function(){ animating = true; animate(); } | |
}; | |
} | |
/*////////////////////////////////////////*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment