Skip to content

Instantly share code, notes, and snippets.

@theadam
Last active February 5, 2016 03:51
Show Gist options
  • Save theadam/8b3742d244436de4033f to your computer and use it in GitHub Desktop.
Save theadam/8b3742d244436de4033f to your computer and use it in GitHub Desktop.
requirebin sketch
var Stream = require('basic-streams/lib/fantasy').Stream;
var raf = require('raf');
var stepper = require('react-motion/lib/stepper');
var presets = require('react-motion/lib/presets');
var now = require("performance-now");
function Emitter(){
var subscribers = [];
return {
on: function(fn) {
subscribers.push(fn);
},
off: function(fn) {
var index = subscribers.indexOf(fn);
if (index > -1) {
subscribers.splice(index, 1);
}
},
emit: function(val) {
for (var i = 0; i < subscribers.length; i++) {
subscribers[i](val);
}
}
};
}
function Mailbox(){
var emitter = Emitter();
return {
address: function(value){
emitter.emit(value);
},
stream: new Stream(function(sink){
var listener = function(value){
sink(value);
}
emitter.on(listener);
return function(){
emitter.off(listener);
}
})
};
}
function State(val, config){
if (Array.isArray(val)) {
var state = {
x: val.slice(),
states: val.map(function(v) {
return State(v, config);
}),
step: function(delta) {
_moving = false;
for (var i = 0; i < this.states.length; i++) {
this.states[i].destination = this.destination[i];
this.states[i].step(delta);
this.x[i] = this.states[i].x;
if (this.states[i].moving) (_moving = true);
}
}
};
var _moving = false;
Object.defineProperty(state, 'moving', {
get: function() {
return _moving;
},
set: function(v) {
for (var i = 0; i < state.states.length; i++) {
state.states[i].moving = v;
}
_moving = v;
}
});
var _destination;
Object.defineProperty(state, 'destination', {
get: function() {
return _destination;
},
set: function(v) {
for (var i = 0; i < state.states; i++) {
state.states[i].destination = v[i];
}
_destination = v;
}
});
return state;
}
if (typeof val === 'object') {
var state = {
x: Object.keys(val).reduce(function(acc, v) {
acc[v] = val[v];
return acc;
}, {}),
states: Object.keys(val).reduce(function(acc, v) {
acc[v] = State(val[v], config);
return acc;
}, {}),
step: function(delta) {
_moving = false;
var keys = Object.keys(this.states);
for (var i = 0; i < keys.length; i++) {
this.states[keys[i]].step(delta);
this.x[keys[i]] = this.states[keys[i]].x;
if (this.states[keys[i]].moving) (_moving = true);
}
}
};
var _moving = false;
Object.defineProperty(state, 'moving', {
get: function() {
return _moving;
},
set: function(v) {
var keys = Object.keys(this.states);
for (var i = 0; i < keys.length; i++) {
state.states[keys[i]].moving = v;
}
_moving = v;
}
});
var _destination;
Object.defineProperty(state, 'destination', {
get: function() {
return _destination;
},
set: function(v) {
var keys = Object.keys(this.states);
for (var i = 0; i < keys.length; i++) {
state.states[keys[i]].destination = v[keys[i]];
}
_destination = v;
}
});
return state;
}
return {
x: val,
stiffness: config.stiffness,
damping: config.damping,
destination: undefined,
vel: 0,
moving: false,
step: function(delta) {
var newStuff = stepper(delta / 1000,
this.x,
this.vel,
this.destination,
this.stiffness,
this.damping,
0.05);
this.x = newStuff[0];
this.vel = newStuff[1];
if (this.x === this.destination && this.vel === 0) this.moving = false;
}
}
}
function Animation(val, config) {
if (!config) config = presets.noWobble;
var emitter = Emitter();
var state = State(val, config);
var last;
var settleEmitter = Emitter();
settleEmitter.on(function(){
state.moving = false;
});
var moveEmitter = Emitter();
moveEmitter.on(function(){
state.moving = true;
});
function update() {
var current = now();
var delta = current - last;
last = current;
state.step(delta);
emitter.emit(state.x);
if (state.moving) raf(update);
else settleEmitter.emit();
}
return {
animateTo: function(val){
state.destination = val;
last = state.moving ? last : now();
if (!state.moving) (moveEmitter.emit(), raf(update));
},
subscribe: function(listener){
emitter.on(listener);
},
unsubscribe: function(listener){
emitter.off(listener);
},
onSettle: function(fn) {
settleEmitter.on(fn);
},
offSettle: function(fn) {
settleEmitter.off(fn);
},
onMove: function(fn) {
moveEmitter.on(fn);
},
offMove: function(fn) {
moveEmitter.off(fn);
}
};
}
var container = document.getElementById('container');
var animation = Animation({x: 0, y: 0}, presets.wobbly);
document.addEventListener('mousemove', function(e){
animation.animateTo({x: e.pageX, y: e.pageY});
});
document.addEventListener('touchmove', function(e){
animation.animateTo({x: e.touches[0].pageX, y: e.touches[0].pageY});
});
animation.subscribe(function(v){
container.style.transform = 'translate3d(' + v.x + 'px,' + v.y + 'px,0)';
});
animation.onMove(function(){
container.style.backgroundColor = 'blue';
});
animation.onSettle(function(){
container.style.backgroundColor = 'red';
});
require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){(function(process){(function(){var getNanoSeconds,hrtime,loadTime;if(typeof performance!=="undefined"&&performance!==null&&performance.now){module.exports=function(){return performance.now()}}else if(typeof process!=="undefined"&&process!==null&&process.hrtime){module.exports=function(){return(getNanoSeconds()-loadTime)/1e6};hrtime=process.hrtime;getNanoSeconds=function(){var hr;hr=hrtime();return hr[0]*1e9+hr[1]};loadTime=getNanoSeconds()}else if(Date.now){module.exports=function(){return Date.now()-loadTime};loadTime=Date.now()}else{module.exports=function(){return(new Date).getTime()-loadTime};loadTime=(new Date).getTime()}}).call(this)}).call(this,require("_process"))},{_process:2}],2:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){var source=ev.source;if((source===window||source===null)&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],raf:[function(require,module,exports){var now=require("performance-now"),global=typeof window==="undefined"?{}:window,vendors=["moz","webkit"],suffix="AnimationFrame",raf=global["request"+suffix],caf=global["cancel"+suffix]||global["cancelRequest"+suffix];for(var i=0;i<vendors.length&&!raf;i++){raf=global[vendors[i]+"Request"+suffix];caf=global[vendors[i]+"Cancel"+suffix]||global[vendors[i]+"CancelRequest"+suffix]}if(!raf||!caf){var last=0,id=0,queue=[],frameDuration=1e3/60;raf=function(callback){if(queue.length===0){var _now=now(),next=Math.max(0,frameDuration-(_now-last));last=next+_now;setTimeout(function(){var cp=queue.slice(0);queue.length=0;for(var i=0;i<cp.length;i++){if(!cp[i].cancelled){try{cp[i].callback(last)}catch(e){setTimeout(function(){throw e},0)}}}},Math.round(next))}queue.push({handle:++id,callback:callback,cancelled:false});return id};caf=function(handle){for(var i=0;i<queue.length;i++){if(queue[i].handle===handle){queue[i].cancelled=true}}}}module.exports=function(fn){return raf.call(global,fn)};module.exports.cancel=function(){caf.apply(global,arguments)}},{"performance-now":1}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}if(canPost){var queue=[];window.addEventListener("message",function(ev){var source=ev.source;if((source===window||source===null)&&ev.data==="process-tick"){ev.stopPropagation();if(queue.length>0){var fn=queue.shift();fn()}}},true);return function nextTick(fn){queue.push(fn);window.postMessage("process-tick","*")}}return function nextTick(fn){setTimeout(fn,0)}}();process.title="browser";process.browser=true;process.env={};process.argv=[];function noop(){}process.on=noop;process.addListener=noop;process.once=noop;process.off=noop;process.removeListener=noop;process.removeAllListeners=noop;process.emit=noop;process.binding=function(name){throw new Error("process.binding is not supported")};process.cwd=function(){return"/"};process.chdir=function(dir){throw new Error("process.chdir is not supported")}},{}],"performance-now":[function(require,module,exports){(function(process){(function(){var getNanoSeconds,hrtime,loadTime;if(typeof performance!=="undefined"&&performance!==null&&performance.now){module.exports=function(){return performance.now()}}else if(typeof process!=="undefined"&&process!==null&&process.hrtime){module.exports=function(){return(getNanoSeconds()-loadTime)/1e6};hrtime=process.hrtime;getNanoSeconds=function(){var hr;hr=hrtime();return hr[0]*1e9+hr[1]};loadTime=getNanoSeconds()}else if(Date.now){module.exports=function(){return Date.now()-loadTime};loadTime=Date.now()}else{module.exports=function(){return(new Date).getTime()-loadTime};loadTime=(new Date).getTime()}}).call(this)}).call(this,require("_process"))},{_process:1}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({1:[function(require,module,exports){"use strict";var _slicedToArray=function(){function sliceIterator(arr,i){var _arr=[];var _n=true;var _d=false;var _e=undefined;try{for(var _i=arr[Symbol.iterator](),_s;!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break}}catch(err){_d=true;_e=err}finally{try{if(!_n&&_i["return"])_i["return"]()}finally{if(_d)throw _e}}return _arr}return function(arr,i){if(Array.isArray(arr)){return arr}else if(Symbol.iterator in Object(arr)){return sliceIterator(arr,i)}else{throw new TypeError("Invalid attempt to destructure non-iterable instance")}}}();Object.defineProperty(exports,"__esModule",{value:true});exports.just=just;exports.map=map;exports.filter=filter;exports.chain=chain;exports.chainLatest=chainLatest;exports.ap=ap;exports.map2=map2;exports.map3=map3;exports.join=join;exports.scan=scan;exports.take=take;exports.takeWhile=takeWhile;exports.takeUntil=takeUntil;exports.skip=skip;exports.skipWhile=skipWhile;exports.skipDuplicates=skipDuplicates;exports.multicast=multicast;exports.startWith=startWith;exports.combineArray=combineArray;exports.combineObject=combineObject;exports.transduce=transduce;function fromArray(xs){return function(sink){xs.forEach(function(x){sink(x)});return function(){}}}var empty=exports.empty=function(){return function(){}};function just(x){return function(sink){sink(x);return function(){}}}function map(fn){return function(stream){return function(sink){return stream(function(payload){return sink(fn(payload))})}}}function filter(predicate){return function(stream){return function(sink){return stream(function(payload){if(predicate(payload)){sink(payload)}})}}}function chain(fn){return function(stream){return function(sink){var spawnedDisposers=[];var mainDisposer=stream(function(payload){spawnedDisposers.push(fn(payload)(sink))});return function(){spawnedDisposers.forEach(function(fn){return fn()});mainDisposer()}}}}function chainLatest(fn){return function(stream){return function(sink){var spawnedDisposers=function(){};var mainDisposer=stream(function(payload){spawnedDisposers();spawnedDisposers=fn(payload)(sink)});return function(){spawnedDisposers();mainDisposer()}}}}function ap(streamf){return function(streamv){return function(sink){var latestF={type:"nothing"};var latestV={type:"nothing"};var push=function(){if(latestF.type==="just"&&latestV.type==="just"){var fn=latestF.value;sink(fn(latestV.value))}};var disposef=streamf(function(f){latestF={type:"just",value:f};push()});var disposev=streamv(function(v){latestV={type:"just",value:v};push()});return function(){disposef();disposev()}}}}function map2(fn){return function(sA,sB){var ofFn=map(function(a){return function(b){return fn(a,b)}})(sA);return ap(ofFn)(sB)}}function map3(fn){return function(sA,sB,sC){var ofFn=map(function(a){return function(b){return function(c){return fn(a,b,c)}}})(sA);return ap(ap(ofFn)(sB))(sC)}}function join(streams){return chain(function(x){return x})(fromArray(streams))}function scan(reducer,seed){return function(stream){return function(sink){var current=seed;sink(current);return stream(function(x){current=reducer(current,x);sink(current)})}}}function take(n){return function(stream){return function(sink){var count=0;var disposer=null;var dispose=function(){if(disposer!==null){disposer();disposer=null}};disposer=stream(function(x){count++;if(count<=n){sink(x)}if(count>=n){dispose()}});if(count>=n){dispose()}return dispose}}}function takeWhile(pred){return function(stream){return function(sink){var completed=false;var disposer=null;var dispose=function(){if(disposer!==null){disposer();disposer=null}};disposer=stream(function(x){if(!completed){if(pred(x)){sink(x)}else{completed=true;dispose()}}});if(completed){dispose()}return dispose}}}function takeUntil(controller){return function(stream){return function(sink){var mainDisposer=null;var ctrlDisposer=null;var dispose=function(){if(mainDisposer!==null){mainDisposer();mainDisposer=null}if(ctrlDisposer!==null){ctrlDisposer();ctrlDisposer=null}};mainDisposer=stream(sink);ctrlDisposer=controller(dispose);if(mainDisposer===null){dispose()}return dispose}}}function skip(n){return function(stream){return function(sink){var count=0;return stream(function(x){count++;if(count>n){sink(x)}})}}}function skipWhile(pred){return function(stream){return function(sink){var started=false;return stream(function(x){if(!started){started=!pred(x)}if(started){sink(x)}})}}}function skipDuplicates(comp){return function(stream){return function(sink){var latest={type:"nothing"};return stream(function(x){if(latest.type==="nothing"||!comp(latest.value,x)){latest={type:"just",value:x};sink(x)}})}}}function multicast(stream){var sinks=[];var push=function(x){sinks.forEach(function(sink){if(sinks.indexOf(sink)!==-1){sink(x)}})};var unsub=null;return function(sink){var disposed=false;sinks=[].concat(sinks,[sink]);if(sinks.length===1){unsub=stream(push)}return function(){if(disposed){return}disposed=true;var index=sinks.indexOf(sink);sinks=[].concat(sinks.slice(0,index),sinks.slice(index+1,sinks.length));if(sinks.length===0&&unsub!==null){unsub();unsub=null}}}}function startWith(x){return function(stream){return function(sink){sink(x);return stream(sink)}}}function combineArray(arr){return arr.reduce(map2(function(arr,i){return arr.concat([i])}),just([]))}var fromPairsLifted=map(function(pairs){var result={};pairs.forEach(function(_ref){var _ref2=_slicedToArray(_ref,2);var key=_ref2[0];var value=_ref2[1];result[key]=value});return result});function combineObject(obj){var ofPairs=Object.keys(obj).map(function(key){return map(function(x){return[key,x]})(obj[key])});return fromPairsLifted(combineArray(ofPairs))}function transduce(transducer){return function(stream){return function(sink){var thisDisposed=false;var sourceDisposer=null;var transformer=transducer({"@@transducer/result":function(){},"@@transducer/step":function(result,input){if(!thisDisposed){sink(input)}return result}});var disposeSource=function(){if(sourceDisposer!==null){sourceDisposer();sourceDisposer=null}};sourceDisposer=stream(function(x){if(transformer===null){return}if(null!==transformer["@@transducer/step"](null,x)){transformer["@@transducer/result"](null);transformer=null;disposeSource()}});if(transformer===null){disposeSource()}return function(){thisDisposed=true;disposeSource()}}}}},{}],2:[function(require,module,exports){module.exports={equals:"equals",concat:"concat",empty:"empty",map:"map",ap:"ap",of:"of",reduce:"reduce",sequence:"sequence",chain:"chain",extend:"extend",extract:"extract"}},{}],"basic-streams/lib/fantasy":[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.Stream=undefined;var _fantasyLand=require("fantasy-land");var _fantasyLand2=_interopRequireDefault(_fantasyLand);var _index=require("./index");var bs=_interopRequireWildcard(_index);function _interopRequireWildcard(obj){if(obj&&obj.__esModule){return obj}else{var newObj={};if(obj!=null){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key))newObj[key]=obj[key]}}newObj.default=obj;return newObj}}function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}var Stream=exports.Stream=function(){function Stream(basicStream){_classCallCheck(this,Stream);this.observe=basicStream}Stream.prototype.concat=function concat(other){return new Stream(bs.join([this.observe,other.observe]))};Stream.empty=function empty(){return new Stream(bs.empty)};Stream.prototype.empty=function empty(){return Stream.empty()};Stream.prototype.map=function map(f){return new Stream(bs.map(f)(this.observe))};Stream.prototype.ap=function ap(other){var streamF=this.observe;return new Stream(bs.ap(streamF)(other.observe))};Stream.of=function of(x){return new Stream(bs.just(x))};Stream.prototype.of=function of(x){return Stream.of(x)};Stream.prototype.chain=function chain(f){return new Stream(bs.chain(function(x){return f(x).observe})(this.observe))};Stream.prototype.filter=function filter(f){return new Stream(bs.filter(f)(this.observe))};Stream.prototype.scan=function scan(f,seed){return new Stream(bs.scan(f,seed)(this.observe))};Stream.prototype.chainLatest=function chainLatest(f){return new Stream(bs.chainLatest(function(x){return f(x).observe})(this.observe))};Stream.prototype.take=function take(n){return new Stream(bs.take(n)(this.observe))};Stream.prototype.takeWhile=function takeWhile(f){return new Stream(bs.takeWhile(f)(this.observe))};Stream.prototype.takeUntil=function takeUntil(other){return new Stream(bs.takeUntil(other.observe)(this.observe))};Stream.prototype.skip=function skip(n){return new Stream(bs.skip(n)(this.observe))};Stream.prototype.skipWhile=function skipWhile(f){return new Stream(bs.skipWhile(f)(this.observe))};Stream.prototype.skipDuplicates=function skipDuplicates(f){return new Stream(bs.skipDuplicates(f)(this.observe))};Stream.prototype.multicast=function multicast(){return new Stream(bs.multicast(this.observe))};Stream.prototype.startWith=function startWith(x){return new Stream(bs.startWith(x)(this.observe))};Stream.prototype.transduce=function transduce(transducer){return new Stream(bs.transduce(transducer)(this.observe))};Stream.join=function join(streams){return new Stream(bs.join(streams.map(function(x){return x.observe})))};Stream.map2=function map2(f){var lifted=bs.map2(f);return function(sA,sB){return new Stream(lifted(sA.observe,sB.observe))}};Stream.map3=function map3(f){var lifted=bs.map3(f);return function(sA,sB,sC){return new Stream(lifted(sA.observe,sB.observe,sC.observe))}};Stream.combineArray=function combineArray(arr){return new Stream(bs.combineArray(arr.map(function(x){return x.observe})))};Stream.combineObject=function combineObject(obj){var ofBasicStreams={};Object.keys(obj).forEach(function(key){ofBasicStreams[key]=obj[key].observe});return new Stream(bs.combineObject(ofBasicStreams))};return Stream}();function addFlMethods(constructor,proto){["concat","empty","map","ap","of","chain"].forEach(function(name){proto[_fantasyLand2.default[name]]=proto[name]});["empty","of"].forEach(function(name){constructor[_fantasyLand2.default[name]]=constructor[name]})}addFlMethods(Stream,Stream.prototype)},{"./index":1,"fantasy-land":2}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({"react-motion/lib/stepper":[function(require,module,exports){"use strict";exports.__esModule=true;exports["default"]=stepper;var reusedTuple=[];function stepper(secondPerFrame,x,v,destX,k,b,precision){var Fspring=-k*(x-destX);var Fdamper=-b*v;var a=Fspring+Fdamper;var newV=v+a*secondPerFrame;var newX=x+newV*secondPerFrame;if(Math.abs(newV)<precision&&Math.abs(newX-destX)<precision){reusedTuple[0]=destX;reusedTuple[1]=0;return reusedTuple}reusedTuple[0]=newX;reusedTuple[1]=newV;return reusedTuple}module.exports=exports["default"]},{}]},{},[]);require=function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s}({"react-motion/lib/presets":[function(require,module,exports){"use strict";exports.__esModule=true;exports["default"]={noWobble:{stiffness:170,damping:26},gentle:{stiffness:120,damping:14},wobbly:{stiffness:180,damping:12},stiff:{stiffness:210,damping:20}};module.exports=exports["default"]},{}]},{},[]);var Stream=require("basic-streams/lib/fantasy").Stream;var raf=require("raf");var stepper=require("react-motion/lib/stepper");var presets=require("react-motion/lib/presets");var now=require("performance-now");function Emitter(){var subscribers=[];return{on:function(fn){subscribers.push(fn)},off:function(fn){var index=subscribers.indexOf(fn);if(index>-1){subscribers.splice(index,1)}},emit:function(val){for(var i=0;i<subscribers.length;i++){subscribers[i](val)}}}}function Mailbox(){var emitter=Emitter();return{address:function(value){emitter.emit(value)},stream:new Stream(function(sink){var listener=function(value){sink(value)};emitter.on(listener);return function(){emitter.off(listener)}})}}function State(val,config){if(Array.isArray(val)){var state={x:val.slice(),states:val.map(function(v){return State(v,config)}),step:function(delta){_moving=false;for(var i=0;i<this.states.length;i++){this.states[i].destination=this.destination[i];this.states[i].step(delta);this.x[i]=this.states[i].x;if(this.states[i].moving)_moving=true}}};var _moving=false;Object.defineProperty(state,"moving",{get:function(){return _moving},set:function(v){for(var i=0;i<state.states.length;i++){state.states[i].moving=v}_moving=v}});var _destination;Object.defineProperty(state,"destination",{get:function(){return _destination},set:function(v){for(var i=0;i<state.states;i++){state.states[i].destination=v[i]}_destination=v}});return state}if(typeof val==="object"){var state={x:Object.keys(val).reduce(function(acc,v){acc[v]=val[v];return acc},{}),states:Object.keys(val).reduce(function(acc,v){acc[v]=State(val[v],config);return acc},{}),step:function(delta){_moving=false;var keys=Object.keys(this.states);for(var i=0;i<keys.length;i++){this.states[keys[i]].step(delta);this.x[keys[i]]=this.states[keys[i]].x;if(this.states[keys[i]].moving)_moving=true}}};var _moving=false;Object.defineProperty(state,"moving",{get:function(){return _moving},set:function(v){var keys=Object.keys(this.states);for(var i=0;i<keys.length;i++){state.states[keys[i]].moving=v}_moving=v}});var _destination;Object.defineProperty(state,"destination",{get:function(){return _destination},set:function(v){var keys=Object.keys(this.states);for(var i=0;i<keys.length;i++){state.states[keys[i]].destination=v[keys[i]]}_destination=v}});return state}return{x:val,stiffness:config.stiffness,damping:config.damping,destination:undefined,vel:0,moving:false,step:function(delta){var newStuff=stepper(delta/1e3,this.x,this.vel,this.destination,this.stiffness,this.damping,.05);this.x=newStuff[0];this.vel=newStuff[1];if(this.x===this.destination&&this.vel===0)this.moving=false}}}function Animation(val,config){if(!config)config=presets.noWobble;var emitter=Emitter();var state=State(val,config);var last;var settleEmitter=Emitter();settleEmitter.on(function(){state.moving=false});var moveEmitter=Emitter();moveEmitter.on(function(){state.moving=true});function update(){var current=now();var delta=current-last;last=current;state.step(delta);emitter.emit(state.x);if(state.moving)raf(update);else settleEmitter.emit()}return{animateTo:function(val){state.destination=val;last=state.moving?last:now();if(!state.moving)moveEmitter.emit(),raf(update)},subscribe:function(listener){emitter.on(listener)},unsubscribe:function(listener){emitter.off(listener)},onSettle:function(fn){settleEmitter.on(fn)},offSettle:function(fn){settleEmitter.off(fn)},onMove:function(fn){moveEmitter.on(fn)},offMove:function(fn){moveEmitter.off(fn)}}}var container=document.getElementById("container");var animation=Animation({x:0,y:0},presets.wobbly);document.addEventListener("mousemove",function(e){animation.animateTo({x:e.pageX,y:e.pageY})});document.addEventListener("touchmove",function(e){animation.animateTo({x:e.touches[0].pageX,y:e.touches[0].pageY})});animation.subscribe(function(v){container.style.transform="translate3d("+v.x+"px,"+v.y+"px,0)"});animation.onMove(function(){container.style.backgroundColor="blue"});animation.onSettle(function(){container.style.backgroundColor="red"});
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"raf": "3.1.0",
"performance-now": "0.2.0",
"basic-streams": "0.3.3",
"react-motion": "0.4.2"
}
}
<!-- contents of this file will be placed inside the <body> -->
<div id='container'></div>
<!-- contents of this file will be placed inside the <head> -->
<style>
#container {
width: 100px;
height: 100px;
border-radius: 100px;
background-color: red;
position: absolute;
top: 20px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment