Použijte animace tvarů v prezentacích s Pythonem

Přehled

Chcete-li pracovat s jednotlivými chováními uvnitř efektu nebo upravit segmenty dráhy pohybu, podívejte se na Custom Animation.

Aspose.Slides for Python via .NET reprezentuje animace snímků jako efekty v časové ose snímku. Efekt má cílový tvar, typ animace a podtyp, spouštěč, nastavení načasování a volitelné vlastnosti, jako je zvuk nebo chování po animaci.

Časová osa obsahuje dva typy sekvencí:

  • hlavní sekvence se přehrává při postupu snímku.
  • interaktivní sekvence se spustí, když je kliknuta její spouštěcí forma.

Protože textová pole, obrázky, grafy, tabulky a další objekty snímků implementují rozhraní IShape, používáte stejnou metodu Sequence.add_effect pro většinu obsahu snímku. Dostupné efekty jsou uvedeny v enumeraci EffectType.

Přidání animací tvarů

Chcete-li přidat animaci, získejte hlavní sekvenci snímku a zavolejte Sequence.add_effect s cílovým tvarem, typem efektu, podtypem a spouštěčem. Pro efekt, který se spustí po kliknutí na jiný tvar, vytvořte interaktivní sekvenci, jejímž spouštěčem je ten jiný tvar.

Následující příklad vytvoří oba typy animací a uloží výsledek do shape-animations.pptx.

import aspose.slides as slides


with slides.Presentation() as presentation:
    slide = presentation.slides[0]

    target_shape = slide.shapes.add_auto_shape(slides.ShapeType.ROUND_CORNER_RECTANGLE, 120, 100, 320, 80)
    target_shape.text_frame.text = "Click to animate this shape"

    main_sequence = slide.timeline.main_sequence
    entrance_effect = main_sequence.add_effect(target_shape, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)
    entrance_effect.timing.duration = 1.5

    trigger_shape = slide.shapes.add_auto_shape(slides.ShapeType.BEVEL, 20, 20, 100, 40)
    trigger_shape.text_frame.text = "Move"

    interactive_sequence = slide.timeline.interactive_sequences.add(trigger_shape)
    interactive_sequence.add_effect(target_shape, slides.animation.EffectType.PATH_FOOTBALL, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)

    presentation.save("shape-animations.pptx", slides.export.SaveFormat.PPTX)

Spouštěč určuje, kdy efekt začne:

Chcete-li animovat obrázek, graf nebo jiný typ tvaru, předávejte tento objekt metodě Sequence.add_effect místo target_shape. Pro možnosti seskupení specifické pro grafy viz Animated Charts.

Čtení animací tvarů

Použijte Sequence.get_effects_by_shape, pokud znáte cílový tvar. Pro prohlížení každého efektu procházejte hlavní sekvenci a všechny interaktivní sekvence. Iterace 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 cílící na tento tvar a pak projde všechny sekvence na snímku.

import aspose.slides as slides


def print_sequence(label, sequence):
    print(f"  {label}: {sequence.count} effect(s)")

    for effect in sequence:
        target_name = "unknown" if effect.target_shape is None else effect.target_shape.name
        effect_description = f"{effect.type.name} {effect.subtype.name}; target: {target_name}; trigger: {effect.timing.trigger_type.name}"
        print(f"    {effect_description}")


with slides.Presentation() as presentation:
    slide = presentation.slides[0]
    target_shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 120, 100, 320, 80)
    target_shape.text_frame.text = "Animated shape"

    main_sequence = slide.timeline.main_sequence
    main_sequence.add_effect(target_shape, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)

    trigger_shape = slide.shapes.add_auto_shape(slides.ShapeType.BEVEL, 20, 20, 100, 40)
    trigger_shape.text_frame.text = "Move"

    interactive_sequence = slide.timeline.interactive_sequences.add(trigger_shape)
    interactive_sequence.add_effect(target_shape, slides.animation.EffectType.PATH_FOOTBALL, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)

    target_effects = main_sequence.get_effects_by_shape(target_shape)
    print(f"The main sequence contains {len(target_effects)} effect(s) for {target_shape.name}.")

    print_sequence("Main sequence", main_sequence)

    for interactive_index, sequence in enumerate(slide.timeline.interactive_sequences, start=1):
        trigger_name = "unknown" if sequence.trigger_shape is None else sequence.trigger_shape.name
        sequence_label = f"Interactive sequence {interactive_index}, trigger: {trigger_name}"
        print_sequence(sequence_label, sequence)

