Tillämpa formanimationer i presentationer med Python

Översikt

För att arbeta med de enskilda beteendena inne i en effekt eller redigera rörelse‑bansegment, se Anpassad animation.

Aspose.Slides för Python via .NET representerar bildanimationer som effekter i en bildtidslinje. En effekt har en målform, en animationstyp och undertyp, en utlösare, tidsinställningar och valfria egenskaper såsom ljud eller beteende efter animationen.

Tidslinjen innehåller två typer av sekvenser:

  • Huvudsekvensen spelas när bilden avancerar.
  • En interaktiv sekvens startar när dess utlösande form klickas.

Eftersom textrutor, bilder, diagram, tabeller och andra bildobjekt implementerar IShape, använder du samma metod Sequence.add_effect för de flesta bildinnehåll. De tillgängliga effekterna listas i uppräkningen EffectType.

Lägg till formanimationer

För att lägga till en animation, hämta bildens huvudsekvens och anropa Sequence.add_effect med målformen, effekttypen, undertypen och utlösaren. För en effekt som startar när en annan form klickas, skapa en interaktiv sekvens vars utlösare är den andra formen.

Följande exempel skapar båda typerna av animation och sparar resultatet till 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)

Utlösaren styr när en effekt startar:

För att animera en bild, ett diagram eller en annan formtyp, skicka det objektet till Sequence.add_effect istället för target_shape. För diagramspecifika grupperingsalternativ, se Animated Charts.

Läs formanimationer

Använd Sequence.get_effects_by_shape när du känner till målformen. För att inspektera varje effekt, iterera genom huvudsekvensen och varje interaktiv sekvens. Iteration undviker antagandet att en sekvens innehåller en effekt på index 0.

Följande exempel skapar en form med huvudsekvens‑ och interaktiva effekter, hämtar de effekter som riktar sig mot formen, och itererar sedan genom varje sekvens på bilden.

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)

Om du bara behöver effekterna för en form, identifiera först formen efter namn, platshållartyp eller en annan stabil egenskap; anropa sedan Sequence.get_effects_by_shape. Anta inte att formen på index 0 alltid är det avsedda objektet.

Arbeta med ärvda platshållareffekter

En platshållare på en normal bild kan ärva animationsegenskaper från motsvarande platshållare på dess layoutbild och mastern. Shape.get_base_placeholder returnerar den föräldraplatshållaren, eller None när ingen förälder finns.

I den följande exempelpresentationen har sidfoten Random Bars på den normala bilden, Split på layoutbilden och Fly In på mastern.

Sidfotens animationseffekt på den normala bilden

Sidfotens platshållareanimationseffekt på layoutbilden

Sidfotens platshållareanimationseffekt på mastern

Det nästa exemplet bygger själva platshållarhierarkin. Det lägger till effekter på en master‑platshållare, en layout‑platshållare och motsvarande platshållare på en normal bild. Varje anrop till Shape.get_base_placeholder kontrolleras innan den returnerade formen används.

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)

Ändra animationstiming

PowerPoint‑dialogen Timing motsvarar egenskaperna i Timing.

PowerPoint‑timingsdialog för en animationseffekt

Detta fristående exempel lägger till en effekt, ändrar dess timing via objektet som returneras av Sequence.add_effect, och sparar resultatet. Att behålla den returnerade Effect‑referensen undviker ett onödigt samlingsindex.

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)

Använd ett repeteringsläge med avsikt. Att kombinera ett repetitionsantal med ett ”until”‑flagga kan ge förvirrande resultat i olika visare. När du ändrar repeteringslägen, sätt Timing.repeat_until_next_click och Timing.repeat_until_end_slide före Timing.repeat_count, eftersom att sätta någon av flaggorna också ändrar det aktiva repeteringsläget.

Lägg till och extrahera animationsljud

En animationseffekt kan referera till inbäddat ljud via Effect.sound. Effect.stop_previous_sound instruerar en effekt att stoppa ljud som startats av en tidigare effekt.

