b-g / Ani

A lightweight animation library for the programming environment Processing
79 stars 13 forks source link

Animation not smooth and not in sync (when expected to be) in Processing 3 #15

Open surmvoise opened 8 years ago

surmvoise commented 8 years ago

In the code below (you also can download it) I recreated this strange behavior I'm referring to in the title. All the animations should basically be in sync and start together (if I'm not really mistaken) but they're not. After at last two recreation cycles (of those Stripe objects) this becomes very obvious. And also strange is that the first row on the far left behaves even more independently. When you look close you see a slight lag on the second Stripe (in the row on the left) as soon as the object in front of it ends it's animation. And yes, I have an application where I need each Stripe object to be able to behave differently, that's why I don't use one single animation for all the Stripe in all rows.

So, what's the reason behind this behavior? Is this a bug? And is there a workaround?

Download pde: RecreateAniBug.zip

Click inside the sketch window to start animation of Stripe objects. I set the frameRate to 10 so the effect is more visible. (I run Processing version: 3.0.2 / Ani library version: 2.7)

`import de.looksgood.ani.*; ArrayList stripeBundles;

void setup() { frameRate(10); size(600, 400, P3D); background(100); Ani.init(this); //Ani.setDefaultTimeMode("FRAMES");

// create 8 StripeBundle objects of which each can have mupltiple Stripe obejects stripeBundles = new ArrayList(); for (int i = 0; i < 8; i++) { stripeBundles.add(new StripeBundle(0 + i*60, 0)); } }

void draw() { background(100); if (stripeBundles.get(7).stripes.size() > 0) { println("seek: "+stripeBundles.get(7).stripes.get(0).posYAni.getSeek()); }

for (StripeBundle sb : stripeBundles) { sb.run();

// print how many Stripe objects each StripeBundle has (check only first one)
if (stripeBundles.indexOf(sb) == 7)
  println("number of Stripe objects: "+stripeBundles.get(stripeBundles.indexOf(sb)).stripes.size());

// add a new Stripe obect to each StripeBundle when animation's seek 
// of first Stripe (in the last StripeBundle) is over the half
if (stripeBundles.get(stripeBundles.lastIndexOf(sb)).stripes.size() == 1) {
  if (stripeBundles.get(3).stripes.get(0).posYAni.getSeek() > 0.5) 
    sb.stripes.add( new Stripe(50, height, 80));
}

} }

void mousePressed() { // add a new Stripe obect to each StripeBundle for (StripeBundle sb : stripeBundles) { sb.stripes.add( new Stripe(50, height, 80)); } }

class StripeBundle { float locX, locY; ArrayList stripes;

StripeBundle(float locX, float locY) { this.locX = locX; this.locY = locY; stripes = new ArrayList(); }

void run() { for (Stripe s : stripes) { pushMatrix(); translate(locX, locY); s.run(); popMatrix(); } for (int i = stripes.size()-1; i >=0; i--) { Stripe s = stripes.get(i); if (!s.alive) stripes.remove(i); } } }

class Stripe { float h; // height of the "canvas" float w; // width of the "canvas" float l; // length of stripe float posY; // current position of Y float posX; // position of X color col; // color of stripe boolean alive; // remove from ArrayList when not alive float dur; // duration of posYAni animation boolean dir; // direction of movement (true: up, flase: down) float fromY; float toY; Ani posYAni; // animation of Y

Stripe(float w, float h, float l) { this.h = h; this.w = w; this.l = l; this.col = color(255); this.posY = h/2; this.posX = w/2; alive = true;

fromY = -h/2 -l/2;
toY = h/2 +l/2+1;
posY = fromY;
dur = 2;
posYAni = new Ani(this, dur, "posY", toY, Ani.QUAD_IN_OUT);

}

void run() { update(); display(); }

void update() { if ( posYAni.isEnded() ) alive = false; }

void display() { pushMatrix(); fill(col); //noStroke(); stroke(0); rectMode(CENTER); translate(posX, h/2); rotate(PI);
rect(0, posY, w, l); popMatrix(); } }`