Pokud potřebujete efekty jen pro jeden tvar, nejprve identifikujte tvar podle názvu, typu zástupného objektu nebo jiné stabilní vlastnosti; poté zavolejte Sequence.get_effects_by_shape. Nepředpokládejte, že tvar na indexu 0 je vždy požadovaný objekt.

Práce s děděnými efekty zástupných objektů

Zástupný objekt na normálním snímku může zdědit chování animace z odpovídajícího zástupného objektu na rozvržení snímku a hlavním snímku. Shape.get_base_placeholder vrací tento nadřazený zástupný objekt, nebo None, pokud žádný nadřazený neexistuje.

V následující ukázkové prezentaci má zápatí Random Bars na normálním snímku, Split na rozvržení snímku a Fly In na hlavním snímku.

Animace patičky na normálním snímku

Animace zástupného objektu patičky na rozvržení snímku

Animace zástupného objektu patičky na hlavním snímku

Další příklad vytvoří samotnou hierarchii zástupných objektů. Přidá efekty k hlavnímu zástupnému objektu, zástupnému objektu rozvržení a odpovídajícímu zástupnému objektu na normálním snímku. Každé volání Shape.get_base_placeholder je kontrolováno, než je vrácený tvar použit.

import aspose.slides as slides


def find_placeholder_with_base(slide):
    for shape in slide.shapes:
        if shape.get_base_placeholder() is not None:
            return shape

    return None


def print_effects(source, effects):
    print(f"{source}: {len(effects)} effect(s)")

    for effect in effects:
        print(f"  {effect.type.name} {effect.subtype.name}")


with slides.Presentation() as presentation:
    layout_slide = presentation.layout_slides.get_by_type(slides.SlideLayoutType.BLANK)
    layout_placeholder = layout_slide.placeholder_manager.add_text_placeholder(100, 100, 400, 80)
    layout_slide.timeline.main_sequence.add_effect(layout_placeholder, slides.animation.EffectType.SPLIT, slides.animation.EffectSubtype.VERTICAL_IN, slides.animation.EffectTriggerType.ON_CLICK)

    master_placeholder = layout_placeholder.get_base_placeholder()
    if master_placeholder is not None:
        master_sequence = layout_slide.master_slide.timeline.main_sequence
        master_sequence.add_effect(master_placeholder, slides.animation.EffectType.FLY, slides.animation.EffectSubtype.BOTTOM, slides.animation.EffectTriggerType.ON_CLICK)

    slide = presentation.slides.add_empty_slide(layout_slide)
    slide_placeholder = find_placeholder_with_base(slide)

    if slide_placeholder is None:
        raise RuntimeError("The slide does not contain a placeholder linked to its layout slide.")

    slide.timeline.main_sequence.add_effect(slide_placeholder, slides.animation.EffectType.RANDOM_BARS, slides.animation.EffectSubtype.HORIZONTAL, slides.animation.EffectTriggerType.ON_CLICK)
    print_effects("Normal slide", slide.timeline.main_sequence.get_effects_by_shape(slide_placeholder))

    base_layout_placeholder = slide_placeholder.get_base_placeholder()
    if base_layout_placeholder is not None:
        print_effects("Layout slide", layout_slide.timeline.main_sequence.get_effects_by_shape(base_layout_placeholder))

        base_master_placeholder = base_layout_placeholder.get_base_placeholder()
        if base_master_placeholder is not None:
            print_effects("Master slide", layout_slide.master_slide.timeline.main_sequence.get_effects_by_shape(base_master_placeholder))

    presentation.save("placeholder-animations.pptx", slides.export.SaveFormat.PPTX)

Změna načasování animace

Dialog PowerPoint Timing odpovídá vlastnostem třídy Timing.

Dialog PowerPoint Timing pro animační efekt

