com.alee.extended.transition.effects.blocks.BlocksTransitionEffect 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.extended.transition.effects.blocks;
import com.alee.extended.transition.ImageTransition;
import com.alee.extended.transition.TransitionUtils;
import com.alee.extended.transition.effects.DefaultTransitionEffect;
import com.alee.extended.transition.effects.Direction;
import com.alee.utils.GraphicsUtils;
import com.alee.utils.MathUtils;
import com.alee.utils.swing.WebTimer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.GeneralPath;
import java.util.ArrayList;
import java.util.List;
/**
* @author Mikle Garin
*/
public class BlocksTransitionEffect extends DefaultTransitionEffect
{
private static final String BLOCK_TYPE = "BLOCK_TYPE";
private static final String BLOCK_FADE = "BLOCK_FADE";
private static final String BLOCK_SIZE = "BLOCK_SIZE";
private static final String BLOCK_SPEED = "BLOCK_SPEED";
private static final String BLOCK_AMOUNT = "BLOCK_AMOUNT";
private int size;
private int speed;
private int blocksAmount;
private boolean fade;
private BlockType type;
private Direction direction;
private int[][] progress;
private Shape clip;
private List allPoints;
private WebTimer randomizer;
public BlocksTransitionEffect ()
{
super ();
}
public BlockType getType ()
{
return get ( BLOCK_TYPE, BlockType.random );
}
public void setType ( final BlockType type )
{
put ( BLOCK_TYPE, type );
}
public boolean isFade ()
{
return get ( BLOCK_FADE, true );
}
public void setFade ( final boolean transparent )
{
put ( BLOCK_FADE, transparent );
}
public int getSize ()
{
return get ( BLOCK_SIZE, 80 );
}
public void setSize ( final int size )
{
put ( BLOCK_SIZE, size );
}
public int getSpeed ()
{
return get ( BLOCK_SPEED, 4 );
}
public void setSpeed ( final int speed )
{
put ( BLOCK_SPEED, speed );
}
public int getBlocksAmount ()
{
return get ( BLOCK_AMOUNT, 5 );
}
public void setBlocksAmount ( final int blocksAmount )
{
put ( BLOCK_AMOUNT, blocksAmount );
}
@Override
public void prepareAnimation ( final ImageTransition imageTransition )
{
// Updating settings
size = getSize ();
speed = getSpeed ();
blocksAmount = getBlocksAmount ();
fade = isFade ();
direction = TransitionUtils.getActualValue ( getDirection () );
type = TransitionUtils.getActualValue ( getType () );
// Updating runtime values
int h = imageTransition.getHeight ();
h = h % size == 0 ? h : ( h / size ) * size + size;
int w = imageTransition.getWidth ();
w = w % size == 0 ? w : ( w / size ) * size + size;
final int cols = w / size;
final int rows = h / size;
progress = new int[ cols ][ rows ];
for ( int i = 0; i < cols; i++ )
{
for ( int j = 0; j < rows; j++ )
{
progress[ i ][ j ] = 0;
}
}
if ( direction.equals ( Direction.right ) || direction.equals ( Direction.down ) )
{
progress[ 0 ][ 0 ] = speed;
}
else
{
progress[ cols - 1 ][ rows - 1 ] = speed;
}
if ( !fade )
{
clip = getBlocksProgressShape ( progress );
}
if ( type.equals ( BlockType.randomize ) )
{
// Collecting all blocks array
allPoints = new ArrayList ();
for ( int i = 0; i < cols; i++ )
{
for ( int j = 0; j < rows; j++ )
{
allPoints.add ( new Point ( i, j ) );
}
}
// Restarting timer
if ( randomizer != null )
{
randomizer.stop ();
}
randomizer = new WebTimer ( "BlocksTransitionEffect.randomizer", 50 );
randomizer.addActionListener ( new ActionListener ()
{
@Override
public void actionPerformed ( final ActionEvent e )
{
for ( int i = 0; i < blocksAmount; i++ )
{
if ( allPoints.size () > 0 )
{
final int index = MathUtils.random ( allPoints.size () );
final Point toAdd = allPoints.remove ( index );
progress[ toAdd.x ][ toAdd.y ] += speed;
imageTransition.repaint ();
}
else
{
randomizer.stop ();
}
}
}
} );
randomizer.start ();
}
// Updating view
imageTransition.repaint ();
}
@Override
public boolean performAnimation ( final ImageTransition imageTransition )
{
// Incrementing grow states
boolean allMax = true;
final int cols = progress.length;
final int rows = progress[ 0 ].length;
for ( int i = 0; i < cols; i++ )
{
for ( int j = 0; j < rows; j++ )
{
if ( progress[ i ][ j ] < size )
{
if ( progress[ i ][ j ] > 0 )
{
// Was already growing
progress[ i ][ j ] += speed;
}
else
{
if ( type.equals ( BlockType.cascade ) )
{
if ( canStartGrow ( i, j, progress ) )
{
// Starts growing now
progress[ i ][ j ] += speed;
}
}
}
// Check if still not max
if ( allMax && progress[ i ][ j ] < size )
{
allMax = false;
}
}
}
}
// Updating blocks clip
if ( !fade )
{
clip = getBlocksProgressShape ( progress );
}
if ( !allMax )
{
imageTransition.repaint ();
return false;
}
else
{
clip = null;
if ( randomizer != null )
{
randomizer.stop ();
}
return true;
}
}
private Shape getBlocksProgressShape ( final int[][] blocksProgress )
{
final GeneralPath gp = new GeneralPath ( GeneralPath.WIND_EVEN_ODD );
for ( int i = 0; i < blocksProgress.length; i++ )
{
for ( int j = 0; j < blocksProgress[ 0 ].length; j++ )
{
gp.append ( new Rectangle ( i * size, j * size, blocksProgress[ i ][ j ], blocksProgress[ i ][ j ] ), false );
}
}
return gp;
}
private boolean canStartGrow ( final int i, final int j, final int[][] blocksProgress )
{
if ( direction.equals ( Direction.right ) || direction.equals ( Direction.down ) )
{
return i > 0 && blocksProgress[ i - 1 ][ j ] > ( float ) size / 6 ||
j > 0 && blocksProgress[ i ][ j - 1 ] > ( float ) size / 6 ||
i > 1 && blocksProgress[ i - 2 ][ j ] > ( float ) size * 2 / 6 ||
j > 1 && blocksProgress[ i ][ j - 2 ] > ( float ) size * 2 / 6 ||
i > 2 && blocksProgress[ i - 3 ][ j ] > ( float ) size * 3 / 6 ||
j > 2 && blocksProgress[ i ][ j - 3 ] > ( float ) size * 3 / 6 ||
i > 3 && blocksProgress[ i - 4 ][ j ] > ( float ) size * 4 / 6 ||
j > 3 && blocksProgress[ i ][ j - 4 ] > ( float ) size * 4 / 6 ||
i > 4 && blocksProgress[ i - 5 ][ j ] > ( float ) size * 5 / 6 ||
j > 4 && blocksProgress[ i ][ j - 5 ] > ( float ) size * 5 / 6;
}
else
{
return i < blocksProgress.length - 1 && blocksProgress[ i + 1 ][ j ] > ( float ) size / 6 ||
j < blocksProgress[ 0 ].length - 1 && blocksProgress[ i ][ j + 1 ] > ( float ) size / 6 ||
i < blocksProgress.length - 2 && blocksProgress[ i + 2 ][ j ] > ( float ) size * 2 / 6 ||
j < blocksProgress[ 0 ].length - 2 && blocksProgress[ i ][ j + 2 ] > ( float ) size * 2 / 6 ||
i < blocksProgress.length - 3 && blocksProgress[ i + 3 ][ j ] > ( float ) size * 3 / 6 ||
j < blocksProgress[ 0 ].length - 3 && blocksProgress[ i ][ j + 3 ] > ( float ) size * 3 / 6 ||
i < blocksProgress.length - 4 && blocksProgress[ i + 4 ][ j ] > ( float ) size * 4 / 6 ||
j < blocksProgress[ 0 ].length - 4 && blocksProgress[ i ][ j + 4 ] > ( float ) size * 4 / 6 ||
i < blocksProgress.length - 5 && blocksProgress[ i + 5 ][ j ] > ( float ) size * 5 / 6 ||
j < blocksProgress[ 0 ].length - 5 && blocksProgress[ i ][ j + 5 ] > ( float ) size * 5 / 6;
}
}
@Override
public void paint ( final Graphics2D g2d, final ImageTransition transition )
{
// Variables
final int width = transition.getWidth ();
final int height = transition.getHeight ();
// Old image as background
g2d.drawImage ( transition.getCurrentImage (), 0, 0, width, height, null );
// Appearance type
if ( fade )
{
// Drawing separate transparent blocks
final int cols = progress.length;
final int rows = progress[ 0 ].length;
for ( int i = 0; i < cols; i++ )
{
for ( int j = 0; j < rows; j++ )
{
final int block = progress[ i ][ j ];
if ( block > 0 )
{
// Block coordinates
final int dx1 = i * size;
final int dy1 = j * size;
final int w = Math.min ( width - dx1, size );
final int h = Math.min ( height - dy1, size );
final int dx2 = dx1 + w;
final int dy2 = dy1 + h;
// Single image block with custom opacity
final Composite old = GraphicsUtils.setupAlphaComposite ( g2d, ( float ) block / size, block < size );
g2d.drawImage ( transition.getOtherImage (), dx1, dy1, dx2, dy2, dx1, dy1, dx2, dy2, null );
GraphicsUtils.restoreComposite ( g2d, old, block < size );
}
}
}
}
else
{
// New image with decreasing clipped area
final Shape old = GraphicsUtils.intersectClip ( g2d, clip );
g2d.drawImage ( transition.getOtherImage (), 0, 0, width, height, null );
GraphicsUtils.restoreClip ( g2d, old );
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy