/*
* @(#)GooTransition2D.java
*
* $Date: 2014-06-06 20:04:49 +0200 (P, 06 jún. 2014) $
*
* Copyright (c) 2011 by Jeremy Wood.
* All rights reserved.
*
* The copyright of this software is owned by Jeremy Wood.
* You may not use, copy or modify this software, except in
* accordance with the license agreement you entered into with
* Jeremy Wood. For details see accompanying license terms.
*
* This software is probably, but not necessarily, discussed here:
* https://javagraphics.java.net/
*
* That site should also contain the most recent official version
* of this software. (See the SVN repository for more details.)
*/
package com.bric.image.transition;
import java.awt.Dimension;
import java.awt.Shape;
import java.awt.geom.GeneralPath;
import java.util.Random;
/** This resembles a bucket of paint being thrown at a wall. The
* clipping of the incoming shape is this liquid-dripping outline. Here are playback samples:
* <p><table summary="Sample Animations of GooTransition2D" cellspacing="50" border="0"><tr>
* <td align="center">
* <img src="https://javagraphics.java.net/resources/transition/GooTransition2D/Goo(10).gif" alt="Goo (10)">
* <p>Goo (10)
* </td>
* <td align="center">
* <img src="https://javagraphics.java.net/resources/transition/GooTransition2D/Goo(20).gif" alt="Goo (10)">
* <p>Goo (20)
* </td>
* <td align="center">
* <img src="https://javagraphics.java.net/resources/transition/GooTransition2D/Goo(50).gif" alt="Goo (10)">
* <p>Goo (50)
* </td>
* </tr></table>
*
*/
public class GooTransition2D extends AbstractClippedTransition2D {
/** This public static method is used by the
* {@link com.bric.image.transition.Transition2DDemoHelper}
* class to create sample animations of this transition.
* @return the transitions that should be used to demonstrate this
* transition.
*/
public static Transition[] getDemoTransitions() {
return new Transition[] {
new GooTransition2D(10),
new GooTransition2D(20),
new GooTransition2D(50)
};
}
float[] offset;
float[] accel;
/** Creates a new goo transtion with 20 columns. */
public GooTransition2D() {
this(20);
}
/** Creates a new goo transition.
*
* @param columns the number of columns to use.
*/
public GooTransition2D(int columns) {
Random r = new Random();
offset = new float[columns];
accel = new float[columns];
boolean ok = false;
long seed = System.currentTimeMillis();
while(!ok) {
seed++;
r.setSeed(seed);
ok = true;
for(int a = 0; a<columns && ok; a++) {
offset[a] = -r.nextFloat();
accel[a] = 4*r.nextFloat()+.2f;
if(accel[a]+1+offset[a]<1.2)
ok = false;
}
if(ok) {
//make sure at least one strand takes up the whole time t=[0,1]
boolean atLeastOneSlowOne = false;
for(int a = 0; a<columns && atLeastOneSlowOne==false; a++) {
atLeastOneSlowOne = accel[a]+1+offset[a]<1.3;
}
ok = atLeastOneSlowOne;
}
}
}
@Override
public Shape[] getShapes(float progress, Dimension size) {
float[] f = new float[offset.length];
for(int a = 0; a<f.length; a++) {
f[a] = size.height*(offset[a]+progress+progress*progress*accel[a]);
}
float w = ((float)size.width)/((float)f.length);
int k = 4; //padding to make the stroke doesn't show
GeneralPath path = new GeneralPath();
path.moveTo(-k, -k);
path.lineTo(-k, f[0]);
path.lineTo(w/2f, f[0]);
for(int a = 1; a<f.length; a++) {
float x1 = (a-1)*w+w/2f;
float x2 = (a)*w+w/2f;
path.curveTo(x1+w/2, f[a-1], x2-w/2, f[a], x2, f[a]);
}
path.lineTo(size.width+k, f[f.length-1]);
path.lineTo(size.width+k, -k);
path.lineTo(-k, -k);
path.closePath();
return new Shape[] {path};
}
@Override
public float getStrokeWidth(float progress,Dimension size) {
return 1;
}
@Override
public String toString() {
return "Goo ("+offset.length+")";
}
}