Tento samostatný příklad přidá efekt, změní jeho načasování pomocí objektu vráceného metodou Sequence.add_effect a uloží výsledek. Uchování vráceného odkazu na Effect zabraňuje zbytečnému indexování kolekce.

import aspose.slides as slides


with slides.Presentation() as presentation:
    slide = presentation.slides[0]
    shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 120, 100, 320, 80)
    shape.text_frame.text = "Timed animation"

    effect = slide.timeline.main_sequence.add_effect(shape, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)
    effect.timing.trigger_type = slides.animation.EffectTriggerType.ON_CLICK
    effect.timing.duration = 2.0
    effect.timing.trigger_delay_time = 0.5
    effect.timing.repeat_until_next_click = False
    effect.timing.repeat_until_end_slide = False
    effect.timing.repeat_count = 2.0
    effect.timing.rewind = True

    presentation.save("shape-animation-timing.pptx", slides.export.SaveFormat.PPTX)

Používejte záměrně jen jeden režim opakování. Kombinace počtu opakování s příznakem „until“ může v různých přehrávačích vést k zmateným výsledkům. Při změně režimu opakování nastavte nejprve Timing.repeat_until_next_click a Timing.repeat_until_end_slide, a až poté Timing.repeat_count, protože nastavení kterékoli z příznaků také mění aktivní režim opakování.

Přidání a extrahování zvuků animace

Animovaný efekt může odkazovat na vložený zvuk prostřednictvím Effect.sound. Effect.stop_previous_sound ří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í zvukový soubor s názvem animation-sound.wav. Vytvoří dva efekty, vloží tento soubor jako zvuk pro první efekt a nakonfiguruje druhý efekt, aby zvuk zastavil. Používá objekty vrácené metodou Sequence.add_effect, takže není potřeba index sekvence.

import aspose.slides as slides


with slides.Presentation() as presentation:
    slide = presentation.slides[0]
    first_shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 80, 100, 240, 80)
    second_shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 400, 100, 240, 80)
    first_shape.text_frame.text = "Starts sound"
    second_shape.text_frame.text = "Stops sound"

    sequence = slide.timeline.main_sequence
    first_effect = sequence.add_effect(first_shape, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)
    second_effect = sequence.add_effect(second_shape, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)

    with open("animation-sound.wav", "rb") as audio_file:
        effect_sound = presentation.audios.add_audio(audio_file.read())

    first_effect.sound = effect_sound
    second_effect.stop_previous_sound = True

    presentation.save("shape-animation-sound.pptx", slides.export.SaveFormat.PPTX)

Extrahování vložených zvuků efektů

Následující příklad očekává lokální prezentaci s názvem 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 se vybírá podle MIME‑typu audia poskytovaného vlastností Audio.content_type.

import os

import aspose.slides as slides


def get_audio_extension(content_type):
    normalized_type = "" if content_type is None else content_type.lower()

    if normalized_type == "audio/mpeg":
        return ".mp3"
    if normalized_type == "audio/mp4":
        return ".m4a"
    if normalized_type == "audio/ogg":
        return ".ogg"
    if normalized_type in ("audio/wav", "audio/x-wav"):
        return ".wav"

    return ".bin"


def save_sounds(sequence, output_directory, sound_index):
    for effect in sequence:
        if effect.sound is None:
            continue

        extension = get_audio_extension(effect.sound.content_type)
        output_path = os.path.join(output_directory, f"effect-sound-{sound_index}{extension}")
        with open(output_path, "wb") as output_file:
            output_file.write(bytes(effect.sound.binary_data))
        sound_index += 1

    return sound_index


input_path = "presentation-with-animation-sounds.pptx"
output_directory = "extracted-animation-sounds"

os.makedirs(output_directory, exist_ok=True)

with slides.Presentation(input_path) as presentation:
    sound_index = 1

    for slide in presentation.slides:
        sound_index = save_sounds(slide.timeline.main_sequence, output_directory, sound_index)

        for sequence in slide.timeline.interactive_sequences:
            sound_index = save_sounds(sequence, output_directory, sound_index)

print(f"Extracted {sound_index - 1} sound file(s) to {os.path.abspath(output_directory)}.")

