Použití animací tvarů v prezentacích pomocí Java
Přehled
Pro práci s jednotlivými chováními uvnitř efektu nebo pro úpravu segmentů křivky pohybu viz Custom Animation.
Aspose.Slides for Java představuje animace snímků jako efekty v časové ose snímku. Efekt má cílový tvar, typ a podtyp animace, spouštěč, časová nastavení a volitelné vlastnosti jako zvuk nebo chování po animaci.
Časová osa obsahuje dva typy sekvencí:
- hlavní sekvence přehrává se při postupu snímku.
- interaktivní sekvence se spustí, když je kliknuto na spouštěcí tvar.
Protože textová pole, obrázky, grafy, tabulky a další objekty snímku implementují IShape, používáte stejnou metodu ISequence.addEffect pro většinu obsahu snímku. Dostupné efekty jsou uvedeny ve třídě EffectType.
Přidání animací tvarů
Chcete‑li přidat animaci, získejte hlavní sekvenci snímku a zavolejte ISequence.addEffect s cílovým tvarem, typem efektu, podtypem a spouštěčem. Pro efekt, který začne po kliknutí na jiný tvar, vytvořte interaktivní sekvenci, jejímž spouštěčem je tento jiný tvar.
Následující příklad vytvoří oba typy animací a uloží výsledek do souboru shape-animations.pptx.
import com.aspose.slides.*;
public class AddShapeAnimations {
public static void main(String[] args) {
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape targetShape = slide.getShapes().addAutoShape(ShapeType.RoundCornerRectangle, 120, 100, 320, 80);
targetShape.addTextFrame("Click to animate this shape");
ISequence mainSequence = slide.getTimeline().getMainSequence();
IEffect entranceEffect = mainSequence.addEffect(targetShape, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
entranceEffect.getTiming().setDuration(1.5f);
IAutoShape triggerShape = slide.getShapes().addAutoShape(ShapeType.Bevel, 20, 20, 100, 40);
triggerShape.addTextFrame("Move");
ISequence interactiveSequence = slide.getTimeline().getInteractiveSequences().add(triggerShape);
interactiveSequence.addEffect(targetShape, EffectType.PathFootball, EffectSubtype.None, EffectTriggerType.OnClick);
presentation.save("shape-animations.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
}
}
Spouštěč určuje, kdy efekt začne:
- EffectTriggerType.OnClick čeká na kliknutí v hlavní sekvenci nebo na kliknutí na spouštěcí tvar v interaktivní sekvenci.
- EffectTriggerType.WithPrevious startuje současně s předchozím efektem.
- EffectTriggerType.AfterPrevious startuje po dokončení předchozího efektu.
Chcete‑li animovat obrázek, graf nebo jiný typ tvaru, předávejte tento objekt metodě ISequence.addEffect místo targetShape. Pro možnosti seskupování specifické pro grafy viz Animated Charts.
Čtení animací tvarů
Použijte ISequence.getEffectsByShape, pokud znáte cílový tvar. Pro prozkoumání všech efektů projděte hlavní sekvenci i všechny interaktivní sekvence. Enumerace zabraňuje předpokladu, že sekvence obsahuje efekt na indexu 0.
Následující příklad vytvoří tvar s hlavními a interaktivními efekty, získá efekty, které cílí na tento tvar, a poté projde všechny sekvence na snímku.
import com.aspose.slides.*;
public class ReadShapeAnimations {
public static void main(String[] args) {
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape targetShape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 120, 100, 320, 80);
targetShape.addTextFrame("Animated shape");
ISequence mainSequence = slide.getTimeline().getMainSequence();
mainSequence.addEffect(targetShape, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
IAutoShape triggerShape = slide.getShapes().addAutoShape(ShapeType.Bevel, 20, 20, 100, 40);
triggerShape.addTextFrame("Move");
ISequence interactiveSequence = slide.getTimeline().getInteractiveSequences().add(triggerShape);
interactiveSequence.addEffect(targetShape, EffectType.PathFootball, EffectSubtype.None, EffectTriggerType.OnClick);
IEffect[] targetEffects = mainSequence.getEffectsByShape(targetShape);
System.out.println("The main sequence contains " + targetEffects.length + " effect(s) for " + targetShape.getName() + ".");
printSequence("Main sequence", mainSequence);
int interactiveIndex = 1;
for (ISequence sequence : slide.getTimeline().getInteractiveSequences()) {
String triggerName = sequence.getTriggerShape() == null ? "unknown" : sequence.getTriggerShape().getName();
String sequenceLabel = "Interactive sequence " + interactiveIndex + ", trigger: " + triggerName;
printSequence(sequenceLabel, sequence);
interactiveIndex++;
}
} finally {
presentation.dispose();
}
}
private static void printSequence(String label, ISequence sequence) {
System.out.println(" " + label + ": " + sequence.getCount() + " effect(s)");
for (IEffect effect : sequence) {
String targetName = effect.getTargetShape() == null ? "unknown" : effect.getTargetShape().getName();
String typeName = EffectType.getName(EffectType.class, effect.getType());
String subtypeName = EffectSubtype.getName(EffectSubtype.class, effect.getSubtype());
String triggerName = EffectTriggerType.getName(EffectTriggerType.class, effect.getTiming().getTriggerType());
String effectDescription = typeName + " " + subtypeName + "; target: " + targetName + "; trigger: " + triggerName;
System.out.println(" " + effectDescription);
}
}
}
Pokud potřebujete efekty jen pro jeden tvar, nejprve identifikujte tvar podle názvu, typu zástupného symbolu nebo jiné stabilní vlastnosti; pak zavolejte ISequence.getEffectsByShape. Nepředpokládejte, že IShapeCollection.get_Item na indexu 0 je vždy požadovaný objekt.
Práce s děděnými efekty zástupných symbolů
Zástupný symbol na běžném snímku může dědit chování animace od odpovídajícího zástupného symbolu na rozložení snímku a hlavní šabloně. IShape.getBasePlaceholder vrací tento nadřazený zástupný symbol, nebo null, pokud neexistuje.
V následující ukázkové prezentaci má zápatí Random Bars na běžném snímku, Split na snímku rozložení a Fly In na hlavní šabloně.



Další příklad používá hierarchii zástupných symbolů z nové prezentace. Přidává efekty k hlavnímu zástupnému symbolu, k symbolu rozložení a k odpovídajícímu symbolu na běžném snímku. Každé volání IShape.getBasePlaceholder je před použitím vráceného tvaru zkontrolováno.
import com.aspose.slides.*;
public class InheritedPlaceholderAnimations {
public static void main(String[] args) {
Presentation presentation = new Presentation();
try {
ILayoutSlide layoutSlide = presentation.getLayoutSlides().getByType(SlideLayoutType.TitleAndObject);
IShape layoutPlaceholder = findPlaceholderWithBase(layoutSlide);
if (layoutPlaceholder == null) {
throw new IllegalStateException("The layout slide does not contain a placeholder linked to its master slide.");
}
IShape masterPlaceholder = layoutPlaceholder.getBasePlaceholder();
layoutSlide.getMasterSlide().getTimeline().getMainSequence().addEffect(masterPlaceholder, EffectType.Fly, EffectSubtype.Bottom, EffectTriggerType.OnClick);
layoutSlide.getTimeline().getMainSequence().addEffect(layoutPlaceholder, EffectType.Split, EffectSubtype.VerticalIn, EffectTriggerType.OnClick);
ISlide slide = presentation.getSlides().addEmptySlide(layoutSlide);
IShape slidePlaceholder = findPlaceholderWithBase(slide, layoutPlaceholder);
if (slidePlaceholder == null) {
throw new IllegalStateException("The slide does not contain a placeholder linked to its layout slide.");
}
slide.getTimeline().getMainSequence().addEffect(slidePlaceholder, EffectType.RandomBars, EffectSubtype.Horizontal, EffectTriggerType.OnClick);
printEffects("Normal slide", slide.getTimeline().getMainSequence().getEffectsByShape(slidePlaceholder));
IShape baseLayoutPlaceholder = slidePlaceholder.getBasePlaceholder();
if (baseLayoutPlaceholder != null) {
printEffects("Layout slide", layoutSlide.getTimeline().getMainSequence().getEffectsByShape(baseLayoutPlaceholder));
IShape baseMasterPlaceholder = baseLayoutPlaceholder.getBasePlaceholder();
if (baseMasterPlaceholder != null) {
printEffects("Master slide", layoutSlide.getMasterSlide().getTimeline().getMainSequence().getEffectsByShape(baseMasterPlaceholder));
}
}
presentation.save("placeholder-animations.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
}
private static IShape findPlaceholderWithBase(ILayoutSlide layoutSlide) {
for (IShape shape : layoutSlide.getShapes()) {
if (shape.getBasePlaceholder() != null) {
return shape;
}
}
return null;
}
private static IShape findPlaceholderWithBase(ISlide slide, IShape expectedBase) {
for (IShape shape : slide.getShapes()) {
if (shape.getBasePlaceholder() == expectedBase) {
return shape;
}
}
return null;
}
private static void printEffects(String source, IEffect[] effects) {
System.out.println(source + ": " + effects.length + " effect(s)");
for (IEffect effect : effects) {
String typeName = EffectType.getName(EffectType.class, effect.getType());
String subtypeName = EffectSubtype.getName(EffectSubtype.class, effect.getSubtype());
System.out.println(" " + typeName + " " + subtypeName);
}
}
}
Změna časování animace
Dialog PowerPoint Timing odpovídá vlastnostem rozhraní ITiming.

- Start odpovídá metodě ITiming.getTriggerType.
- Duration odpovídá metodě ITiming.getDuration, v sekundách.
- Delay odpovídá metodě ITiming.getTriggerDelayTime, v sekundách.
- Repeat odpovídá metodám ITiming.getRepeatCount, ITiming.getRepeatUntilNextClick, nebo ITiming.getRepeatUntilEndSlide.
- Rewind when done playing odpovídá metodě ITiming.getRewind.
Tento samostatný příklad přidá efekt, změní jeho časování pomocí objektu vráceného metodou ISequence.addEffect, a výsledek uloží. Uložení reference na vrácený objekt IEffect zabraňuje zbytečnému indexování kolekce.
import com.aspose.slides.*;
public class ChangeAnimationTiming {
public static void main(String[] args) {
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 120, 100, 320, 80);
shape.addTextFrame("Timed animation");
IEffect effect = slide.getTimeline().getMainSequence().addEffect(shape, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
effect.getTiming().setTriggerType(EffectTriggerType.OnClick);
effect.getTiming().setDuration(2.0f);
effect.getTiming().setTriggerDelayTime(0.5f);
effect.getTiming().setRepeatUntilNextClick(false);
effect.getTiming().setRepeatUntilEndSlide(false);
effect.getTiming().setRepeatCount(2.0f);
effect.getTiming().setRewind(true);
presentation.save("shape-animation-timing.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
}
}
Používejte jen jeden režim opakování. Kombinace počtu opakování s příznakem „until“ může vést k nejasným výsledkům v různých prohlížečích. Při změně režimů opakování nejprve nastavte ITiming.setRepeatUntilNextClick a ITiming.setRepeatUntilEndSlide, teprve poté ITiming.setRepeatCount, protože nastavení některého z příznaků také mění aktivní režim opakování.
Přidání a extrakce zvuků animací
Efekt animace může odkazovat na vložený zvuk pomocí IEffect.getSound. IEffect.setStopPreviousSound říká efektu, aby zastavil zvuk zahájený předchozím efektem.
Přidání zvuku k efektu
Následující příklad očekává lokální audio soubor pojmenovaný animation-sound.wav. Vytvoří dva efekty, vloží tento soubor jako zvuk pro první efekt a nastaví druhý efekt tak, aby zvuk zastavil. Používá objekty vrácené metodou ISequence.addEffect, takže není potřeba zadávat index sekvence.
import com.aspose.slides.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class AddAnimationSound {
public static void main(String[] args) throws IOException {
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape firstShape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 80, 100, 240, 80);
IAutoShape secondShape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 400, 100, 240, 80);
firstShape.addTextFrame("Starts sound");
secondShape.addTextFrame("Stops sound");
ISequence sequence = slide.getTimeline().getMainSequence();
IEffect firstEffect = sequence.addEffect(firstShape, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
IEffect secondEffect = sequence.addEffect(secondShape, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
byte[] audioData = Files.readAllBytes(Paths.get("animation-sound.wav"));
IAudio effectSound = presentation.getAudios().addAudio(audioData);
firstEffect.setSound(effectSound);
secondEffect.setStopPreviousSound(true);
presentation.save("shape-animation-sound.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
}
}
Extrahování vložených zvuků efektů
Následující příklad očekává lokální prezentaci pojmenovanou presentation-with-animation-sounds.pptx. Prohledá hlavní i interaktivní sekvence a zapíše každý vložený zvuk efektu do adresáře extracted-animation-sounds. Přípona je vybrána podle MIME‑type zvuku, který vrací IAudio.getContentType.
import com.aspose.slides.*;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Locale;
public class ExtractAnimationSounds {
public static void main(String[] args) throws IOException {
Path inputPath = Paths.get("presentation-with-animation-sounds.pptx");
Path outputDirectory = Paths.get("extracted-animation-sounds");
Files.createDirectories(outputDirectory);
Presentation presentation = new Presentation(inputPath.toString());
try {
int soundIndex = 1;
for (ISlide slide : presentation.getSlides()) {
soundIndex = saveSounds(slide.getTimeline().getMainSequence(), outputDirectory, soundIndex);
for (ISequence sequence : slide.getTimeline().getInteractiveSequences()) {
soundIndex = saveSounds(sequence, outputDirectory, soundIndex);
}
}
System.out.println("Extracted " + (soundIndex - 1) + " sound file(s) to " + outputDirectory.toAbsolutePath() + ".");
} finally {
presentation.dispose();
}
}
private static int saveSounds(ISequence sequence, Path outputDirectory, int soundIndex) throws IOException {
for (IEffect effect : sequence) {
if (effect.getSound() == null) {
continue;
}
String extension = getAudioExtension(effect.getSound().getContentType());
Path outputPath = outputDirectory.resolve("effect-sound-" + soundIndex + extension);
Files.write(outputPath, effect.getSound().getBinaryData());
soundIndex++;
}
return soundIndex;
}
private static String getAudioExtension(String contentType) {
String normalizedType = contentType == null ? "" : contentType.toLowerCase(Locale.ROOT);
if (normalizedType.equals("audio/mpeg")) {
return ".mp3";
}
if (normalizedType.equals("audio/mp4")) {
return ".m4a";
}
if (normalizedType.equals("audio/ogg")) {
return ".ogg";
}
if (normalizedType.equals("audio/wav") || normalizedType.equals("audio/x-wav")) {
return ".wav";
}
return ".bin";
}
}
U velkých audio objektů použijte IAudio.getStream a zkopírujte proud do souboru místo načítání celého objektu do pole bytů.
Nastavení chování po animaci
Volba After animation určuje, co se stane s tvarem po dokončení jeho efektu.

Třída AfterAnimationType podporuje ponechání tvaru beze změny, změnu jeho barvy, skrytí po animaci nebo skrytí při dalším kliknutí. Když je typ AfterAnimationType.Color, nastavte také IEffect.getAfterAnimationColor.
Tento samostatný příklad vytvoří efekt, nastaví jeho chování po animaci pomocí vráceného objektu efektu a výsledek uloží.
import com.aspose.slides.*;
import java.awt.Color;
public class SetAfterAnimationBehavior {
public static void main(String[] args) {
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 120, 100, 320, 80);
shape.addTextFrame("Dim after animation");
IEffect effect = slide.getTimeline().getMainSequence().addEffect(shape, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
effect.setAfterAnimationType(AfterAnimationType.Color);
effect.getAfterAnimationColor().setColor(Color.LIGHT_GRAY);
presentation.save("shape-animation-after-effect.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
}
}
Změna typu z AfterAnimationType.Color vymaže nastavení barvy po animaci.
Animace textu
Animace textu má dva související ovladače:
- ITextAnimation.getBuildType určuje, zda se odstavce zobrazují najednou nebo po úrovních odstavců.
- IEffect.getAnimateTextType určuje, zda se text zobrazuje najednou, po slovech či po znacích. IEffect.getDelayBetweenTextParts nastavuje prodlevu mezi slovy nebo znaky. Kladná hodnota je procento trvání efektu; záporná hodnota je prodleva v sekundách.
Následující samostatný příklad animuje slova v textovém poli. BuildType.AsOneObject vypne budování po odstavcích, takže nastavení pro slova se použije na celý textový rámec.
import com.aspose.slides.*;
public class AnimateTextByWord {
public static void main(String[] args) {
Presentation presentation = new Presentation();
try {
ISlide slide = presentation.getSlides().get_Item(0);
IAutoShape textBox = slide.getShapes().addAutoShape(ShapeType.Rectangle, 80, 80, 560, 100);
textBox.addTextFrame("Aspose.Slides animates this sentence word by word.");
IEffect effect = slide.getTimeline().getMainSequence().addEffect(textBox, EffectType.Fade, EffectSubtype.None, EffectTriggerType.OnClick);
effect.getTextAnimation().setBuildType(BuildType.AsOneObject);
effect.setAnimateTextType(AnimateTextType.ByWord);
effect.setDelayBetweenTextParts(20.0f);
presentation.save("animated-text.pptx", SaveFormat.Pptx);
} finally {
presentation.dispose();
}
}
}
Pro budování textového pole po odstavcích nastavte BuildType.ByLevelParagraphs1 (nebo jinou úroveň odstavce). Chcete‑li cílit na jediný odstavec s vlastním efektem, použijte přetížení ISequence.addEffect přijímající IParagraph. Viz Animated Text pro příklady na úrovni odstavců.
Export a poznámky o kompatibilitě
- Ukládání do PPT nebo PPTX zachovává model animace, ale finální přehrávání řídí prohlížeč prezentace.
- PDF a statické obrázky animace nepřehrávají. Použijte HTML5 export, animovaný GIF nebo konverzi videa, když výstup musí zobrazovat pohyb.
- Pro HTML5 povolte Html5Options.setAnimateShapes a podle potřeby i Html5Options.setAnimateTransitions.
- Renderování videa podporuje mnoho běžných vstupních, důrazových, výstupních a křivek pohybu efektů, ale ne každý efekt PowerPointu je podporován. Zkontrolujte aktuální supported animations and effects a otestujte kritické prezentace s verzí Aspose.Slides, kterou používáte.
- Pokročilé vlastní efekty a efekty importované z jiných formátů mohou být v souboru zachovány, ale ve PowerPointu, HTML5 nebo videu se mohou vykreslovat odlišně. Ověřte exportovaný výsledek místo spoléhání se jen na název efektu.
Často kladené dotazy
Proč se animace zobrazí v PowerPointu, ale ne v PDF?
PDF je statický formát, takže animace a přechody snímků se nepřehrávají. Exportujte do HTML5, animovaného GIFu nebo videa, pokud je nutný pohyb.
Proč se efekt v videu přehrává odlišně?
Export videa renderuje animace místo uložení původního chování PowerPointu. Některé pokročilé efekty nejsou podporovány nebo jsou aproximovány. Prohlédněte si tabulku podporovaných efektů a otestujte skutečnou prezentaci před produkčním nasazením.
Mění posunutí tvaru dopředu nebo dozadu jeho pořadí animace?
Ne. Z‑order tvaru určuje překrývání, zatímco pořadí sekvence a spouštěče řídí přehrávání animací. Pokud potřebujete jiné pořadí přehrávání, změňte časovou osu.