Lägg till ett ljud till en effekt

Följande exempel förväntar en lokal ljudfil med namnet animation-sound.wav. Det skapar två effekter, bäddar in den filen som ljud för den första effekten, och konfigurerar den andra effekten att stoppa ljudet. Det använder objekten som returneras av Sequence.add_effect, så inget sekvensindex behövs.

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)

Extrahera inbäddade effektljud

Följande exempel förväntar en lokal presentation med namnet presentation-with-animation-sounds.pptx. Det skannar både huvud‑ och interaktiva sekvenser och skriver varje inbäddat effektljud till katalogen extracted-animation-sounds. Filändelsen väljs från ljudets MIME‑typ som exponeras av 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)}.")

För stora ljudobjekt, använd Audio.get_stream och kopiera strömmen till en fil i stället för att ladda hela objektet i en byte‑array.

Ställ in beteende efter animation

After animation‑alternativet styr vad som händer med en form efter att dess effekt avslutats.

PowerPoint‑effektalternativdialog som visar inställningar för After animation

AfterAnimationType‑uppräkningen stöder att låta formen förbli oförändrad, ändra dess färg, dölja den efter animationen, eller dölja den vid nästa klick. När typen är AfterAnimationType.COLOR, sätt även Effect.after_animation_color .

Detta fristående exempel skapar en effekt, sätter dess after‑animation‑beteende via den returnerade effekt‑objektet, och sparar resultatet.

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)

Att ändra typen från AfterAnimationType.COLOR rensar inställningen för after‑animation‑färg.

Animera text

Textanimation har två relaterade kontroller:

Följande fristående exempel animera orden i en textruta. BuildType.AS_ONE_OBJECT inaktiverar byggandet stycke för stycke så att ordinställningen gäller för hela textramen.

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)

För att bygga en textruta stycke för stycke, sätt BuildType.BY_LEVEL_PARAGRAPHS1 (eller en annan stycknivå). För att rikta en enskild stycke med egen effekt, använd Sequence.add_effect‑översättningen som accepterar ett IParagraph. Se Animated Text för exempel på stycknivå.

Export‑ och kompatibilitetsnoteringar

  • Att spara till PPT eller PPTX bevarar animationsmodellen, men den slutliga uppspelningen styrs av presentationsvisaren.
  • PDF och statiska bilder spelar inte upp animationer. Använd HTML5 export, animerad GIF eller video conversion när utdata måste visa rörelse.
  • För HTML5, aktivera Html5Options.animate_shapes och, vid behov, Html5Options.animate_transitions .
  • Videorendering stöder många vanliga ingångs‑, betoning‑, utgångs‑ och rörelse‑baneeffekter, men inte varje PowerPoint‑effekt stöds. Kontrollera de aktuella supported animations and effects och testa kritiska presentationer med din målanpassade Aspose.Slides‑version.
  • Avancerade anpassade effekter och effekter som importeras från andra presentationsformat kan bevaras i filen men renderas annorlunda i PowerPoint, HTML5 eller video. Validera det exporterade resultatet snarare än att enbart förlita sig på effektens namn.

FAQ

Varför visas en animation i PowerPoint men inte i en PDF?

PDF är ett statiskt format, så animationer och bildövergångar spelas inte upp. Exportera till HTML5, animerad GIF eller video när rörelse måste bevaras.

Varför spelas en effekt annorlunda i en video?

Videoexport renderar animationer snarare än att lagra det ursprungliga PowerPoint‑beteendet. Vissa avancerade effekter stöds inte eller approximeras. Granska tabellen över stödda effekter och testa den faktiska presentationen innan produktion.

Ändrar flyttning av en form framåt eller bakåt dess animationsordning?

Nej. Formens z‑ordning styr överlappning, medan sekvensordning och utlösare styr animationsuppspelning. Ändra tidslinjen om du behöver en annan uppspelningsordning.