U velkých audio objektů použijte Audio.get_stream a zkopírujte proud do souboru místo načítání celého objektu do pole bajtů.

Nastavení chování po animaci

Možnost After animation určuje, co se stane s tvarem po dokončení jeho efektu.

Dialog PowerPoint Effect Options zobrazující nastavení After animation

Enumerace 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é Effect.after_animation_color.

Tento samostatný příklad vytvoří efekt, nastaví jeho chování po animaci pomocí vráceného objektu efektu a uloží výsledek.

import aspose.pydrawing as draw
import aspose.slides as slides


with slides.Presentation() as presentation:
    slide = presentation.slides[0]
    shape = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 120, 100, 320, 80)
    shape.text_frame.text = "Dim after animation"

    effect = slide.timeline.main_sequence.add_effect(shape, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)
    effect.after_animation_type = slides.animation.AfterAnimationType.COLOR
    effect.after_animation_color.color = draw.Color.light_gray

    presentation.save("shape-animation-after-effect.pptx", slides.export.SaveFormat.PPTX)

Změna typu od AfterAnimationType.COLOR vymaže nastavení barvy po animaci.

Animovat text

Animace textu má dva související ovladače:

Následující samostatný příklad animuje slova v textovém poli. BuildType.AS_ONE_OBJECT zakáže budování po odstavcích, takže nastavení pro slovo se použije na celý textový rámec.

import aspose.slides as slides


with slides.Presentation() as presentation:
    slide = presentation.slides[0]
    text_box = slide.shapes.add_auto_shape(slides.ShapeType.RECTANGLE, 80, 80, 560, 100)
    text_box.text_frame.text = "Aspose.Slides animates this sentence word by word."

    effect = slide.timeline.main_sequence.add_effect(text_box, slides.animation.EffectType.FADE, slides.animation.EffectSubtype.NONE, slides.animation.EffectTriggerType.ON_CLICK)
    effect.text_animation.build_type = slides.animation.BuildType.AS_ONE_OBJECT
    effect.animate_text_type = slides.animation.AnimateTextType.BY_WORD
    effect.delay_between_text_parts = 20.0

    presentation.save("animated-text.pptx", slides.export.SaveFormat.PPTX)

Pro budování textového pole po odstavcích nastavte BuildType.BY_LEVEL_PARAGRAPHS1 (nebo jinou úroveň odstavce). Chcete-li cílit na jediný odstavec s vlastním efektem, použijte přetížení Sequence.add_effect, které přijímá IParagraph. Viz Animated Text pro příklady na úrovni odstavců.

Export a poznámky o kompatibilitě

  • Ukládání do formátů PPT nebo PPTX zachovává model animací, ale finální přehrávání řídí prohlížeč prezentací.
  • PDF a statické obrázky animace nepřehrávají. Použijte HTML5 export, animovaný GIF nebo video konverzi, když výstup musí zobrazovat pohyb.
  • Pro HTML5 povolte Html5Options.animate_shapes a podle potřeby i Html5Options.animate_transitions.
  • Video rendering podporuje mnoho běžných vstupních, důrazových, výstupních a motion‑path efektů, ale ne každý PowerPoint efekt je podporován. Zkontrolujte aktuální supported animations and effects a otestujte kritické prezentace s vaší cílovou verzí Aspose.Slides.
  • Pokročilé vlastní efekty a efekty importované z jiných formátů mohou být v souboru zachovány, ale v PowerPointu, HTML5 nebo videu se vykreslují odlišně. Ověřte exportovaný výsledek místo spoléhaní se pouze na název efektu.

Často kladené otázky

Proč se animace zobrazuje 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 potřeba zachovat pohyb.

Proč se efekt přehrává odlišně ve videu?

Export do videa vykresluje 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 tabulku podporovaných efektů a otestujte prezentaci před nasazením do výroby.

Mění změna pořadí tvaru dopředu nebo dozadu jeho pořadí animace?

Ne. Z‑order tvaru řídí překrývání, zatímco pořadí sekvence a spouštěče řídí přehrávání animací. Změňte časovou osu, pokud potřebujete jiný pořádek přehrávání.