@kll Android Processing does have a lot of bugs and errors, so I’m not even surprised all that much.
@unique_username I don’t want a simple texture. I want to make an animation creating the outline and then filling the interior, like this. Also, this works on Android.
PGraphics[] gl;
int fps = 15;
float start = -0;
int frameImage = 0;
boolean loading = true;
boolean realTimeGen = false;
float scale = 0.5;
int w = 1600;
int h = 1200;
float[] l = new float[]{1, 0.5, 0.5, 1, 0.5};
AriaEasingArgument[] aea = new AriaEasingArgument[]{
new AriaEasingArgument(AriaEasing.Type.SINE, 2, AriaEasing.Type.SINE, 2),
new AriaEasingArgument(AriaEasing.Type.EXPONENTIAL, 2, AriaEasing.Type.EXPONENTIAL, 2),
new AriaEasingArgument(AriaEasing.Type.POLYNOMIAL, 4, AriaEasing.Type.POLYNOMIAL, 4),
new AriaEasingArgument(AriaEasing.Type.SINE, 2, AriaEasing.Type.SINE, 2),
new AriaEasingArgument(AriaEasing.Type.POLYNOMIAL, 2, AriaEasing.Type.POLYNOMIAL, 2),
};
int[] sr = new int[]{-1, 0, 0, 1, 3};
void setup(){
//size(640, 480);
//surface.setResizable(true);
fullScreen();
frameRate(fps);
//orientation(LANDSCAPE);
w = width;
h = height;
float sum = 0;
for(float f:l) sum += f;
gl = new PGraphics[int(sum * fps - start * fps + 1)];
}
void draw(){
background(0);
textSize(50);
textAlign(LEFT, TOP);
imageMode(CENTER);
if(realTimeGen){
line(0, 100, frameImage * width / gl.length, 100);
text("Displaying " + frameImage + " / " + (gl.length - 1), 0, 120);
PGraphics pg = getImage();
float scale = min(float(width) / pg.width, float(height) / pg.height);
image(pg, width / 2, height / 2, pg.width * scale, pg.height * scale);
frameImage ++;
if(frameImage == gl.length) frameImage = gl.length - 1;
}
else{
if(loading){
loadNextImage();
line(0, 100, frameImage * width / gl.length, 100);
text("Loading " + frameImage + " / " + (gl.length - 1), 0, 120);
}
else{
line(0, 100, frameImage * width / gl.length, 100);
text("Displaying " + frameImage + " / " + (gl.length - 1), 0, 120);
float scale = min(float(width) / gl[frameImage].width, float(height) / gl[frameImage].height);
image(gl[frameImage], width / 2, height / 2, gl[frameImage].width * scale, gl[frameImage].height * scale);
frameImage ++;
if(frameImage == gl.length) frameImage = gl.length - 1;
}
}
save(dataPath((frameCount >= 10000 ? "" : "0") + (frameCount >= 1000 ? "" : "0") + (frameCount >= 100 ? "" : "0") + (frameCount >= 10 ? "" : "0") + frameCount + ".png"));
}
PGraphics getImage(){
float t = float(frameImage) / float(fps) + start;
//float t = (float)(millis()) / 4000;
return new LogoFurryNightShade().getGraphics(int(w * scale), int(h * scale), 1, t, l[0], l[1], l[2], l[3], l[4], sr, aea[0], aea[1], aea[2], aea[3], aea[4]);
}
void loadNextImage(){
gl[frameImage] = getImage();
frameImage ++;
if(frameImage == gl.length){
loading = false;
frameImage = 0;
}
}
//------------------------------------------------------------------------
//AriaEasing
//Version 1.0
//Doesn't require any other libraries
static class AriaEasing{
enum Type{
LINEAR, HOLD, IMMEDIATE, POLYNOMIAL, EXPONENTIAL, SINE, EULER
}
static double get(double time, double startTime, double endTime, double startValue, double endValue, AriaEasing.Type type, double tension){
if(startTime >= endTime) return endValue;
if(startValue == endValue) return endValue;
return startValue + (endValue - startValue) * AriaEasing.getNormalized((time - startTime) / (endTime - startTime), type, tension);
}
static double get(double time, double startTime, double endTime, double startValue, double endValue, AriaEasing.Type type1, double tension1, AriaEasing.Type type2, double tension2){
if(startTime >= endTime) return endValue;
if(startValue == endValue) return endValue;
return startValue + (endValue - startValue) * AriaEasing.getNormalized((time - startTime) / (endTime - startTime), type1, tension1, type2, tension2);
}
static double getNormalized(double time, AriaEasing.Type type1, double tension1, AriaEasing.Type type2, double tension2){
if(time < 0) return 0;
if(time > 1) return 1;
if(time == 0.5) return 0.5;
if(time < 0.5) return 0.5 * AriaEasing.getNormalized(time * 2, type1, tension1);
return 1 - 0.5 * AriaEasing.getNormalized(2 - time * 2, type2, tension2);
}
static double getNormalized(double time, AriaEasing.Type type, double tension){
if(time <= 0) return 0;
if(time >= 1) return 1;
if(Math.abs(tension) < 1) return 1 - AriaEasing.getNormalized(1 - time, type, 1 / tension);
double rawOutput = 0;
if(type == null) type = AriaEasing.Type.LINEAR;
if(type == AriaEasing.Type.LINEAR) rawOutput = AriaEasing.getLinear(time);
if(type == AriaEasing.Type.HOLD) rawOutput = AriaEasing.getHold(time);
if(type == AriaEasing.Type.IMMEDIATE) rawOutput = AriaEasing.getImmediate(time);
if(type == AriaEasing.Type.POLYNOMIAL) rawOutput = AriaEasing.getPolynomial(time, tension);
if(type == AriaEasing.Type.EXPONENTIAL) rawOutput = AriaEasing.getExponential(time, tension);
if(type == AriaEasing.Type.SINE) rawOutput = AriaEasing.getSine(time, tension);
if(type == AriaEasing.Type.EULER) rawOutput = AriaEasing.getEuler(time, tension);
return rawOutput;
}
static private double getLinear(double time){
return time;
}
static private double getHold(double time){
return time < 1 ? 0 : 1;
}
static private double getImmediate(double time){
return time > 0 ? 1 : 0;
}
static private double getPolynomial(double time, double tension){
if(tension < 0) return AriaEasing.getImmediate(time);
return Math.pow(time, tension);
}
static private double getExponential(double time, double tension){
return Math.pow(tension, time * 10 - 10);
}
static private double getSine(double time, double tension){
if(tension < 0) return AriaEasing.getImmediate(time);
if(tension < 1) return 1 - AriaEasing.getSine(1 - time, 1 / tension);
return Math.pow(1 - Math.cos(time * PI / 2), tension / 2);
}
static private double getEuler(double time, double tension){
if(tension < 0) return AriaEasing.getImmediate(time);
return (Math.pow(exp(1), time * tension) - 1) / (Math.pow(exp(1), tension) - 1);
}
}
//---------------------------------------------------
class AriaEasingArgument{
AriaEasing.Type type1, type2;
double tension1, tension2;
AriaEasingArgument(AriaEasing.Type type1, double tension1, AriaEasing.Type type2, double tension2){
this.type1 = type1;
this.type2 = type2;
this.tension1 = tension1;
this.tension2 = tension2;
}
}
//------------------------------------------------------
class LogoFurryNightShade{
boolean procedureDebug = false;
boolean errorDebug = true;
boolean warningDebug = true;
boolean finalDebug = false;
String tabText = procedureDebug ? " " : "";
PVector[] pointsf = new PVector[]{
new PVector(0, 0),
new PVector(4 / 9.0, 0),
new PVector(4 / 9.0, 1 / 9.0),
new PVector(1 / 9.0, 1 / 9.0),
new PVector(1 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0, 6 / 9.0)
};
PVector[] pointsu = new PVector[]{
new PVector(0, 2 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 5 / 9.0),
new PVector(2 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(3 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(2 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0, 5 / 9.0)
};
PVector[] pointsr = new PVector[]{
new PVector(0 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 3 / 9.0),
new PVector(2 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 3 / 9.0),
new PVector(2 / 9.0, 3 / 9.0),
new PVector(1 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 6 / 9.0)
};
PVector[] pointsy = new PVector[]{
new PVector(0 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 8 / 9.0),
new PVector(3 / 9.0, 9 / 9.0),
new PVector(1 / 9.0, 9 / 9.0),
new PVector(0 / 9.0, 8 / 9.0),
new PVector(0 / 9.0, 7 / 9.0),
new PVector(1 / 9.0, 7 / 9.0),
new PVector(1 / 9.0, 8 / 9.0),
new PVector(3 / 9.0, 8 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 5 / 9.0)
};
PVector[] pointsn = new PVector[]{
new PVector(0 / 9.0, 0 / 9.0),
new PVector(1 / 9.0, 0 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(3 / 9.0, 0 / 9.0),
new PVector(4 / 9.0, 0 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 6 / 9.0)
};
PVector[] pointsi = new PVector[]{
new PVector(0 / 9.0, 3 / 9.0),
new PVector(1 / 9.0, 3 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 6 / 9.0)
};
PVector[] pointsic = new PVector[]{
new PVector(0 / 9.0, 1 / 9.0),
new PVector(1 / 9.0, 1 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(0 / 9.0, 2 / 9.0)
};
PVector[] pointsg = new PVector[]{
new PVector(1 / 9.0, 2 / 9.0),
new PVector(3 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 3 / 9.0),
new PVector(4 / 9.0, 8 / 9.0),
new PVector(3 / 9.0, 9 / 9.0),
new PVector(1 / 9.0, 9 / 9.0),
new PVector(0 / 9.0, 8 / 9.0),
new PVector(0 / 9.0, 7 / 9.0),
new PVector(1 / 9.0, 7 / 9.0),
new PVector(1 / 9.0, 8 / 9.0),
new PVector(3 / 9.0, 8 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 5 / 9.0),
new PVector(0 / 9.0, 3 / 9.0)
};
PVector[] pointsgc = new PVector[]{
new PVector(1 / 9.0, 3 / 9.0),
new PVector(1 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 3 / 9.0)
};
PVector[] pointsh = new PVector[]{
new PVector(0 / 9.0, 0 / 9.0),
new PVector(1 / 9.0, 0 / 9.0),
new PVector(1 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 3 / 9.0),
new PVector(4 / 9.0, 4 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 6 / 9.0)
};
PVector[] pointst = new PVector[]{
new PVector(1 / 9.0, 2 / 9.0),
new PVector(2 / 9.0, 2 / 9.0),
new PVector(2 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(2 / 9.0, 4 / 9.0),
new PVector(2 / 9.0, 5 / 9.0),
new PVector(4 / 9.0, 5 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 4 / 9.0),
new PVector(0 / 9.0, 4 / 9.0),
new PVector(0 / 9.0, 3 / 9.0),
new PVector(1 / 9.0, 3 / 9.0)
};
PVector[] pointss = new PVector[]{
new PVector(0 / 9.0, 0 / 9.0),
new PVector(4 / 9.0, 0 / 9.0),
new PVector(4 / 9.0, 1 / 9.0),
new PVector(1 / 9.0, 1 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 3 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(0 / 9.0, 3 / 9.0)
};
PVector[] pointsa = new PVector[]{
new PVector(3 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(0 / 9.0, 3 / 9.0),
new PVector(0 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 1 / 9.0),
new PVector(3 / 9.0, 1 / 9.0),
new PVector(4 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(2 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 5 / 9.0),
new PVector(0 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 3 / 9.0)
};
PVector[] pointsac = new PVector[]{
new PVector(3 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 5 / 9.0),
new PVector(2 / 9.0, 5 / 9.0)
};
PVector[] pointsd = new PVector[]{
new PVector(1 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 0 / 9.0),
new PVector(4 / 9.0, 0 / 9.0),
new PVector(4 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(2 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 5 / 9.0),
new PVector(0 / 9.0, 4 / 9.0)
};
PVector[] pointse = new PVector[]{
new PVector(1 / 9.0, 1 / 9.0),
new PVector(3 / 9.0, 1 / 9.0),
new PVector(4 / 9.0, 2 / 9.0),
new PVector(4 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 4 / 9.0),
new PVector(1 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 5 / 9.0),
new PVector(4 / 9.0, 4 / 9.0),
new PVector(4 / 9.0, 5 / 9.0),
new PVector(3 / 9.0, 6 / 9.0),
new PVector(1 / 9.0, 6 / 9.0),
new PVector(0 / 9.0, 5 / 9.0),
new PVector(0 / 9.0, 2 / 9.0)
};
PVector[] pointsec = new PVector[]{
new PVector(3 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 2 / 9.0),
new PVector(1 / 9.0, 3 / 9.0),
new PVector(3 / 9.0, 3 / 9.0)
};
PVector[] pointsdc = this.pointsac;
float strokeSize = 0.02;
color strokeColor = #00F5FF;
color bgGradLT = #FF96FD;
color bgGradRB = #D9FF96;
color bgGradLT2 = #984DFF;
color bgGradRB2 = #4DFFFD;
LogoFurryNightShade(){
}
LogoFurryNightShade(float strokeSize, color strokeColor, color bgGradLT, color bgGradRB){
this.strokeSize = strokeSize;
this.strokeColor = strokeColor;
this.bgGradLT = bgGradLT;
this.bgGradRB = bgGradRB;
}
PGraphics getGraphics(int x, int y, float logoSize, float animationTime, float animCS, float animM, float animCF, float animLS, float animLF, int[] startReq, AriaEasingArgument aeaCS, AriaEasingArgument aeaM, AriaEasingArgument aeaCF, AriaEasingArgument aeaLS, AriaEasingArgument aeaLF){
if(procedureDebug){
print("\nLogoFurryNightShade.getGraphics(x:" + x + ", y:" + y + ", logoSize:" + logoSize + ", animCS:" + animCS + ", animM:" + animM + ", animCF:" + animCF + ", animLS:" + animLS + ", animLF:" + animLF + ", startReq:");
if(startReq == null) println("null);");
else{
print("new int[]{");
for(int i = 0; i < startReq.length; i ++){
if(i != 0) print(", ");
print(startReq[i]);
}
print("});");
}
}
if(procedureDebug) println("Checking inpited values...");
if(x <= 0 || y <= 0){
if(errorDebug) println(tabText + "Error: Size must be greater than 0 in both directions (" + x + ", " + y + ").");
if(finalDebug) println(tabText + "Returned null.");
return null;
}
logoSize = constrain(logoSize, 0, 1);
if(logoSize <= 0){
if(errorDebug) println(tabText + "Error: Logo size must be greater than 0 (" + logoSize + ").");
if(finalDebug) println(tabText + "Returned empty PGraphics.");
return createGraphics(x, y);
}
if(animationTime <= 0){
if(errorDebug) println(tabText + "Error: Time must be greater than 0 (" + animationTime + ").");
if(finalDebug) println(tabText + "Returned rmpty PGraphics.");
return createGraphics(x, y);
}
animCF = animCF < 0 ? 0 : animCF;
animCS = animCS < 0 ? 0 : animCS;
animM = animM < 0 ? 0 : animM;
animLF = animLF < 0 ? 0 : animLF;
animLS = animLS < 0 ? 0 : animLS;
if(procedureDebug) println("Checking startReq...");
if(startReq == null){
if(warningDebug) println(tabText + "startReq is null. Setting startReq to default...");
startReq = new int[]{-1, 0, 1, 2, 3};
}
if(startReq.length != 5){
if(warningDebug) println(tabText + "startReq is not 5 values long(" + startReq.length + "). Setting startReq to default...");
startReq = new int[]{-1, 0, 1, 2, 3};
}
if(procedureDebug) println("Checking for startReq loops...");
for(int i = 0; i < startReq.length; i ++){
int req = startReq[i];
boolean loopFound = false;
IntList history = new IntList();
history.append(req);
while(req >= 0 && req < 5){
if(req == i){
loopFound = true;
history.append(req);
break;
}
history.append(req);
req = startReq[req];
}
if(loopFound){
if(errorDebug){
print(tabText + "Found a loop in startReq of length " + (history.size() - 1) + "(");
for(int j = 0; j < history.size(); j ++){
if(j != 0) print(" > ");
print(history.get(j));
}
print(").");
}
if(finalDebug) println(tabText + "Returned empty PGraphics.");
return createGraphics(x, y);
}
}
float scale = logoSize * min(x / 6.0, y / 1.0);
if(scale * x < 1 || scale * y < 1){
if(errorDebug) println(tabText + "Error: Scaled size must be greater than 0 in both directions (" + int(x * scale) + ", " + int(y * scale) + ").");
if(finalDebug) println(tabText + "Returned null.");
return null;
}
return this.generateGraphics(x, y, logoSize, animationTime, animCS, animM, animCF, animLS, animLF, startReq, aeaCS, aeaM, aeaCF, aeaLS, aeaLF);
}
private PGraphics generateGraphics(int x, int y, float logoSize, float animationTime, float animCS, float animM, float animCF, float animLS, float animLF, int[] startReq, AriaEasingArgument aeaCS, AriaEasingArgument aeaM, AriaEasingArgument aeaCF, AriaEasingArgument aeaLS, AriaEasingArgument aeaLF){
if(this.procedureDebug) println("Generating graphics...");
if(this.procedureDebug) println("Calculating time values...");
float[] animLength = new float[]{animCS, animM, animCF, animLS, animLF};
int[] deps = new int[5];
for(int i = 0; i < 5; i ++){
int l = -1;
int req = i;
while(req >= 0 && req < 5){
l ++;
req = startReq[req];
}
deps[i] = l;
}
float[] animStart = new float[5];
float[] animEnd = new float[5];
for(int dep = 0; dep < 5; dep ++){
for(int i = 0; i < 5; i ++){
if(deps[i] == dep){
if(dep == 0) animStart[i] = 0;
else animStart[i] = animEnd[startReq[i]];
animEnd[i] = animStart[i] + animLength[i];
}
}
}
if(frameCount == 30){
printArray(animStart);
printArray(animEnd);
}
float scale = logoSize * min(x * 9.0 / 72.0, y / 9.0);
float animCSP = constrain((animationTime - animStart[0]) / (animEnd[0] - animStart[0]), 0, 1);
float animMP = constrain((animationTime - animStart[1]) / (animEnd[1] - animStart[1]), 0, 1);
float animCFP = constrain((animationTime - animStart[2]) / (animEnd[2] - animStart[2]), 0, 1);
float animLSP = constrain((animationTime - animStart[3]) / (animEnd[3] - animStart[3]), 0, 1);
float animLFP = constrain((animationTime - animStart[4]) / (animEnd[4] - animStart[4]), 0, 1);
animCSP = (float)(aeaCS == null ? animCSP : (aeaCS.type2 == null ? AriaEasing.getNormalized(animCSP, aeaCS.type1, aeaCS.tension1) : AriaEasing.getNormalized(animCSP, aeaCS.type1, aeaCS.tension1, aeaCS.type2, aeaCS.tension2)));
animMP = (float)(aeaM == null ? animMP : (aeaM.type2 == null ? AriaEasing.getNormalized(animMP, aeaM.type1, aeaM.tension1) : AriaEasing.getNormalized(animMP, aeaM.type1, aeaM.tension1, aeaM.type2, aeaM.tension2)));
animCFP = (float)(aeaCF == null ? animCFP : (aeaCF.type2 == null ? AriaEasing.getNormalized(animCFP, aeaCF.type1, aeaCF.tension1) : AriaEasing.getNormalized(animCFP, aeaCF.type1, aeaCF.tension1, aeaCF.type2, aeaCF.tension2)));
animLSP = (float)(aeaCS == null ? animLSP : (aeaLS.type2 == null ? AriaEasing.getNormalized(animLSP, aeaLS.type1, aeaLS.tension1) : AriaEasing.getNormalized(animLSP, aeaLS.type1, aeaLS.tension1, aeaLS.type2, aeaLS.tension2)));
animLFP = (float)(aeaLF == null ? animLFP : (aeaLF.type2 == null ? AriaEasing.getNormalized(animLFP, aeaLF.type1, aeaLF.tension1) : AriaEasing.getNormalized(animLFP, aeaLF.type1, aeaLF.tension1, aeaLF.type2, aeaLF.tension2)));
float left = x / 2 - 72.0 / 18.0 * scale;
float right = x - left;
float top = y / 2 - scale;
float bottom = y - top;
float bw = (right - left) / 72;
if(this.procedureDebug) println("Generating fill templates...");
PImage bgTemplateCapital = createImage(int(right - left), int(bottom - top), RGB);
PImage bgTemplateLowercase = createImage(int(right - left), int(bottom - top), RGB);
bgTemplateCapital.loadPixels();
bgTemplateLowercase.loadPixels();
for(int xc = 0; xc < bgTemplateCapital.width; xc ++){
for(int yc = 0; yc < bgTemplateCapital.height; yc ++){
float percentage = (xc + yc) / float(bgTemplateCapital.width + bgTemplateCapital.height);
bgTemplateCapital.pixels[xc + yc * bgTemplateCapital.width] = percentage <= animCFP ? lerpColor(this.bgGradLT, this.bgGradRB, percentage) : color(0, 0);
bgTemplateLowercase.pixels[xc + yc * bgTemplateLowercase.width] = percentage <= animLFP ? lerpColor(this.bgGradLT2, this.bgGradRB2, percentage) : color(0, 0);
}
}
bgTemplateCapital.updatePixels();
bgTemplateLowercase.updatePixels();
float lf = left + (28.5 - 28.5 * animMP) * bw;
float lu = lf + 5 * bw;
float lr1 = lf + 10 * bw;
float lr2 = lf + 15 * bw;
float ly = lf + 20 * bw;
float ln = left + (33.5 - 8.5 * animMP) * bw;
float li = ln + 5 * bw;
float lg = ln + 7 * bw;
float lh1 = ln + 12 * bw;
float lt = ln + 17 * bw;
float ls = left + (38.5 + 8.5 * animMP) * bw;
float lh2 = ls + 5 * bw;
float la = ls + 10 * bw;
float ld = ls + 15 * bw;
float le = ls + 20 * bw;
float lfes = lf + 5 * bw + 19 * bw * animMP;
float lnes = ln + 5 * bw + 16 * bw * animMP;
float lses = ls + 5 * bw + 19 * bw * animMP;
if(this.procedureDebug) println("Generating text template...");
PGraphics strokeText = createGraphics(x, y);
strokeText.beginDraw();
strokeText.stroke(this.strokeColor);
strokeText.noFill();
strokeText.strokeWeight(this.strokeSize * scale);
this.drawShapeStroke(this.pointsf, strokeText, lf, top, bw, animCSP, "F");
this.drawShapeStroke(this.pointsu, strokeText, lu, top, bw, animLSP, "u");
this.drawShapeStroke(this.pointsr, strokeText, lr1, top, bw, animLSP, "r");
this.drawShapeStroke(this.pointsr, strokeText, lr2, top, bw, animLSP, "r");
this.drawShapeStroke(this.pointsy, strokeText, ly, top, bw, animLSP, "y");
this.removeRight(strokeText, lfes);
this.drawShapeStroke(this.pointsn, strokeText, ln, top, bw, animCSP, "N");
this.drawShapeStroke(this.pointsi, strokeText, li, top, bw, animLSP, "i");
this.drawShapeStroke(this.pointsic, strokeText, li, top, bw, animLSP, "i");
this.drawShapeStroke(this.pointsg, strokeText, lg, top, bw, animLSP, "g");
this.drawShapeStroke(this.pointsgc, strokeText, lg, top, bw, animLSP, "g");
this.drawShapeStroke(this.pointsh, strokeText, lh1, top, bw, animLSP, "h");
this.drawShapeStroke(this.pointst, strokeText, lt, top, bw, animLSP, "t");
this.removeRight(strokeText, lnes);
this.drawShapeStroke(this.pointss, strokeText, ls, top, bw, animCSP, "S");
this.drawShapeStroke(this.pointsh, strokeText, lh2, top, bw, animLSP, "h");
this.drawShapeStroke(this.pointsa, strokeText, la, top, bw, animLSP, "a");
this.drawShapeStroke(this.pointsac, strokeText, la, top, bw, animLSP, "a");
this.drawShapeStroke(this.pointsd, strokeText, ld, top, bw, animLSP, "d");
this.drawShapeStroke(this.pointsdc, strokeText, ld, top, bw, animLSP, "d");
this.drawShapeStroke(this.pointse, strokeText, le, top, bw, animLSP, "e");
this.drawShapeStroke(this.pointsec, strokeText, le, top, bw, animLSP, "e");
this.removeRight(strokeText, lses);
strokeText.endDraw();
PGraphics fillTemplate = createGraphics(x, y);
fillTemplate.beginDraw();
fillTemplate.fill(255);
fillTemplate.noStroke();
this.drawShapeFill(this.pointsf, null, fillTemplate, lf, top, bw, "F");
this.drawShapeFill(this.pointsu, null, fillTemplate, lu, top, bw, "u");
this.drawShapeFill(this.pointsr, null, fillTemplate, lr1, top, bw, "r");
this.drawShapeFill(this.pointsr, null, fillTemplate, lr2, top, bw, "r");
this.drawShapeFill(this.pointsy, null, fillTemplate, ly, top, bw, "y");
this.removeRight(fillTemplate, lfes);
this.drawShapeFill(this.pointsn, null, fillTemplate, ln, top, bw, "N");
this.drawShapeFill(this.pointsi, null, fillTemplate, li, top, bw, "i");
this.drawShapeFill(this.pointsic, null, fillTemplate, li, top, bw, "i");
this.drawShapeFill(this.pointsg, this.pointsgc, fillTemplate, lg, top, bw, "g");
this.drawShapeFill(this.pointsh, null, fillTemplate, lh1, top, bw, "h");
this.drawShapeFill(this.pointst, null, fillTemplate, lt, top, bw, "t");
this.removeRight(fillTemplate, lnes);
this.drawShapeFill(this.pointss, null, fillTemplate, ls, top, bw, "S");
this.drawShapeFill(this.pointsh, null, fillTemplate, lh2, top, bw, "h");
this.drawShapeFill(this.pointsa, this.pointsac, fillTemplate, la, top, bw, "a");
this.drawShapeFill(this.pointsd, this.pointsdc, fillTemplate, ld, top, bw, "d");
this.drawShapeFill(this.pointse, this.pointsec, fillTemplate, le, top, bw, "e");
this.removeRight(fillTemplate, lses);
fillTemplate.endDraw();
if(this.procedureDebug) println("Generating final PGraphics...");
PGraphics pg = createGraphics(x, y);
pg.beginDraw();
pg.loadPixels();
fillTemplate.loadPixels();
bgTemplateCapital.loadPixels();
bgTemplateLowercase.loadPixels();
for(int xc = 0; xc < bgTemplateCapital.width; xc ++){
for(int yc = 0; yc < bgTemplateCapital.height; yc ++){
boolean isAtCapital = false;
if(left + xc >= lf && left + xc <= lf + 4 * bw) isAtCapital = true;
else if(left + xc >= ln && left + xc <= ln + 4 * bw) isAtCapital = true;
else if(left + xc >= ls && left + xc <= ls + 4 * bw) isAtCapital = true;
if(isAtCapital)
if(fillTemplate.pixels[int(left) + xc + int(top + yc) * fillTemplate.width] == color(255)) pg.pixels[int(left) + xc + int(top + yc) * pg.width] = bgTemplateCapital.pixels[xc + yc * bgTemplateCapital.width];
if(!isAtCapital)
if(fillTemplate.pixels[int(left) + xc + int(top + yc) * fillTemplate.width] == color(255)) pg.pixels[int(left) + xc + int(top + yc) * pg.width] = bgTemplateLowercase.pixels[xc + yc * bgTemplateLowercase.width];
}
}
pg.updatePixels();
fillTemplate.updatePixels();
bgTemplateCapital.updatePixels();
bgTemplateLowercase.updatePixels();
pg.imageMode(CORNERS);
pg.image(strokeText, 0, 0);
pg.endDraw();
if(this.finalDebug) println("Returned PGraphics.");
return pg;
}
private void drawShapeStroke(PVector[] pts, PGraphics pg, float x, float y, float bw, float perc, String s){
if(this.procedureDebug) println("Generating text stroke template for '" + s + "'...");
float length = 0;
float usedDistance = 0;
for(int i = 0; i < pts.length; i ++){
PVector a = pts[i];
PVector b = pts[(i + 1) % pts.length];
length += dist(a.x, a.y, b.x, b.y);
}
length *= perc;
for(int i = 0; i < pts.length; i ++){
PVector a = pts[i];
PVector b = pts[(i + 1) % pts.length];
float d = dist(a.x, a.y, b.x, b.y);
float totald = d;
if(d >= length - usedDistance && perc != 1){
d = length - usedDistance;
float dp = d / totald;
//println(dp + " = " + d + " / " + totald);
float x1 = x + bw * 9 * a.x;
float y1 = y + bw * 9 * a.y;
float x2 = x + bw * 9 * ((b.x - a.x) * dp + a.x);
float y2 = y + bw * 9 * ((b.y - a.y) * dp + a.y);
pg.line(x1, y1, x2, y2);
break;
}
else{
pg.line(x + bw * a.x * 9, y + bw * a.y * 9, x + bw * b.x * 9, y + bw * b.y * 9);
usedDistance += d;
}
}
}
private void removeRight(PGraphics pg, float x){
pg.loadPixels();
for(int xc = int(x); xc < pg.width; xc ++){
for(int yc = 0; yc < pg.height; yc ++){
pg.pixels[xc + yc * pg.width] = color(0, 0);
}
}
pg.updatePixels();
}
private void drawShapeFill(PVector[] pts, PVector[] c, PGraphics pg, float x, float y, float bw, String s){
if(this.procedureDebug) println("Generating text fill template for '" + s + "'...");
pg.beginShape();
for(int i = 0; i < pts.length + 1; i ++){
PVector a = pts[(i + 1) % pts.length];
pg.vertex(x + bw * a.x * 9, y + bw * a.y * 9);
}
if(c != null){
pg.beginContour();
for(int i = 0; i < c.length + 1; i ++){
PVector a = c[(i) % c.length];
pg.vertex(x + bw * a.x * 9, y + bw * a.y * 9);
}
pg.endContour();
}
pg.endShape(CLOSE);
}
}