/******************************************************************************* * Copyright (c) 2006-2010 Nicolas Richeton. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors : * Nicolas Richeton (nicolas.richeton@gmail.com) - initial API and implementation *******************************************************************************/ package org.eclipse.nebula.animation.effects; import org.eclipse.nebula.animation.movement.IMovement; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; /** * Cross fade images in a target object. The target must implement * {@link IImageObject}. * * @author Nicolas Richeton */ public class CrossFadeEffect extends AbstractEffect { public interface IImageObject { /** * Get the current image of this object * * @return */ Image getImage(); /** * Set the image of this object * * @param c */ void setImage(Image i); } Image buffer = null; double easingValue; GC gc = null; Image image1 = null; Image image2 = null; IImageObject obj = null; /** * Cross fade from image1 to image2 on obj. * * @param obj * @param image1 * @param image2 * @param lengthMilli * @param movement */ public CrossFadeEffect(IImageObject obj, Image image1, Image image2, long lengthMilli, IMovement movement) { this(obj, image1, image2, lengthMilli, movement, null, null); } /** * Cross fade from image1 to image2 on obj. * * @param obj * @param image1 * @param image2 * @param lengthMilli * @param movement * @param onStop */ public CrossFadeEffect(IImageObject obj, Image image1, Image image2, long lengthMilli, IMovement movement, Runnable onStop) { this(obj, image1, image2, lengthMilli, movement, onStop, null); } /** * Cross fade from image1 to image2 on obj. * * @param obj * @param image1 * @param image2 * @param lengthMilli * @param movement * @param onStop * @param onCancel */ public CrossFadeEffect(IImageObject obj, Image image1, Image image2, long lengthMilli, IMovement movement, Runnable onStop, Runnable onCancel) { super(lengthMilli, movement, onStop, onCancel); this.obj = obj; this.image1 = image1; this.image2 = image2; if (!image1.getBounds().equals(image2.getBounds())) { throw new IllegalArgumentException( "Both image must have the same dimensions"); } easingFunction.init(0, 1, (int) lengthMilli); buffer = new Image(image1.getDevice(), image1.getBounds().width, image1 .getBounds().height); gc = new GC(buffer); } /* * (non-Javadoc) * * @see * org.eclipse.nebula.animation.effects.AbstractEffect#applyEffect(long) */ public void applyEffect(long currentTime) { easingValue = easingFunction.getValue(currentTime); if (easingValue == 0) { obj.setImage(image1); } else if (easingValue == 1) { obj.setImage(image2); } else { gc.setAlpha(255); gc.drawImage(image1, 0, 0); gc.setAlpha((int) (255 * easingValue)); gc.drawImage(image2, 0, 0); obj.setImage(buffer); } } /** * Clear resources. */ protected void cleanup() { gc.dispose(); buffer.dispose(); } /* * (non-Javadoc) * * @see org.eclipse.nebula.animation.effects.AbstractEffect#doCancel() */ protected void doCancel() { obj.setImage(image2); super.doCancel(); cleanup(); } /* * (non-Javadoc) * * @see org.eclipse.nebula.animation.effects.AbstractEffect#doStop() */ protected void doStop() { super.doStop(); cleanup(); } }