DragonFireGamesLvl 11
FGUI 1.4 - Pages
// FGUI Fire Graphics User Interface
// By: DragonFireGames
// Version: 1.4
// Description: A port/mix of HTML, CSS,
// and p5.js to make a component based
// graphics interface. Styles are used
// and can be inherited and set.
var isMobile = _isSafari();
showMobileControls(true,true,true,true);
var testgraphics = createGraphics(400,400);
background(255);
testgraphics.fill(0);
testgraphics.noStroke();
testgraphics.rect(0,0,200,200);
image(testgraphics,0,0,200,200);
var doubleGraphics = get(150,150)[0] == 0;
delete testgraphics;
window._createGraphics = window.createGraphics;
window.createGraphics = function(w,h,gl) {
if (doubleGraphics) w *= 2, h*= 2;
var buf = window._createGraphics(w,h,gl);
buf.format = function(f,s,sw,ts,tax,tay) {
return format(f,s,sw,ts,tax,tay,buf);
};
buf.typewrite = function(str,t,x,y,mw,mh){
return typewrite(str,t,x,y,mw,mh,buf);
};
buf.beveledImage = function(img,sx,sy,sw,sh,x,y,w,h,bev) {
return beveledImage(img,sx,sy,sw,sh,x,y,w,h,bev,buf);
}
return buf;
};
var elementList = [];
var pageMap1 = {};
var pageMap2 = {};
var pageMap3 = {};
var display = "default";
var activeElement = false;
var defaultStyle = {
padx:5,
pady:5,
fill:128,
stroke:0,
strokeWeight:1,
textFill:0,
textStroke:false,
textStrokeWeight:1,
textSize:12,
placeholderTextFill:100,
placeholderStroke:false,
horizAlign:"left",
vertAlign:"top",
textmax:true,
font:"heveltica",
bevel:0,
imageBevel:0,
imageFit:"none",
imageHorizAlign:"center",
imageVertAlign:"center",
cursor:0,
get:function(e) {
return defaultStyle[e];
}
};
// Create a style
function createStyle(parent) {
var obj = {};
obj.parent = parent || defaultStyle;
obj.get = function(e) {
if (obj[e] === undefined) return obj.parent.get(e);
return obj[e];
};
return obj;
}
// Create an element
function createElement(x,y,w,h) {
var obj = {};
obj.x = x || 0;
obj.y = y || 0;
obj.width = w === undefined ? 50 : w;
obj.height = h === undefined ? 50 : h;
obj.style = createStyle();
obj.visible = true;
obj._cache = {};
obj.page = "default";
obj.testhover = function() {
return mouseRect(obj.x,obj.y,obj.width,obj.height);
};
obj.getmax = function() {
return {x:obj.x+obj.w,y:obj.y+obj.h};
};
obj.body = function(s,b) {
b.format(s.get("fill"),s.get("stroke"),s.get("strokeWeight"));
b.rect(obj.x,obj.y,obj.width,obj.height,s.get("bevel"));
};
obj.show = function(b) {
if (obj.page != display) return;
if (!obj.visible) return;
if (obj.drag) obj.drag(s,b);
var s = obj.style;
b = b || window;
if (obj.hover) {
if (mouseDown("left") && obj.onclick) s = obj.clickStyle;
else s = obj.hoverStyle;
}
if (activeElement == obj) {
if (obj.cursor) s = obj.activeStyle;
else if (obj.drag) s = obj.clickStyle;
}
obj.body(s,b);
if (obj.image) obj.image(s,b);
if (obj.text) obj.text(s,b);
if (obj.cursor) obj.cursor(s,b);
if (obj.canvas) obj.canvas(s,b);
if (obj.onshow) obj.onshow(s,b);
};
obj.addComponent = function(e,a,b,c) {
Components[e](obj,a,b,c);
};
elementList.push(obj);
obj.zindex = 0;
elementList = elementList.sort(function(a,b){return a.zindex - b.zindex;});
return obj;
}
// Create a page
function createPage(name,bef,aft,onopen) {
pageMap1[name] = bef || function(){};
pageMap2[name] = aft || function(){};
pageMap3[name] = onopen || function(){};
}
function setPage(name) {
display = name;
pageMap3[name]();
}
var Components = {};
Components.text = function(obj,txt) {
obj.value = txt||"";
obj.placeholder = "";
obj.activeStyle = createStyle(obj.clickStyle||obj.style);
obj.text = function(s,b) {
var c = obj._cache;
var ax = s.get("horizAlign");
var ay = s.get("vertAlign");
b.format(s.get("textFill"),s.get("textStroke"),s.get("textStrokeWeight"),s.get("textSize"),ax,ay);
b.textFont(s.get("font"));
var str = obj.value;
if (!obj.value && obj.placeholder) {
b.format(s.get("placeholderTextFill"),s.get("placeholderTextStroke"),s.get("textStrokeWeight"),s.get("textSize"),ax,ay);
str = obj.placeholder;
}
var max, tx = s.get("padx"), ty = s.get("pady");
var tm = s.get("textmax");
if (obj.cursor) ax = "left", ay = "top";
if (tm) {
max = obj.width - tx;
if (ax == "center") max = obj.width - tx * 2;
} else {
if (ax == "right") tx = obj.width - tx;
else if (ax == "center") tx = obj.width/2;
}
if (ay == "bottom") ty = obj.height - ty;
else if (ay == "center") ty = obj.height/2;
if (tm == 'number') max = tm;
c.max = max; c.tx = tx; c.ty = ty;
b.text(str,obj.x+tx,obj.y+ty,max);
if (ax == "left" && c.value !== obj.value) {
c.lines = getLines(obj.value,max);
obj.textHeight = c.lines.length*(s.get("textSize")*1.25)+ty;
obj.textWidth = textWidth(c.lines[c.lines.length-1])+tx;
c.value = obj.value;
}
};
obj.getmax = function() {
var c = obj._cache;
var m1x = obj.x+obj.w, m1y = obj.y+obj.h;
return {x:max(m1x,obj.textWidth||0),y:max(m1y,obj.textHeight||0)}
};
};
Components.button = function(obj) {
obj.hoverStyle = createStyle(obj.style);
obj.clickStyle = createStyle(obj.hoverStyle);
obj.hover = false;
obj.onclick = function(){};
obj.onunclick = function(){};
obj.interactive = true;
};
Components.image = function(obj,url,callback,failure) {
if (typeof url == 'string') obj.img = loadImage(url,function(img) {
if (obj.width === 0) obj.width = img.width;
if (obj.height === 0) obj.height = img.height;
},failure);
else obj.img = url;
obj.image = function(s,b) {
var f = s.get("imageFit");
var ax = s.get("imageHorizAlign");
var ay = s.get("imageVertAlign");
var bev = s.get("imageBevel");
if (f == "inside") {
var bb = centerRect(obj.width,obj.height,obj.img.width,obj.img.height);
if (ax == "left") bb.x = 0;
if (ax == "right") bb.x = obj.width-bb.w;
if (ay == "top") bb.y = 0;
if (ay == "bottom") bb.y = obj.height-bb.h;
beveledImage(obj.img,obj.x+bb.x,obj.y+bb.y,bb.w,bb.h,bev);
}
else if (f == "outside") {
var bb = centerRect(obj.img.width,obj.img.height,obj.width,obj.height);
if (ax == "left") bb.x = 0;
if (ax == "right") bb.x = obj.img.width-bb.w;
if (ay == "top") bb.y = 0;
if (ay == "bottom") bb.y = obj.img.height-bb.h;
beveledImage(obj.img,bb.x,bb.y,bb.w,bb.h,obj.x,obj.y,obj.width,obj.height,bev);
}
else beveledImage(obj.img,obj.x,obj.y,obj.width,obj.height,bev);
};
};
Components.input = function(obj,txt) {
Components.text(obj,txt);
Components.button(obj);
obj.activeStyle = createStyle(obj.clickStyle);
obj.cursorPos = obj.value.length;
obj.cursor = function(s,b) {
if (isMobile) return;
var c = obj._cache;
if (frameCount % 30 < 15 && activeElement == obj) return;
b.noStroke();
b.fill(s.get("cursor"));
b.text("|",obj.x+c.cursorX,obj.y+c.cursorY+0.5);
};
obj.calculateCursorPos = function() {
var s = obj.style, c = obj._cache;
c.cursorY = (obj.beflines.length-1)*(s.get("textSize")*1.25)+c.ty;
c.cursorX = textWidth(obj.beflines[obj.beflines.length-1])+c.tx;
};
obj.onclick = function() {
if (isMobile) {
var str = JSON.stringify(obj.value);
str = str.substring(1,str.length-1);
str = prompt(obj.placeholder||"Enter text:",str);
if (str === null) return;
str = str.replace(/"/g,"\\\"");
obj.value = JSON.parse("\""+str+"\"");
obj.update();
obj.oninput();
obj.onchange();
obj.onunfocus();
return;
}
var s = obj.style, c = obj._cache;
activeElement = obj;
var lines = obj.lines;
var dx = mouseX - obj.x - c.tx;
var dy = mouseY - obj.y - c.ty;
var li = constrain(ceil(dy/(s.get("textSize")*1.25)),0,lines.length)-1;
var e = textWidth("_");
var last = lines[li]||"";
var cpos = min(round(dx/e),last.length);
while (textWidth(last.substring(0,cpos))>dx) cpos--;
while (textWidth(last.substring(0,cpos))<dx-e && cpos < last.length) cpos++;
for (var i = 0; i < li; i++) {
cpos += lines[i].length;
}
cpos += (obj.value.substring(0,cpos).match(/\n/g)||[]).length;
obj.cursorPos = cpos;
obj.update();
obj._cache.val = obj.value;
obj.onfocus();
};
obj.update = function() {
obj.text(obj.style,window);
obj.lines = getLines(obj.value,obj._cache.max);
var bef = [];
var c = obj.cursorPos;
for (var i = 0; i < obj.lines.length; i++) {
bef.push(obj.lines[i]);
c-=obj.lines[i].length;
if (c < 0) break;
}
bef[bef.length-1] = bef[bef.length-1].substring(0,bef[bef.length-1].length+c);
obj.beflines = bef;
obj.calculateCursorPos();
obj.oninput();
};
obj.oninput = function() {};
obj.onfocus = function() {};
obj.onunfocus = function() {};
obj.onchange = function() {};
setTimeout(function(){
obj.update();
},0);
};
Components.canvas = function(obj,gl) {
obj.buff = createGraphics(obj.width,obj.height,gl);
obj._cache.width = obj.width;
obj._cache.height = obj.height;
obj.children = [];
obj.canvas = function(s,b) {
obj.buff.clear();
if (obj._cache.width != obj.width || obj._cache.width != obj.width) {
obj.buff = createGraphics(obj.width,obj.height);
}
obj.draw(obj.buff,s);
b.image(obj.buff,obj.x,obj.y,obj.width,obj.height);
};
};
Components.div = function(obj) {
Components.canvas(obj);
obj.children = [];
obj.appendChild = function(elem) {
elem.parent = obj;
obj.children.push(elem);
obj.children = obj.children.sort(function(a,b){return a.zindex - b.zindex;});
};
obj.prependChild = function(elem) {
elem.parent = obj;
obj.children.shift(elem);
obj.children = obj.children.sort(function(a,b){return a.zindex - b.zindex;});
};
obj.removeChild = function(elem) {
var i = obj.children.indexOf(elem);
delete elem.parent;
obj.children.splice(i,1);
};
obj.removeChildAtIndex = function(i) {
delete obj.children[i].parent;
obj.children.splice(i,1);
};
obj.draw = function(b,s) {
b.translate(-obj.scrollX,-obj.scrollY);
for (var i = 0; i < obj.children.length; i++) {
obj.children[i].show(b);
}
b.translate(obj.scrollX,obj.scrollY);
};
obj.scrollX = 0;
obj.scrollY = 0;
obj.minScrollX = 0;
obj.minScrollY = 0;
obj.maxScrollX = 0;
obj.maxScrollY = 0;
obj.onscroll = function(){};
obj.scroll = function(x,y) {
if (x == 0 && y == 0) return;
var px = obj.scrollX, py = obj.scrollY;
obj.scrollX = constrain(px+x,obj.minScrollX,obj.maxScrollX);
obj.scrollY = constrain(py+y,obj.minScrollY,obj.maxScrollY);
px -= obj.scrollX;
py -= obj.scrollY;
if (px != 0 || py != 0) obj.onscroll(px,py);
};
obj.div = true;
};
Components.draggable = function(obj) {
Components.button(obj);
obj.drag = function(s,b) {
if (activeElement == obj) {
obj.x += mouseX-pmouseX;
obj.y += mouseY-pmouseY;
}
}
obj.ongrab = function() {};
obj.onrelease = function(){};
obj.onclick = function() {
activeElement = obj;
obj.ongrab();
};
obj.onunclick = function(){
activeElement = false;
obj.onrelease();
};
};
// Draw elements
function drawElements() {
cursor(ARROW);
pageMap1[display]();
clickerElement(function(obj) {
if (obj.onclick) {
if (obj.cursor) cursor(TEXT);
else cursor(HAND);
}
if (!obj.div) return;
var sx = 0, sy = 0;
if (mouseDown("left") && !activeElement.drag) {
sx += pmouseX-mouseX;
sy += pmouseY-mouseY;
}
if (keyDown("left")) sx -= 5;
if (keyDown("right")) sx += 5;
if (keyDown("up")) sy -= 5;
if (keyDown("down")) sy += 5;
obj.scroll(sx,sy);
});
for (var i = 0; i < elementList.length; i++) {
if (elementList[i].parent) continue;
elementList[i].show();
}
pageMap2[display]();
}
// Run When Mouse Pressed
function mousePressedElements() {
var celem = activeElement;
activeElement = false;
clickerElement(function(obj) {
if (!obj.onclick) return;
obj.onclick();
});
if (celem != activeElement && celem.cursor) {
if (celem._cache.val !== celem.value) celem.onchange(celem.value);
celem.onunfocus();
}
}
// Run When Mouse Released
function mouseReleasedElements() {
clickerElement(function(obj) {
if (!obj.onunclick) return;
obj.onunclick();
});
}
// Run Key Typed
function keyTypedElements() {
if (!activeElement) return;
if (key == "\r") return;
var oldkey = key;
onHold(keyCode,key,function(){
activeElement.value = activeElement.value.substring(0, activeElement.cursorPos) + oldkey + activeElement.value.substring(activeElement.cursorPos, activeElement.value.length);
activeElement.cursorPos++;
activeElement.update();
activeElement.oninput(key);
});
}
// Run Key Pressed
function keyPressedElements() {
if (!activeElement || !activeElement.cursor) return;
onHold(BACKSPACE,"backspace",function() {
activeElement.value = activeElement.value.substring(0, activeElement.cursorPos-1) + activeElement.value.substring(activeElement.cursorPos, activeElement.value.length);
activeElement.cursorPos--;
activeElement.cursorPos = max(0,activeElement.cursorPos);
activeElement.update();
activeElement.oninput("backspace");
});
onHold(LEFT_ARROW,"left",function() {
activeElement.cursorPos = max(activeElement.cursorPos-1,0);
activeElement.update();
activeElement.oninput("left");
});
onHold(RIGHT_ARROW,"right",function() {
activeElement.cursorPos = min(activeElement.cursorPos+1,activeElement.value.length);
activeElement.update();
activeElement.oninput("right");
});
if (keyCode == ENTER) {
activeElement.value = activeElement.value.substring(0, activeElement.cursorPos) + "\n" + activeElement.value.substring(activeElement.cursorPos, activeElement.value.length);
activeElement.cursorPos++;
activeElement.update();
activeElement.oninput("\n");
return;
}
var lines, cursorLine, cursorOffset;
var updateLines = function() {
activeElement.update();
lines = activeElement.lines;
cursorLine = activeElement.beflines.length-1;
cursorOffset = activeElement.cursorPos;
for (var i = 0; i < cursorLine; i++) {
cursorOffset -= lines[i].length+1;
}
}
onHold(UP_ARROW,"up",function() {
updateLines();
if (cursorLine <= 0) return;
var newPos = 0;
for (var i = 0; i < cursorLine-1; i++) {
newPos += lines[i].length+1;
}
activeElement.cursorPos = newPos + min(cursorOffset,lines[cursorLine-1].length);
});
onHold(DOWN_ARROW,"down",function() {
updateLines();
if (cursorLine >= lines.length-1) return;
var newPos = 0;
for (var i = 0; i < cursorLine+1; i++) {
newPos += lines[i].length+1;
}
activeElement.cursorPos = newPos + min(cursorOffset,lines[cursorLine+1].length);
});
if (keyCode == 86 && keyDown(CONTROL)) {
var pasted = prompt("Paste here:");
if (!pasted) return;
activeElement.value = activeElement.value.substring(0,activeElement.cursorPos) + pasted + activeElement.value.substring(activeElement.cursorPos,activeElement.value.length);
activeElement.cursorPos += pasted.length;
activeElement.update();
activeElement.oninput(pasted);
}
}
// Run Mouse Wheel
function mouseWheelElements(e) {
/*
if (activeElement && activeElement.div && activeElement.hover) {
var ty = activeElement.y + activeElement.height/2;
var s = 0;
if (mouseY > ty) {
activeElement.scroll(0,-5);
}
}
*/
}
// Check if cursor in rect
function mouseRect(x,y,width,height) {
return (
mouseX > x &&
mouseX < x+width &&
mouseY > y &&
mouseY < y+height
);
}
// Center rectange in another
function centerRect(w1,h1,w2,h2) {
var fatness1 = w1 / h1;
var fatness2 = w2 / h2;
var scale;
if (fatness2 >= fatness1) scale = w1 / w2;
else scale = h1 / h2;
var w = w2 * scale;
var h = h2 * scale;
var xCenter = 0 + (w1 / 2);
var yCenter = 0 + (h1 / 2);
var x = xCenter - (w / 2);
var y = yCenter - (h / 2);
return { x:x, y:y, w:w, h:h };
}
// Get lines of text
function getLines(string,width) {
if (typeof string !== 'string') return [];
var lines = string.split("\n");
for (var i = 0; i < lines.length; i++) {
if (textWidth(lines[i]) <= width) continue;
if (!lines[i].match(/[\s-_]/)) continue;
var off = "";
while (textWidth(lines[i]) > width || (!lines[i].match(/[\s-_]$/) && lines[i].match(/[\s-_]/))) {
off = lines[i].charAt(lines[i].length-1)+off;
lines[i] = lines[i].substr(0,lines[i].length-1);
}
lines.splice(i+1,0,off);
}
return lines;
}
function clickerElement(callback) {
var done = false;
var hov = function(obj) {
if (!obj.visible || (!obj.interactive && !obj.div)) return;
var h = !done && obj.testhover();
if (obj.div) {
if (!h) return;
mouseX -= obj.x - obj.scrollX;
mouseY -= obj.y - obj.scrollY;
for (var j = obj.children.length-1; j >= 0; j--) {
hov(obj.children[j]);
}
mouseX += obj.x - obj.scrollX;
mouseY += obj.y - obj.scrollY;
} else {
obj.hover = h;
if (h) done = true;
}
if (h) callback(obj);
};
for (var i = elementList.length-1; i >= 0; i--) {
var obj = elementList[i];
if (obj.page != display) continue;
if (obj.parent) continue;
hov(obj);
}
}
function onHold(kc,k,funct) {
if (keyCode != kc && key != k) return;
funct();
setTimeout(function() {
if (!keyDown(k)) return;
funct();
var int = setInterval(function() {
if (!keyDown(k)) {
clearInterval(int);
return;
}
funct();
},100);
},600);
}
function beveledImage(img,sx,sy,sw,sh,x,y,w,h,bev,b) {
b = b || window;
if (!y) {
bev = x;
x = sx;
y = sy;
w = sw;
h = sh;
sx = 0;
sy = 0;
sw = img.width;
sh = img.height;
}
if (img.width != 0 && bev) {
var n = "bev"+[sx,sy,sw,sh,w,h,bev].join(",");
if (!img[n]) {
var buf = window._createGraphics(w,h);
buf.image(img,sx,sy,sw,sh,0,0,w,h);
var get1 = buf.get();
buf.clear();
buf.noStroke();
buf.rect(0,0,w,h,bev);
var get2 = buf.get();
get1.mask(get2);
img[n] = get1;
}
b.image(img[n],x,y,w,h);
} else b.image(img,sx,sy,sw,sh,x,y,w,h);
}
createPage("default");
FANIM 1.1 - Sequences
// FANIM Fire Animations
// By: DragonFireGames
// Version: 1.1
// Description: Animation functions
var Sequences = [];
// Creates an animation sequence
function createSequence() {
var seq = {};
// Animation Handlers
seq.animations = [];
// Creates Animations
seq.createAnimation = function(start,end,drawer,interp) {
var len = end-start;
interp = interp || function(t){return t};
seq.animations.push(function(time){
if (time > end || time < start) return;
drawer(interp((time-start)/len));
});
};
// Draws Animations
seq.draw = function() {
if (!seq.startTime) return;
for (var i = 0; i < seq.animations.length; i++) {
seq.animations[i](Date.now()-seq.startTime);
}
};
seq.start = function() {
seq.startTime = Date.now();
};
seq.end = function() {
delete seq.startTime;
};
Sequences.push(seq);
return seq;
}
// Draw animation sequences
function drawSequences() {
for (var i = 0; i < Sequences.length; i++) {
Sequences[i].draw();
}
}
//easings from: https://easings.net
var Ease = {
in: {
line: function(t) {
return t;
},
sine: function(t) {
return 1-Math.cos((t*Math.PI)/2);
},
quad: function(t) {
return t*t;
},
cubic: function(t) {
return t*t*t;
},
quart: function(t) {
return t*t*t*t;
},
quint: function(t) {
return t*t*t*t*t;
},
expo: function(t) {
if (t === 0) return 0;
return Math.pow(2,10*t-10);
},
circ: function(t) {
return 1-Math.sqrt(1-t*t);
},
back: function(t) {
var c1 = 1.70158;
var c3 = c1 + 1;
return c3*t*t*t-c1*t*t;
},
elastic: function(t) {
if (t === 0 || t === 1) return t;
var c4 = (2 * Math.PI) / 3;
return -Math.pow(2,10*t-10)*Math.sin((t*10-10.75)*c4);
},
bounce: function(t) {
return 1-Ease.out.bounce(1-t);
},
},
out: {
line: function(t) {
return 1-t;
},
sine: function(t) {
return Math.sin((t*Math.PI)/2);
},
quad: function(t) {
t = 1-t;
return 1-t*t;
},
cubic: function(t) {
t = 1-t;
return 1-t*t*t;
},
quart: function(t) {
t = 1-t;
return 1-t*t*t*t;
},
quint: function(t) {
t = 1-t;
return 1-t*t*t*t*t;
},
expo: function(t) {
if (t === 1) return 1;
return 1-Math.pow(2,-10*t);
},
circ: function(t) {
t = 1-t;
return Math.sqrt(1-t*t);
},
back: function(t) {
var c1 = 1.70158;
var c3 = c1 + 1;
t = t-1;
return 1+c3*t*t*t-c1*t*t;
},
elastic: function(t) {
if (t === 0 || t === 1) return t;
var c4 = (2 * Math.PI) / 3;
return -Math.pow(2,10*t-10)*Math.sin((t*10-10.75)*c4);
},
bounce: function(t) {
var n1 = 7.5625;
var d1 = 2.75;
if (t < 1/d1) {
return n1*t*t;
} else if (t < 2/d1) {
return n1*(t-=1.5/d1)*t+0.75;
} else if (t < 2.5/d1) {
return n1*(t-=2.25/d1)*t+0.9375;
} else {
return n1*(t-=2.625/d1)*t+0.984375;
}
},
},
inout: {
line: function(t) {
return t;
},
sine: function(t) {
return -(Math.cos(Math.PI*t)-1)/2;
},
quad: function(t) {
if (t < 0.5) return 2*t*t;
var x = -2*t+2;
return 1-x*x/2;
},
cubic: function(t) {
if (t < 0.5) return 4*t*t*t;
var x = -2*t+2;
return 1-x*x*x/2;
},
quart: function(t) {
if (t < 0.5) return 8*t*t*t*t;
var x = -2*t+2;
return 1-x*x*x*x/2;
},
quint: function(t) {
if (t < 0.5) return 16*t*t*t*t*t;
var x = -2*t+2;
return 1-x*x*x*x*x/2;
},
expo: function(t) {
if (t === 0 || t === 1) return t;
if (t < 0.5) return Math.pow(2,20*t-10)/2;
else return (2-Math.pow(2,-20*t+10))/2;
},
circ: function(t) {
if (t < 0.5) return (1-Math.sqrt(1-4*t*t))/2
var x = -2*x+2;
return (Math.sqrt(1-x*x)+1)/2;
},
back: function(t) {
var c1 = 1.70158;
var c2 = c1 * 1.525;
if (t < 0.5) return (4*t*t*((c2+1)*2*t-c2))/2;
var x = -2*x+2;
return (x*x*((c2+1)*(t*2-2)+c2)+2)/2;
},
elastic: function(t) {
if (t === 0 || t === 1) return t;
var c5 = (2 * Math.PI) / 4.5;
if (t < 0.5) return -(Math.pow(2,20*t-10)*Math.sin((20*t-11.125)*c5))/2;
return (Math.pow(2,-20*t+10)*Math.sin((20*t-11.125)*c5))/2+1;
},
bounce: function(t) {
if (t < 0.5) return 1-Ease.out.bounce(1-2*t)/2;
return 1+Ease.out.bounce(2*t-1)/2;
}
},
outin: {
line: function(t) {
return 1-t;
},
sine: function(t) {
return 1-Ease.inout.sine(1-t);
},
quad: function(t) {
return 1-Ease.inout.quad(1-t);
},
cubic: function(t) {
return 1-Ease.inout.cubic(1-t);
},
quart: function(t) {
return 1-Ease.inout.quart(1-t);
},
quint: function(t) {
return 1-Ease.inout.quint(1-t);
},
expo: function(t) {
return 1-Ease.inout.expo(1-t);
},
circ: function(t) {
return 1-Ease.inout.circ(1-t);
},
back: function(t) {
return 1-Ease.inout.back(1-t);
},
elastic: function(t) {
return 1-Ease.inout.elastic(1-t);
},
bounce: function(t) {
return 1-Ease.inout.bounce(1-t);
}
},
}
// https://cubic-bezier.com/
/*function cubicBezier(x1,y1,x2,y2) {
}*/
// Misc
function format(f,s,sw,ts,tax,tay,b) {
b = b || window;
if (!f && f !== 0) b.noFill();
else b.fill(f);
if (!s && s !== 0) b.noStroke(s);
else b.stroke(s);
b.strokeWeight(sw||1);
b.textSize(ts||12);
b.textAlign(tax||CENTER,tay||CENTER);
}
function typewrite(str,t,x,y,mw,mh,b){
b = b || window;
b.text(str.substring(0,Math.round(str.length*t)),x,y,mw,mh);
}
function alpha(c,a){
if (typeof a != 'number') return c;
a = constrain(a,0,1);
var col = color(c);
col._array[3] = a;
return col;
}