com.alee.managers.effects.ShapeTransition Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weblaf-ui Show documentation
Show all versions of weblaf-ui Show documentation
WebLaf is a Java Swing Look and Feel and extended components library for cross-platform applications
/*
* This file is part of WebLookAndFeel library.
*
* WebLookAndFeel library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* WebLookAndFeel library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with WebLookAndFeel library. If not, see .
*/
package com.alee.managers.effects;
import com.alee.extended.window.TestFrame;
import com.alee.laf.WebLookAndFeel;
import com.alee.managers.hotkey.Hotkey;
import com.alee.managers.hotkey.HotkeyManager;
import com.alee.managers.hotkey.HotkeyRunnable;
import com.alee.utils.GraphicsUtils;
import com.alee.utils.swing.WebTimer;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Mikle Garin
*/
public class ShapeTransition
{
private static Shape shape = null;
private static JComponent component;
private static WebTimer timer;
private static int counter = 0;
public static void main ( final String[] args )
{
WebLookAndFeel.install ();
// final Ellipse2D.Double circle = new Ellipse2D.Double ( 0, 0, 100, 100 );
// final GeneralPath circle = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
final Shape circle = new Arc2D.Double ( 0,0,800,800,0f, 270, Arc2D.PIE );
final Line2D.Double line = new Line2D.Double ( 0, 0, 800, 0 );
component = new JComponent ()
{
@Override
protected void paintComponent ( final Graphics g )
{
super.paintComponent ( g );
final Graphics2D g2d = ( Graphics2D ) g;
GraphicsUtils.setupAntialias ( g2d );
g2d.setPaint ( Color.BLACK );
g2d.draw ( shape != null ? shape : circle );
}
@Override
public Dimension getPreferredSize ()
{
return new Dimension ( 800, 800 );
}
};
final MouseAdapter a = new MouseAdapter ()
{
public void mousePressed ( final MouseEvent e )
{
if ( timer != null && timer.isRunning () )
{
reset ();
}
else
{
addPoint ( e );
}
}
public void mouseDragged ( final MouseEvent e )
{
if ( timer != null && timer.isRunning () )
{
reset ();
}
else
{
addPoint ( e );
}
}
protected void reset ()
{
// if ( timer != null )
// {
// timer.stop ();
// }
// shape = null;
// counter = 0;
// circle.reset ();
// component.repaint ();
}
protected void addPoint ( final MouseEvent e )
{
// if ( counter == 0 )
// {
// circle.moveTo ( e.getPoint ().x, e.getPoint ().y );
// }
// else
// {
// circle.lineTo ( e.getPoint ().x, e.getPoint ().y );
// }
// counter++;
// component.repaint ();
}
};
component.addMouseListener ( a );
component.addMouseMotionListener ( a );
component.setFocusable ( true );
TestFrame.show ( component );
HotkeyManager.registerHotkey ( Hotkey.SPACE, new HotkeyRunnable ()
{
public void run ( final KeyEvent e )
{
System.out.println ( "STARTED!" );
perform ( circle, line, 5000 );
}
} );
component.requestFocusInWindow ();
}
public static void perform ( final Shape startShape, final Shape endShape, final long time )
{
final List startInfo = gatherInfo ( startShape.getPathIterator ( null ) );
final List endInfo = gatherInfo ( endShape.getPathIterator ( null ) );
final List srcPoints = calculateSrc ( startInfo );
final List dstPoints = calculateDst ( startInfo, endInfo );
if ( timer != null )
{
timer.stop ();
}
timer = WebTimer.repeat ( 1000 / 60, 0, true, new ActionListener ()
{
private float progress = 0f;
@Override
public void actionPerformed ( final ActionEvent e )
{
progress += ( 1f - progress ) * 0.05f;
final GeneralPath gp = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
for ( int i = 0; i < srcPoints.size (); i++ )
{
final PointInfo src = srcPoints.get ( i );
final PointInfo dst = dstPoints.get ( i );
switch ( src.command )
{
case PathIterator.SEG_MOVETO:
gp.moveTo ( progress ( src.points[ 0 ], dst.points[ 0 ], progress ),
progress ( src.points[ 1 ], dst.points[ 1 ], progress ) );
break;
case PathIterator.SEG_LINETO:
gp.lineTo ( progress ( src.points[ 0 ], dst.points[ 0 ], progress ),
progress ( src.points[ 1 ], dst.points[ 1 ], progress ) );
break;
case PathIterator.SEG_QUADTO:
gp.quadTo ( progress ( src.points[ 0 ], dst.points[ 0 ], progress ),
progress ( src.points[ 1 ], dst.points[ 1 ], progress ),
progress ( src.points[ 2 ], dst.points[ 2 ], progress ),
progress ( src.points[ 3 ], dst.points[ 3 ], progress ) );
break;
case PathIterator.SEG_CUBICTO:
gp.curveTo ( progress ( src.points[ 0 ], dst.points[ 0 ], progress ),
progress ( src.points[ 1 ], dst.points[ 1 ], progress ),
progress ( src.points[ 2 ], dst.points[ 2 ], progress ),
progress ( src.points[ 3 ], dst.points[ 3 ], progress ),
progress ( src.points[ 4 ], dst.points[ 4 ], progress ),
progress ( src.points[ 5 ], dst.points[ 5 ], progress ) );
break;
case PathIterator.SEG_CLOSE:
gp.closePath ();
break;
}
}
shape = gp;
if ( progress >= 1f )
{
progress = 1f;
timer.stop ();
}
else
{
component.repaint ();
}
}
} );
}
private static List calculateSrc ( final List startInfo )
{
return startInfo;
// List srcInfo = new ArrayList ( startInfo.size () );
// for ( int i = 0; i < startInfo.size (); i++ )
// {
// srcInfo.add ( new PointInfo ( i == 0 ? PathIterator.SEG_MOVETO : PathIterator.SEG_LINETO,
// new float[]{ startInfo.get ( i ).points[ 0 ], startInfo.get ( i ).points[ 1 ] } ) );
// }
// return srcInfo;
}
private static List calculateDst ( final List startInfo, final List endInfo )
{
final List dstInfo = new ArrayList ( startInfo.size () );
final Point2D.Double p1 = new Point2D.Double ( endInfo.get ( 0 ).points[ 0 ], endInfo.get ( 0 ).points[ 1 ] );
final Point2D.Double p2 = new Point2D.Double ( endInfo.get ( 1 ).points[ 0 ], endInfo.get ( 1 ).points[ 1 ] );
for ( int i = 0; i < startInfo.size (); i++ )
{
final float x = ( float ) ( p1.x + p2.x ) * i / ( startInfo.size () - 1 );
final float y = ( float ) ( p1.y + p2.y ) * i / ( startInfo.size () - 1 );
final int command = startInfo.get ( i ).command;
switch ( command )
{
case PathIterator.SEG_MOVETO:
{
dstInfo.add ( new PointInfo ( command, new float[]{ x, y } ) );
break;
}
case PathIterator.SEG_LINETO:
{
dstInfo.add ( new PointInfo ( command, new float[]{ x, y } ) );
break;
}
case PathIterator.SEG_QUADTO:
{
final float[] pp = dstInfo.get ( i - 1 ).points;
final float px = pp[ pp.length - 2 ];
final float py = pp[ pp.length - 1 ];
dstInfo.add ( new PointInfo ( command, new float[]{ progress ( px, x, 0.5f ), progress ( py, y, 0.5f ), x, y } ) );
break;
}
case PathIterator.SEG_CUBICTO:
{
final float[] pp = dstInfo.get ( i - 1 ).points;
final float px = pp[ pp.length - 2 ];
final float py = pp[ pp.length - 1 ];
dstInfo.add ( new PointInfo ( command,
new float[]{ progress ( px, x, 0.33f ), progress ( py, y, 0.33f ), progress ( px, x, 0.66f ),
progress ( py, y, 0.66f ), x, y } ) );
break;
}
case PathIterator.SEG_CLOSE:
{
dstInfo.add ( new PointInfo ( command, null ) );
break;
}
}
}
return dstInfo;
}
protected static List gatherInfo ( final PathIterator iterator )
{
final List info = new ArrayList ();
while ( !iterator.isDone () )
{
final float[] points = new float[ 6 ];
final int type = iterator.currentSegment ( points );
System.out.println ( Arrays.toString ( points ) );
switch ( type )
{
case PathIterator.SEG_MOVETO:
System.out.println ( "SEG_MOVETO" );
break;
case PathIterator.SEG_LINETO:
System.out.println ( "SEG_LINETO" );
break;
case PathIterator.SEG_QUADTO:
System.out.println ( "SEG_QUADTO" );
break;
case PathIterator.SEG_CUBICTO:
System.out.println ( "SEG_CUBICTO" );
break;
case PathIterator.SEG_CLOSE:
System.out.println ( "SEG_CLOSE" );
break;
}
info.add ( new PointInfo ( type, points ) );
iterator.next ();
}
return info;
}
public static class PointInfo
{
public final int command;
public final float[] points;
public PointInfo ( final int command, final float[] points )
{
super ();
this.command = command;
this.points = points;
}
}
private static float progress ( final float x1, final float x2, final float progress )
{
return ( 1 - progress ) * x1 + progress * x2;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy