Skip to content

Instantly share code, notes, and snippets.

@shshaw
Last active October 25, 2016 17:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shshaw/8e9262bffb2627e59de79433a305da7e to your computer and use it in GitHub Desktop.
Save shshaw/8e9262bffb2627e59de79433a305da7e to your computer and use it in GitHub Desktop.
Listener Reactive Animation Helper [WIP]
<button>Click me</button>
<script>console.clear();</script>
// 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