/* * @(#)FunkyWipeTransition2D.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 com.bric.geom.Clipper; import com.bric.geom.MeasuredShape; import com.bric.geom.RectangularTransform; import net.jafama.FastMath; import java.awt.Dimension; import java.awt.geom.AffineTransform; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** This is a fun variation of a "Wipe" transition. The line * that separates the two frames spins as it slides. The * circular wipe is especially interesting because it begins and ends * on the same side of the frame. * <P>(This is loosely based on a transition I saw while * watching Royal Pains on Hulu one weekend...) * <p>Here are playback samples: * <p><table summary="Sample Animations of FunkyWipeTransition2D" cellspacing="50" border="0"><tr> * <td align="center"> * <img src="https://javagraphics.java.net/resources/transition/FunkyWipeTransition2D/FunkyWipeCircular.gif" alt="Funky Wipe Circular"> * <p>Funky Wipe Circular * </td> * <td align="center"> * <img src="https://javagraphics.java.net/resources/transition/FunkyWipeTransition2D/FunkyWipeAcross.gif" alt="Funky Wipe Across"> * <p>Funky Wipe Across * </td> * </tr></table> * */ public class FunkyWipeTransition2D extends Transition2D { /** 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 FunkyWipeTransition2D(true), new FunkyWipeTransition2D(false) }; } private static final GeneralPath pathCyclic = createPathCyclic(); private static final MeasuredShape measuredPathCyclic = new MeasuredShape(pathCyclic); private static final GeneralPath pathAcross = createPathAcross(); private static final MeasuredShape measuredPathAcross = new MeasuredShape(pathAcross); private static GeneralPath createPathCyclic() { GeneralPath p = new GeneralPath(); p.moveTo(99.936f, 51.019f); p.curveTo(99.936f, 51.019f, 78.316f, 86.931f, 51.019f, 89.745f); p.curveTo(23.721f, 92.559f, -2.012f, 75.843f, 11.082f, 61.21f); p.curveTo(4.178f, 46.576f, 34.931f, 39.565f, 62.229f, 36.751f); p.curveTo(89.526f, 33.937f, 99.936f, 51.019f, 99.936f, 51.019f); return p; } private static GeneralPath createPathAcross() { GeneralPath p = new GeneralPath(); p.moveTo(99.936f, 21.019f); p.curveTo(99.936f, 51.019f, 78.316f, 86.931f, 51.019f, 89.745f); p.curveTo(23.721f, 92.559f, -2.012f, 75.843f, 0, 61.21f); return p; } boolean circular; public FunkyWipeTransition2D(boolean fullCircle) { circular = fullCircle; } @Override public Transition2DInstruction[] getInstructions(float progress, Dimension size) { Rectangle2D.Float frameRect = new Rectangle2D.Float(0, 0, size.width, size.height); Point2D p = new Point2D.Double(); MeasuredShape path = circular ? measuredPathCyclic : measuredPathAcross; path.getPoint(progress*path.getOriginalDistance(), p ); int m = circular ? 1 : 2; double angle = Math.PI/2+m*Math.PI*progress; float k = 10000; GeneralPath clip = new GeneralPath(); clip.moveTo((float)p.getX(), (float)p.getY()); clip.lineTo((float)(p.getX()+k*FastMath.cos(angle)), (float)(p.getY()+k* FastMath.sin(angle))); clip.lineTo((float)(p.getX()+k*FastMath.cos(angle)+k*FastMath.cos(angle-Math.PI/2)), (float)(p.getY()+k*FastMath.sin(angle)+k*FastMath.sin(angle-Math.PI/2)) ); clip.lineTo((float)(p.getX()-100*FastMath.cos(angle)+k*FastMath.cos(angle-Math.PI/2)), (float)(p.getY()-k*FastMath.sin(angle)+k*FastMath.sin(angle-Math.PI/2)) ); clip.lineTo((float)(p.getX()-k*FastMath.cos(angle)), (float)(p.getY()-k*FastMath.sin(angle)) ); clip.closePath(); AffineTransform map = RectangularTransform.create( new Rectangle2D.Float(0, 0, 100, 100), frameRect ); clip.transform( map ); clip = Clipper.clipToRect(clip, frameRect); return new Transition2DInstruction[] { new ImageInstruction(true, 1, frameRect, size, null), new ImageInstruction(false, 1, frameRect, size, clip) }; } @Override public String toString() { String s = ( circular ? " Circular" : " Across"); return "Funky Wipe "+s; } }