Skip to content

Instantly share code, notes, and snippets.

@kamicane
Last active January 12, 2017 09:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kamicane/49567b290698badce686 to your computer and use it in GitHub Desktop.
Save kamicane/49567b290698badce686 to your computer and use it in GitHub Desktop.
requirebin sketch
another requirebin equation-designer early demo
"use strict";
var ready = require("elements/domready");
var get = function(one, two, three, four, t) {
var v = 1 - t,
b1 = t * t * t,
b2 = 3 * t * t * v,
b3 = 3 * t * v * v,
b4 = v * v * v;
return four * b1 + three * b2 + two * b3 + one * b4;
};
var clamp = function(n, min, max) {
if (n < min) return min;
if (n > max) return max;
return n;
};
var bezier = function(vectors, epsilon) {
if (vectors.length % 3 !== 1) throw new Error("invalid input");
for (var i = 0; i < vectors.length - 1; i += 3) {
var c0 = vectors[i],
c1 = vectors[i + 1],
c2 = vectors[i + 2],
c3 = vectors[i + 3];
if (i === 0) c0.x = 0; // clamp the first 0 to x 0
else c0.x = clamp(c0.x, 0, 1);
if (i === vectors.length - 4) c3.x = 1;
else c3.x = clamp(c3.x, c0.x, 1);
// clamp the rest
c1.x = clamp(c1.x, c0.x, c3.x);
c2.x = clamp(c2.x, c0.x, c3.x);
}
return function(x) {
var c0, c1, c2, c3;
for (var i = 0; i < vectors.length - 1; i += 3) {
c0 = vectors[i];
c1 = vectors[i + 1];
c2 = vectors[i + 2];
c3 = vectors[i + 3];
if (x >= c0.x && x <= c3.x) break;
}
var lower = 0, upper = 1, t = x, xt;
if (x < lower) return get(c0.y, c1.y, c2.y, c3.y, lower);
if (x > upper) return get(c0.y, c1.y, c2.y, c3.y, upper);
while (lower < upper) {
xt = get(c0.x, c1.x, c2.x, c3.x, t);
if (Math.abs(xt - x) < epsilon) return get(c0.y, c1.y, c2.y, c3.y, t);
if (x > xt) lower = t;
else upper = t;
t = (upper - lower) * 0.5 + lower;
}
// Failure
return get(c0.y, c1.y, c2.y, c3.y, t);
};
};
var Transition = require("transition");
var width = 900;
var height = 900;
var boxLeft = 100,
boxTop = 300;
var boxWidth = 600,
boxHeight = 300;
var convertVectorsToPixels = function(vectors) {
return vectors.map(function(v) {
return { x: boxLeft + (v.x * boxWidth), y: boxTop + ((-v.y + 1) * boxHeight) };
});
};
// note: the cubic-bezier curve has its Y axis inverted
var convertVectorsToPercentages = function(vectors) {
return vectors.map(function(v) {
return { x: (v.x - boxLeft) / boxWidth, y: -((v.y - boxTop) / boxHeight) + 1 };
});
};
var pixelVectors = convertVectorsToPixels([
{ x: 0, y: 0 }, { x: 0, y: 1 }, { x: 0.5, y: 1 }, { x: 0.5, y: 0 },
{ x: 0.5, y: 1 }, { x: 1, y: 1 }, { x: 1, y: 0 }
]);
var lerp = function(from, to, delta) {
return (to - from) * delta + from;
};
var equation;
var simplify = function(n, places) {
return Number(n).toFixed(places).replace(/\.?0+$/, '');
};
var render = function(ctx) {
var vectors = convertVectorsToPercentages(pixelVectors);
equation = bezier(vectors, 0.0001); // vectors are now clamped
pixelVectors = convertVectorsToPixels(vectors); // convert again for clamping
var i, c0, c1, c2, c3;
// clear canvas
ctx.clearRect(0, 0, width, height);
// draw main box
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.rect(boxLeft, boxTop, boxWidth, boxHeight);
ctx.closePath();
ctx.stroke();
// draw bezier curves
ctx.strokeStyle = "red";
c0 = pixelVectors[0];
ctx.beginPath();
ctx.moveTo(c0.x, c0.y);
for (i = 1; i < pixelVectors.length - 1; i += 3) {
c1 = pixelVectors[i];
c2 = pixelVectors[i + 1];
c3 = pixelVectors[i + 2];
ctx.bezierCurveTo(c1.x, c1.y, c2.x, c2.y, c3.x, c3.y);
}
ctx.stroke();
// draw control lines
ctx.strokeStyle = "green";
for (i = 0; i < pixelVectors.length - 1; i += 3) {
c0 = pixelVectors[i];
c1 = pixelVectors[i + 1];
c2 = pixelVectors[i + 2];
c3 = pixelVectors[i + 3];
ctx.beginPath();
ctx.moveTo(c0.x, c0.y);
ctx.lineTo(c1.x, c1.y);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(c3.x, c3.y);
ctx.lineTo(c2.x, c2.y);
ctx.closePath();
ctx.stroke();
}
// draw control handles
for (i = 0; i < pixelVectors.length; i++) {
ctx.fillStyle = activePoint === i ? "cyan" : "green";
var p = pixelVectors[i];
ctx.beginPath();
ctx.arc(p.x, p.y, 5 , 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
}
document.querySelector("#curve").textContent = "cubicBezier([" + vectors.map(function(p) {
return "{ x: " + simplify(p.x, 2) + ", y: " + simplify(p.y, 2) + "}";
}).join(", ") + "], 0.0001)";
var res = 40;
var points = [];
for (i = 0; i < res; i++) {
var pct = i / (res - 1);
var x = boxLeft + (pct * boxWidth);
var line = [{ x: x, y: boxTop + boxHeight }, { x: x, y: boxTop }];
ctx.strokeStyle = "rgba(255, 255, 255, 0.05)";
ctx.beginPath();
ctx.moveTo(line[0].x, line[0].y);
ctx.lineTo(line[1].x, line[1].y);
ctx.closePath();
ctx.stroke();
var y = boxTop + ((-equation(pct) + 1) * boxHeight);
points.push({ x: x, y: y });
}
// draw computed points
ctx.fillStyle = "blue";
points.forEach(function(p) {
ctx.beginPath();
ctx.arc(p.x, p.y, 2, 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
});
};
var activePoint;
var contained = function(p, box) {
return p.x >= box.left && p.x <= box.right && p.y >= box.top && p.y <= box.bottom;
};
var findCurvePoint = function(p) {
var found;
for (var i = 0; i < pixelVectors.length; i++) {
var cp = pixelVectors[i];
var box = { left: cp.x - 10, right: cp.x + 10, top: cp.y - 10, bottom: cp.y + 10 };
if (contained(p, box)) {
found = i;
break;
}
}
activePoint = found;
};
ready(function() {
var canvas = document.querySelector("#curves");
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
render(ctx);
document.addEventListener("mousedown", function(event) {
findCurvePoint({ x: event.pageX, y: event.pageY });
if (activePoint != null) render(ctx);
}, false);
document.addEventListener("mouseup", function() {
if (activePoint != null) {
activePoint = null;
render(ctx);
}
}, false);
document.addEventListener("mousemove", function(event) {
if (activePoint == null) return;
pixelVectors[activePoint] = { x: event.pageX, y: event.pageY };
event.preventDefault();
render(ctx);
}, false);
document.querySelector("#add").addEventListener("click", function() {
var vectors = convertVectorsToPercentages(pixelVectors);
var segments = (vectors.length - 1) / 3 + 1;
var ratio = 1 - (1 / segments);
for (var i = 0; i < vectors.length; i++) {
var c = vectors[i];
c.x *= ratio;
}
vectors.push({ x: ratio, y: 1 }, { x: 1, y: 1 }, {x: 1, y: 0 });
pixelVectors = convertVectorsToPixels(vectors);
render(ctx);
}, false);
var sprite = document.querySelector("#sprite");
document.querySelector("#fade-in").addEventListener("click", function() {
var start = 0, end = 1;
var transition = new Transition(5000, equation, function(delta) {
sprite.style.opacity = lerp(start, end, delta);
});
transition.start();
}, false);
document.querySelector("#fade-out").addEventListener("click", function() {
var start = 1, end = 0;
var transition = new Transition(5000, equation, function(delta) {
sprite.style.opacity = lerp(start, end, delta);
});
transition.start();
}, false);
document.querySelector("#rise").addEventListener("click", function() {
var start = 800, end = 100;
sprite.style.opacity = 1;
var transition = new Transition(5000, equation, function(delta) {
sprite.style.top = lerp(start, end, delta) + "px";
});
transition.start();
}, false);
document.querySelector("#fall").addEventListener("click", function() {
var start = 100, end = 800;
sprite.style.opacity = 1;
var transition = new Transition(5000, equation, function(delta) {
sprite.style.top = lerp(start, end, delta) + "px";
});
transition.start();
}, false);
});
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 canMutationObserver=typeof window!=="undefined"&&window.MutationObserver;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}var queue=[];if(canMutationObserver){var hiddenDiv=document.createElement("div");var observer=new MutationObserver(function(){var queueList=queue.slice();queue.length=0;queueList.forEach(function(fn){fn()})});observer.observe(hiddenDiv,{attributes:true});return function nextTick(fn){if(!queue.length){hiddenDiv.setAttribute("yes","no")}queue.push(fn)}}if(canPost){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")}},{}],2:[function(require,module,exports){"use strict";var prime=require("prime"),defer=require("prime/defer");var Transition=prime({constructor:function Transition(duration,equation,callback){if(!duration)throw new Error("no duration given");if(!equation)throw new Error("no equation given");if(!callback)throw new Error("no callback given");this.duration=duration;this.equation=equation;this.callback=callback},get paused(){return this.cancel==null&&this.elapsed!=null},get active(){return this.cancel!=null},get idle(){return this.cancel==null&&this.elapsed==null},start:function(){if(this.idle){this.elapsed=0;this.cancel=defer.frame(this.step,this)}return this},step:function(time){this.elapsed+=time-(this.time||time);var factor=this.elapsed/this.duration;if(factor>1)factor=1;if(factor!==1){this.time=time;this.cancel=defer.frame(this.step,this)}else{this.cancel=this.time=this.elapsed=null}var delta=this.equation(factor);this.callback(delta)},stop:function(){if(this.active){this.cancel();this.elapsed=this.cancel=this.time=null}return this},pause:function(){if(this.active){this.cancel();this.cancel=this.time=null}return this},resume:function(){if(this.paused){this.cancel=defer.frame(this.step,this)}return this}});module.exports=Transition},{prime:13,"prime/defer":12}],3:[function(require,module,exports){function forEach(arr,callback,thisObj){if(arr==null){return}var i=-1,len=arr.length;while(++i<len){if(callback.call(thisObj,arr[i],i,arr)===false){break}}}module.exports=forEach},{}],4:[function(require,module,exports){function indexOf(arr,item,fromIndex){fromIndex=fromIndex||0;if(arr==null){return-1}var len=arr.length,i=fromIndex<0?len+fromIndex:fromIndex;while(i<len){if(arr[i]===item){return i}i++}return-1}module.exports=indexOf},{}],5:[function(require,module,exports){var mixIn=require("../object/mixIn");function createObject(parent,props){function F(){}F.prototype=parent;return mixIn(new F,props)}module.exports=createObject},{"../object/mixIn":10}],6:[function(require,module,exports){var _rKind=/^\[object (.*)\]$/,_toString=Object.prototype.toString,UNDEF;function kindOf(val){if(val===null){return"Null"}else if(val===UNDEF){return"Undefined"}else{return _rKind.exec(_toString.call(val))[1]}}module.exports=kindOf},{}],7:[function(require,module,exports){var hasOwn=require("./hasOwn");var _hasDontEnumBug,_dontEnums;function checkDontEnum(){_dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];_hasDontEnumBug=true;for(var key in{toString:null}){_hasDontEnumBug=false}}function forIn(obj,fn,thisObj){var key,i=0;if(_hasDontEnumBug==null)checkDontEnum();for(key in obj){if(exec(fn,obj,key,thisObj)===false){break}}if(_hasDontEnumBug){var ctor=obj.constructor,isProto=!!ctor&&obj===ctor.prototype;while(key=_dontEnums[i++]){if((key!=="constructor"||!isProto&&hasOwn(obj,key))&&obj[key]!==Object.prototype[key]){if(exec(fn,obj,key,thisObj)===false){break}}}}}function exec(fn,obj,key,thisObj){return fn.call(thisObj,obj[key],key,obj)}module.exports=forIn},{"./hasOwn":9}],8:[function(require,module,exports){var hasOwn=require("./hasOwn");var forIn=require("./forIn");function forOwn(obj,fn,thisObj){forIn(obj,function(val,key){if(hasOwn(obj,key)){return fn.call(thisObj,obj[key],key,obj)}})}module.exports=forOwn},{"./forIn":7,"./hasOwn":9}],9:[function(require,module,exports){function hasOwn(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}module.exports=hasOwn},{}],10:[function(require,module,exports){var forOwn=require("./forOwn");function mixIn(target,objects){var i=0,n=arguments.length,obj;while(++i<n){obj=arguments[i];if(obj!=null){forOwn(obj,copyProp,target)}}return target}function copyProp(val,key){this[key]=val}module.exports=mixIn},{"./forOwn":8}],11:[function(require,module,exports){function now(){return now.get()}now.get=typeof Date.now==="function"?Date.now:function(){return+new Date};module.exports=now},{}],12:[function(require,module,exports){(function(process,global){"use strict";var kindOf=require("mout/lang/kindOf"),now=require("mout/time/now"),forEach=require("mout/array/forEach"),indexOf=require("mout/array/indexOf");var callbacks={timeout:{},frame:[],immediate:[]};var push=function(collection,callback,context,defer){var iterator=function(){iterate(collection)};if(!collection.length)defer(iterator);var entry={callback:callback,context:context};collection.push(entry);return function(){var io=indexOf(collection,entry);if(io>-1)collection.splice(io,1)}};var iterate=function(collection){var time=now();forEach(collection.splice(0),function(entry){entry.callback.call(entry.context,time)})};var defer=function(callback,argument,context){return kindOf(argument)==="Number"?defer.timeout(callback,argument,context):defer.immediate(callback,argument)};if(global.process&&process.nextTick){defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,process.nextTick)}}else if(global.setImmediate){defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,setImmediate)}}else if(global.postMessage&&global.addEventListener){addEventListener("message",function(event){if(event.source===global&&event.data==="@deferred"){event.stopPropagation();iterate(callbacks.immediate)}},true);defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,function(){postMessage("@deferred","*")})}}else{defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,function(iterator){setTimeout(iterator,0)})}}var requestAnimationFrame=global.requestAnimationFrame||global.webkitRequestAnimationFrame||global.mozRequestAnimationFrame||global.oRequestAnimationFrame||global.msRequestAnimationFrame||function(callback){setTimeout(callback,1e3/60)};defer.frame=function(callback,context){return push(callbacks.frame,callback,context,requestAnimationFrame)};var clear;defer.timeout=function(callback,ms,context){var ct=callbacks.timeout;if(!clear)clear=defer.immediate(function(){clear=null;callbacks.timeout={}});return push(ct[ms]||(ct[ms]=[]),callback,context,function(iterator){setTimeout(iterator,ms)})};module.exports=defer}).call(this,require("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{_process:1,"mout/array/forEach":3,"mout/array/indexOf":4,"mout/lang/kindOf":6,"mout/time/now":11}],13:[function(require,module,exports){"use strict";var hasOwn=require("mout/object/hasOwn"),mixIn=require("mout/object/mixIn"),create=require("mout/lang/createObject"),kindOf=require("mout/lang/kindOf");var hasDescriptors=true;try{Object.defineProperty({},"~",{});Object.getOwnPropertyDescriptor({},"~")}catch(e){hasDescriptors=false}var hasEnumBug=!{valueOf:0}.propertyIsEnumerable("valueOf"),buggy=["toString","valueOf"];var verbs=/^constructor|inherits|mixin$/;var implement=function(proto){var prototype=this.prototype;for(var key in proto){if(key.match(verbs))continue;if(hasDescriptors){var descriptor=Object.getOwnPropertyDescriptor(proto,key);if(descriptor){Object.defineProperty(prototype,key,descriptor);continue}}prototype[key]=proto[key]}if(hasEnumBug)for(var i=0;key=buggy[i];i++){var value=proto[key];if(value!==Object.prototype[key])prototype[key]=value}return this};var prime=function(proto){if(kindOf(proto)==="Function")proto={constructor:proto};var superprime=proto.inherits;var constructor=hasOwn(proto,"constructor")?proto.constructor:superprime?function(){return superprime.apply(this,arguments)}:function(){};if(superprime){mixIn(constructor,superprime);var superproto=superprime.prototype;var cproto=constructor.prototype=create(superproto);constructor.parent=superproto;cproto.constructor=constructor}if(!constructor.implement)constructor.implement=implement;var mixins=proto.mixin;if(mixins){if(kindOf(mixins)!=="Array")mixins=[mixins];for(var i=0;i<mixins.length;i++)constructor.implement(create(mixins[i].prototype))}return constructor.implement(proto)};module.exports=prime},{"mout/lang/createObject":5,"mout/lang/kindOf":6,"mout/object/hasOwn":9,"mout/object/mixIn":10}],transition:[function(require,module,exports){"use strict";module.exports=require("./lib/transition")},{"./lib/transition":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}({1:[function(require,module,exports){var process=module.exports={};process.nextTick=function(){var canSetImmediate=typeof window!=="undefined"&&window.setImmediate;var canMutationObserver=typeof window!=="undefined"&&window.MutationObserver;var canPost=typeof window!=="undefined"&&window.postMessage&&window.addEventListener;if(canSetImmediate){return function(f){return window.setImmediate(f)}}var queue=[];if(canMutationObserver){var hiddenDiv=document.createElement("div");var observer=new MutationObserver(function(){var queueList=queue.slice();queue.length=0;queueList.forEach(function(fn){fn()})});observer.observe(hiddenDiv,{attributes:true});return function nextTick(fn){if(!queue.length){hiddenDiv.setAttribute("yes","no")}queue.push(fn)}}if(canPost){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")}},{}],2:[function(require,module,exports){"use strict";var prime=require("prime");var forEach=require("mout/array/forEach"),map=require("mout/array/map"),filter=require("mout/array/filter"),every=require("mout/array/every"),some=require("mout/array/some");var index=0,__dc=document.__counter,counter=document.__counter=(__dc?parseInt(__dc,36)+1:0).toString(36),key="uid:"+counter;var uniqueID=function(n){if(n===window)return"window";if(n===document)return"document";if(n===document.documentElement)return"html";return n[key]||(n[key]=(index++).toString(36))};var instances={};var $=prime({constructor:function $(n,context){if(n==null)return this&&this.constructor===$?new Elements:null;var self,uid;if(n.constructor!==Elements){self=new Elements;if(typeof n==="string"){if(!self.search)return null;self[self.length++]=context||document;return self.search(n)}if(n.nodeType||n===window){self[self.length++]=n}else if(n.length){var uniques={};for(var i=0,l=n.length;i<l;i++){var nodes=$(n[i],context);if(nodes&&nodes.length)for(var j=0,k=nodes.length;j<k;j++){var node=nodes[j];uid=uniqueID(node);if(!uniques[uid]){self[self.length++]=node;uniques[uid]=true}}}}}else{self=n}if(!self.length)return null;if(self.length===1){uid=uniqueID(self[0]);return instances[uid]||(instances[uid]=self)}return self}});var Elements=prime({inherits:$,constructor:function Elements(){this.length=0},unlink:function(){return this.map(function(node){delete instances[uniqueID(node)];return node})},forEach:function(method,context){forEach(this,method,context);return this},map:function(method,context){return map(this,method,context)},filter:function(method,context){return filter(this,method,context)},every:function(method,context){return every(this,method,context)},some:function(method,context){return some(this,method,context)}});module.exports=$},{"mout/array/every":4,"mout/array/filter":5,"mout/array/forEach":6,"mout/array/map":8,"mout/array/some":9,prime:25}],3:[function(require,module,exports){"use strict";var Emitter=require("prime/emitter");var $=require("./base");var html=document.documentElement;var addEventListener=html.addEventListener?function(node,event,handle,useCapture){node.addEventListener(event,handle,useCapture||false);return handle}:function(node,event,handle){node.attachEvent("on"+event,handle);return handle};var removeEventListener=html.removeEventListener?function(node,event,handle,useCapture){node.removeEventListener(event,handle,useCapture||false)}:function(node,event,handle){node.detachEvent("on"+event,handle)};$.implement({on:function(event,handle,useCapture){return this.forEach(function(node){var self=$(node);var internalEvent=event+(useCapture?":capture":"");Emitter.prototype.on.call(self,internalEvent,handle);var domListeners=self._domListeners||(self._domListeners={});if(!domListeners[internalEvent])domListeners[internalEvent]=addEventListener(node,event,function(e){Emitter.prototype.emit.call(self,internalEvent,e||window.event,Emitter.EMIT_SYNC)},useCapture)})},off:function(event,handle,useCapture){return this.forEach(function(node){var self=$(node);var internalEvent=event+(useCapture?":capture":"");var domListeners=self._domListeners,domEvent,listeners=self._listeners,events;if(domListeners&&(domEvent=domListeners[internalEvent])&&listeners&&(events=listeners[internalEvent])){Emitter.prototype.off.call(self,internalEvent,handle);if(!self._listeners||!self._listeners[event]){removeEventListener(node,event,domEvent);delete domListeners[event];for(var l in domListeners)return;delete self._domListeners}}})},emit:function(){var args=arguments;return this.forEach(function(node){Emitter.prototype.emit.apply($(node),args)})}});module.exports=$},{"./base":2,"prime/emitter":24}],4:[function(require,module,exports){var makeIterator=require("../function/makeIterator_");function every(arr,callback,thisObj){callback=makeIterator(callback,thisObj);var result=true;if(arr==null){return result}var i=-1,len=arr.length;while(++i<len){if(!callback(arr[i],i,arr)){result=false;break}}return result}module.exports=every},{"../function/makeIterator_":11}],5:[function(require,module,exports){var makeIterator=require("../function/makeIterator_");function filter(arr,callback,thisObj){callback=makeIterator(callback,thisObj);var results=[];if(arr==null){return results}var i=-1,len=arr.length,value;while(++i<len){value=arr[i];if(callback(value,i,arr)){results.push(value)}}return results}module.exports=filter},{"../function/makeIterator_":11}],6:[function(require,module,exports){function forEach(arr,callback,thisObj){if(arr==null){return}var i=-1,len=arr.length;while(++i<len){if(callback.call(thisObj,arr[i],i,arr)===false){break}}}module.exports=forEach},{}],7:[function(require,module,exports){function indexOf(arr,item,fromIndex){fromIndex=fromIndex||0;if(arr==null){return-1}var len=arr.length,i=fromIndex<0?len+fromIndex:fromIndex;while(i<len){if(arr[i]===item){return i}i++}return-1}module.exports=indexOf},{}],8:[function(require,module,exports){var makeIterator=require("../function/makeIterator_");function map(arr,callback,thisObj){callback=makeIterator(callback,thisObj);var results=[];if(arr==null){return results}var i=-1,len=arr.length;while(++i<len){results[i]=callback(arr[i],i,arr)}return results}module.exports=map},{"../function/makeIterator_":11}],9:[function(require,module,exports){var makeIterator=require("../function/makeIterator_");function some(arr,callback,thisObj){callback=makeIterator(callback,thisObj);var result=false;if(arr==null){return result}var i=-1,len=arr.length;while(++i<len){if(callback(arr[i],i,arr)){result=true;break}}return result}module.exports=some},{"../function/makeIterator_":11}],10:[function(require,module,exports){function identity(val){return val}module.exports=identity},{}],11:[function(require,module,exports){var identity=require("./identity");var prop=require("./prop");var deepMatches=require("../object/deepMatches");function makeIterator(src,thisObj){if(src==null){return identity}switch(typeof src){case"function":return typeof thisObj!=="undefined"?function(val,i,arr){return src.call(thisObj,val,i,arr)}:src;case"object":return function(val){return deepMatches(val,src)};case"string":case"number":return prop(src)}}module.exports=makeIterator},{"../object/deepMatches":17,"./identity":10,"./prop":12}],12:[function(require,module,exports){function prop(name){return function(obj){return obj[name]}}module.exports=prop},{}],13:[function(require,module,exports){var mixIn=require("../object/mixIn");function createObject(parent,props){function F(){}F.prototype=parent;return mixIn(new F,props)}module.exports=createObject},{"../object/mixIn":21}],14:[function(require,module,exports){var isKind=require("./isKind");var isArray=Array.isArray||function(val){return isKind(val,"Array")};module.exports=isArray},{"./isKind":15}],15:[function(require,module,exports){var kindOf=require("./kindOf");function isKind(val,kind){return kindOf(val)===kind}module.exports=isKind},{"./kindOf":16}],16:[function(require,module,exports){var _rKind=/^\[object (.*)\]$/,_toString=Object.prototype.toString,UNDEF;function kindOf(val){if(val===null){return"Null"}else if(val===UNDEF){return"Undefined"}else{return _rKind.exec(_toString.call(val))[1]}}module.exports=kindOf},{}],17:[function(require,module,exports){var forOwn=require("./forOwn");var isArray=require("../lang/isArray");function containsMatch(array,pattern){var i=-1,length=array.length;while(++i<length){if(deepMatches(array[i],pattern)){return true}}return false}function matchArray(target,pattern){var i=-1,patternLength=pattern.length;while(++i<patternLength){if(!containsMatch(target,pattern[i])){return false}}return true}function matchObject(target,pattern){var result=true;forOwn(pattern,function(val,key){if(!deepMatches(target[key],val)){return result=false}});return result}function deepMatches(target,pattern){if(target&&typeof target==="object"){if(isArray(target)&&isArray(pattern)){return matchArray(target,pattern)}else{return matchObject(target,pattern)}}else{return target===pattern}}module.exports=deepMatches},{"../lang/isArray":14,"./forOwn":19}],18:[function(require,module,exports){var hasOwn=require("./hasOwn");var _hasDontEnumBug,_dontEnums;function checkDontEnum(){_dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];_hasDontEnumBug=true;for(var key in{toString:null}){_hasDontEnumBug=false}}function forIn(obj,fn,thisObj){var key,i=0;if(_hasDontEnumBug==null)checkDontEnum();for(key in obj){if(exec(fn,obj,key,thisObj)===false){break}}if(_hasDontEnumBug){var ctor=obj.constructor,isProto=!!ctor&&obj===ctor.prototype;while(key=_dontEnums[i++]){if((key!=="constructor"||!isProto&&hasOwn(obj,key))&&obj[key]!==Object.prototype[key]){if(exec(fn,obj,key,thisObj)===false){break}}}}}function exec(fn,obj,key,thisObj){return fn.call(thisObj,obj[key],key,obj)}module.exports=forIn},{"./hasOwn":20}],19:[function(require,module,exports){var hasOwn=require("./hasOwn");var forIn=require("./forIn");function forOwn(obj,fn,thisObj){forIn(obj,function(val,key){if(hasOwn(obj,key)){return fn.call(thisObj,obj[key],key,obj)}})}module.exports=forOwn},{"./forIn":18,"./hasOwn":20}],20:[function(require,module,exports){function hasOwn(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)}module.exports=hasOwn},{}],21:[function(require,module,exports){var forOwn=require("./forOwn");function mixIn(target,objects){var i=0,n=arguments.length,obj;while(++i<n){obj=arguments[i];if(obj!=null){forOwn(obj,copyProp,target)}}return target}function copyProp(val,key){this[key]=val}module.exports=mixIn},{"./forOwn":19}],22:[function(require,module,exports){function now(){return now.get()}now.get=typeof Date.now==="function"?Date.now:function(){return+new Date};module.exports=now},{}],23:[function(require,module,exports){(function(process,global){"use strict";var kindOf=require("mout/lang/kindOf"),now=require("mout/time/now"),forEach=require("mout/array/forEach"),indexOf=require("mout/array/indexOf");var callbacks={timeout:{},frame:[],immediate:[]};var push=function(collection,callback,context,defer){var iterator=function(){iterate(collection)};if(!collection.length)defer(iterator);var entry={callback:callback,context:context};collection.push(entry);return function(){var io=indexOf(collection,entry);if(io>-1)collection.splice(io,1)}};var iterate=function(collection){var time=now();forEach(collection.splice(0),function(entry){entry.callback.call(entry.context,time)})};var defer=function(callback,argument,context){return kindOf(argument)==="Number"?defer.timeout(callback,argument,context):defer.immediate(callback,argument)};if(global.process&&process.nextTick){defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,process.nextTick)}}else if(global.setImmediate){defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,setImmediate)}}else if(global.postMessage&&global.addEventListener){addEventListener("message",function(event){if(event.source===global&&event.data==="@deferred"){event.stopPropagation();iterate(callbacks.immediate)}},true);defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,function(){postMessage("@deferred","*")})}}else{defer.immediate=function(callback,context){return push(callbacks.immediate,callback,context,function(iterator){setTimeout(iterator,0)})}}var requestAnimationFrame=global.requestAnimationFrame||global.webkitRequestAnimationFrame||global.mozRequestAnimationFrame||global.oRequestAnimationFrame||global.msRequestAnimationFrame||function(callback){setTimeout(callback,1e3/60)};defer.frame=function(callback,context){return push(callbacks.frame,callback,context,requestAnimationFrame)};var clear;defer.timeout=function(callback,ms,context){var ct=callbacks.timeout;if(!clear)clear=defer.immediate(function(){clear=null;callbacks.timeout={}});return push(ct[ms]||(ct[ms]=[]),callback,context,function(iterator){setTimeout(iterator,ms)})};module.exports=defer}).call(this,require("_process"),typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{_process:1,"mout/array/forEach":6,"mout/array/indexOf":7,"mout/lang/kindOf":16,"mout/time/now":22}],24:[function(require,module,exports){"use strict";var indexOf=require("mout/array/indexOf"),forEach=require("mout/array/forEach");var prime=require("./index"),defer=require("./defer");var slice=Array.prototype.slice;var Emitter=prime({on:function(event,fn){var listeners=this._listeners||(this._listeners={}),events=listeners[event]||(listeners[event]=[]);if(indexOf(events,fn)===-1)events.push(fn);return this},off:function(event,fn){var listeners=this._listeners,events,key,length=0;if(listeners&&(events=listeners[event])){var io=indexOf(events,fn);if(io>-1)events.splice(io,1);if(!events.length)delete listeners[event];for(var l in listeners)return this;delete this._listeners}return this},emit:function(event){var self=this,args=slice.call(arguments,1);var emit=function(){var listeners=self._listeners,events;if(listeners&&(events=listeners[event])){forEach(events.slice(0),function(event){return event.apply(self,args)})}};if(args[args.length-1]===Emitter.EMIT_SYNC){args.pop();emit()}else{defer(emit)}return this}});Emitter.EMIT_SYNC={};module.exports=Emitter},{"./defer":23,"./index":25,"mout/array/forEach":6,"mout/array/indexOf":7}],25:[function(require,module,exports){"use strict";var hasOwn=require("mout/object/hasOwn"),mixIn=require("mout/object/mixIn"),create=require("mout/lang/createObject"),kindOf=require("mout/lang/kindOf");var hasDescriptors=true;try{Object.defineProperty({},"~",{});Object.getOwnPropertyDescriptor({},"~")}catch(e){hasDescriptors=false}var hasEnumBug=!{valueOf:0}.propertyIsEnumerable("valueOf"),buggy=["toString","valueOf"];var verbs=/^constructor|inherits|mixin$/;var implement=function(proto){var prototype=this.prototype;for(var key in proto){if(key.match(verbs))continue;if(hasDescriptors){var descriptor=Object.getOwnPropertyDescriptor(proto,key);if(descriptor){Object.defineProperty(prototype,key,descriptor);continue}}prototype[key]=proto[key]}if(hasEnumBug)for(var i=0;key=buggy[i];i++){var value=proto[key];if(value!==Object.prototype[key])prototype[key]=value}return this};var prime=function(proto){if(kindOf(proto)==="Function")proto={constructor:proto};var superprime=proto.inherits;var constructor=hasOwn(proto,"constructor")?proto.constructor:superprime?function(){return superprime.apply(this,arguments)}:function(){};if(superprime){mixIn(constructor,superprime);var superproto=superprime.prototype;var cproto=constructor.prototype=create(superproto);constructor.parent=superproto;cproto.constructor=constructor}if(!constructor.implement)constructor.implement=implement;var mixins=proto.mixin;if(mixins){if(kindOf(mixins)!=="Array")mixins=[mixins];for(var i=0;i<mixins.length;i++)constructor.implement(create(mixins[i].prototype))}return constructor.implement(proto)};module.exports=prime},{"mout/lang/createObject":13,"mout/lang/kindOf":16,"mout/object/hasOwn":20,"mout/object/mixIn":21}],"elements/domready":[function(require,module,exports){"use strict";var $=require("./events");var readystatechange="onreadystatechange"in document,shouldPoll=false,loaded=false,readys=[],checks=[],ready=null,timer=null,test=document.createElement("div"),doc=$(document),win=$(window);var domready=function(){if(timer)timer=clearTimeout(timer);if(!loaded){if(readystatechange)doc.off("readystatechange",check);doc.off("DOMContentLoaded",domready);win.off("load",domready);loaded=true;for(var i=0;ready=readys[i++];)ready()}return loaded};var check=function(){for(var i=checks.length;i--;)if(checks[i]())return domready();return false};var poll=function(){clearTimeout(timer);if(!check())timer=setTimeout(poll,1e3/60)};if(document.readyState){var complete=function(){return!!/loaded|complete/.test(document.readyState)};checks.push(complete);if(!complete()){if(readystatechange)doc.on("readystatechange",check);else shouldPoll=true}else{domready()}}if(test.doScroll){var scrolls=function(){try{test.doScroll();return true}catch(e){}return false};if(!scrolls()){checks.push(scrolls);shouldPoll=true}}if(shouldPoll)poll();doc.on("DOMContentLoaded",domready);win.on("load",domready);module.exports=function(ready){loaded?ready():readys.push(ready);return null}},{"./events":3}]},{},[]);"use strict";var ready=require("elements/domready");var get=function(one,two,three,four,t){var v=1-t,b1=t*t*t,b2=3*t*t*v,b3=3*t*v*v,b4=v*v*v;return four*b1+three*b2+two*b3+one*b4};var clamp=function(n,min,max){if(n<min)return min;if(n>max)return max;return n};var bezier=function(vectors,epsilon){if(vectors.length%3!==1)throw new Error("invalid input");for(var i=0;i<vectors.length-1;i+=3){var c0=vectors[i],c1=vectors[i+1],c2=vectors[i+2],c3=vectors[i+3];if(i===0)c0.x=0;else c0.x=clamp(c0.x,0,1);if(i===vectors.length-4)c3.x=1;else c3.x=clamp(c3.x,c0.x,1);c1.x=clamp(c1.x,c0.x,c3.x);c2.x=clamp(c2.x,c0.x,c3.x)}return function(x){var c0,c1,c2,c3;for(var i=0;i<vectors.length-1;i+=3){c0=vectors[i];c1=vectors[i+1];c2=vectors[i+2];c3=vectors[i+3];if(x>=c0.x&&x<=c3.x)break}var lower=0,upper=1,t=x,xt;if(x<lower)return get(c0.y,c1.y,c2.y,c3.y,lower);if(x>upper)return get(c0.y,c1.y,c2.y,c3.y,upper);while(lower<upper){xt=get(c0.x,c1.x,c2.x,c3.x,t);if(Math.abs(xt-x)<epsilon)return get(c0.y,c1.y,c2.y,c3.y,t);if(x>xt)lower=t;else upper=t;t=(upper-lower)*.5+lower}return get(c0.y,c1.y,c2.y,c3.y,t)}};var Transition=require("transition");var width=900;var height=900;var boxLeft=100,boxTop=300;var boxWidth=600,boxHeight=300;var convertVectorsToPixels=function(vectors){return vectors.map(function(v){return{x:boxLeft+v.x*boxWidth,y:boxTop+(-v.y+1)*boxHeight}})};var convertVectorsToPercentages=function(vectors){return vectors.map(function(v){return{x:(v.x-boxLeft)/boxWidth,y:-((v.y-boxTop)/boxHeight)+1}})};var pixelVectors=convertVectorsToPixels([{x:0,y:0},{x:0,y:1},{x:.5,y:1},{x:.5,y:0},{x:.5,y:1},{x:1,y:1},{x:1,y:0}]);var lerp=function(from,to,delta){return(to-from)*delta+from};var equation;var simplify=function(n,places){return Number(n).toFixed(places).replace(/\.?0+$/,"")};var render=function(ctx){var vectors=convertVectorsToPercentages(pixelVectors);equation=bezier(vectors,1e-4);pixelVectors=convertVectorsToPixels(vectors);var i,c0,c1,c2,c3;ctx.clearRect(0,0,width,height);ctx.strokeStyle="rgba(255, 255, 255, 0.2)";ctx.lineWidth=1;ctx.beginPath();ctx.rect(boxLeft,boxTop,boxWidth,boxHeight);ctx.closePath();ctx.stroke();ctx.strokeStyle="red";c0=pixelVectors[0];ctx.beginPath();ctx.moveTo(c0.x,c0.y);for(i=1;i<pixelVectors.length-1;i+=3){c1=pixelVectors[i];c2=pixelVectors[i+1];c3=pixelVectors[i+2];ctx.bezierCurveTo(c1.x,c1.y,c2.x,c2.y,c3.x,c3.y)}ctx.stroke();ctx.strokeStyle="green";for(i=0;i<pixelVectors.length-1;i+=3){c0=pixelVectors[i];c1=pixelVectors[i+1];c2=pixelVectors[i+2];c3=pixelVectors[i+3];ctx.beginPath();ctx.moveTo(c0.x,c0.y);ctx.lineTo(c1.x,c1.y);ctx.closePath();ctx.stroke();ctx.beginPath();ctx.moveTo(c3.x,c3.y);ctx.lineTo(c2.x,c2.y);ctx.closePath();ctx.stroke()}for(i=0;i<pixelVectors.length;i++){ctx.fillStyle=activePoint===i?"cyan":"green";var p=pixelVectors[i];ctx.beginPath();ctx.arc(p.x,p.y,5,0,Math.PI*2);ctx.closePath();ctx.fill()}document.querySelector("#curve").textContent="cubicBezier(["+vectors.map(function(p){return"{ x: "+simplify(p.x,2)+", y: "+simplify(p.y,2)+"}"}).join(", ")+"], 0.0001)";var res=40;var points=[];for(i=0;i<res;i++){var pct=i/(res-1);var x=boxLeft+pct*boxWidth;var line=[{x:x,y:boxTop+boxHeight},{x:x,y:boxTop}];ctx.strokeStyle="rgba(255, 255, 255, 0.05)";ctx.beginPath();ctx.moveTo(line[0].x,line[0].y);ctx.lineTo(line[1].x,line[1].y);ctx.closePath();ctx.stroke();
var y=boxTop+(-equation(pct)+1)*boxHeight;points.push({x:x,y:y})}ctx.fillStyle="blue";points.forEach(function(p){ctx.beginPath();ctx.arc(p.x,p.y,2,0,Math.PI*2);ctx.closePath();ctx.fill()})};var activePoint;var contained=function(p,box){return p.x>=box.left&&p.x<=box.right&&p.y>=box.top&&p.y<=box.bottom};var findCurvePoint=function(p){var found;for(var i=0;i<pixelVectors.length;i++){var cp=pixelVectors[i];var box={left:cp.x-10,right:cp.x+10,top:cp.y-10,bottom:cp.y+10};if(contained(p,box)){found=i;break}}activePoint=found};ready(function(){var canvas=document.querySelector("#curves");canvas.width=width;canvas.height=height;var ctx=canvas.getContext("2d");render(ctx);document.addEventListener("mousedown",function(event){findCurvePoint({x:event.pageX,y:event.pageY});if(activePoint!=null)render(ctx)},false);document.addEventListener("mouseup",function(){if(activePoint!=null){activePoint=null;render(ctx)}},false);document.addEventListener("mousemove",function(event){if(activePoint==null)return;pixelVectors[activePoint]={x:event.pageX,y:event.pageY};event.preventDefault();render(ctx)},false);document.querySelector("#add").addEventListener("click",function(){var vectors=convertVectorsToPercentages(pixelVectors);var segments=(vectors.length-1)/3+1;var ratio=1-1/segments;for(var i=0;i<vectors.length;i++){var c=vectors[i];c.x*=ratio}vectors.push({x:ratio,y:1},{x:1,y:1},{x:1,y:0});pixelVectors=convertVectorsToPixels(vectors);render(ctx)},false);var sprite=document.querySelector("#sprite");document.querySelector("#fade-in").addEventListener("click",function(){var start=0,end=1;var transition=new Transition(5e3,equation,function(delta){sprite.style.opacity=lerp(start,end,delta)});transition.start()},false);document.querySelector("#fade-out").addEventListener("click",function(){var start=1,end=0;var transition=new Transition(5e3,equation,function(delta){sprite.style.opacity=lerp(start,end,delta)});transition.start()},false);document.querySelector("#rise").addEventListener("click",function(){var start=800,end=100;sprite.style.opacity=1;var transition=new Transition(5e3,equation,function(delta){sprite.style.top=lerp(start,end,delta)+"px"});transition.start()},false);document.querySelector("#fall").addEventListener("click",function(){var start=100,end=800;sprite.style.opacity=1;var transition=new Transition(5e3,equation,function(delta){sprite.style.top=lerp(start,end,delta)+"px"});transition.start()},false)});
{
"name": "requirebin-sketch",
"version": "1.0.0",
"dependencies": {
"transition": "0.1.1",
"elements": "0.5.0"
}
}
<canvas id="curves"></canvas>
<div id="sprite"></div>
<div id="curve"></div>
<div id="controls">
<button id="fade-in">Animate Opacity (0 - 1)</button>
<button id="fade-out">Animate Opacity (1 - 0)</button>
<button id="fall">Animate Top (100 - 800)</button>
<button id="rise">Animate Top (800 - 100)</button>
<button id="add">Add Curve</button>
</div>
<style>
body {
margin: 0;
padding: 0;
background-color: #222;
font-family: Arial;
}
#controls {
position: absolute;
top: 120px;
left: 20px;
width: 380px;
}
button {
display: inline-block;
margin: 0 5px 5px 0;
width: 180px;
height: 30px;
}
#curves {
top: 0;
left: 0;
position: absolute;
}
#curve {
color: white;
position: absolute;
top: 20px;
left: 20px;
font-size: 15px;
}
#sprite {
position: absolute;
top: 100px;
left: 500px;
background: red;
height: 40px;
width: 40px;
border-radius: 20px;
}
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment