Применение анимации фигур в презентациях с использованием C++
Обзор
Чтобы работать с отдельными поведениями внутри эффекта или редактировать сегменты траекторий движения, см. Custom Animation.
Aspose.Slides for C++ представляет анимацию слайдов в виде эффектов на временной шкале слайда. Эффект имеет целевую форму, тип и подтип анимации, триггер, настройки тайминга и необязательные свойства, такие как звук или поведение после анимации.
Временная шкала содержит два типа последовательностей:
- главная последовательность воспроизводится при переходе к слайду.
- интерактивная последовательность начинается, когда форма‑триггер нажата.
Поскольку текстовые блоки, изображения, диаграммы, таблицы и другие объекты слайда реализуют IShape, вы используете тот же метод ISequence::AddEffect для большинства содержимого слайда. Доступные эффекты перечислены в перечислении EffectType.
Добавление анимаций фигур
Чтобы добавить анимацию, получите главную последовательность слайда и вызовите ISequence::AddEffect с целевой формой, типом эффекта, подтипом и триггером. Для эффекта, который начинается при щелчке по другой форме, создайте интерактивную последовательность, триггером которой будет эта другая форма.
Следующий пример создает оба типа анимации и сохраняет результат в shape-animations.pptx.
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/Animation/ISequenceCollection.h>
#include <DOM/Animation/ITiming.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAutoShape.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/ITextFrame.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto targetShape = slide->get_Shapes()->AddAutoShape(ShapeType::RoundCornerRectangle, 120.0f, 100.0f, 320.0f, 80.0f);
targetShape->get_TextFrame()->set_Text(u"Click to animate this shape");
auto mainSequence = slide->get_Timeline()->get_MainSequence();
auto entranceEffect = mainSequence->AddEffect(targetShape, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
entranceEffect->get_Timing()->set_Duration(1.5f);
auto triggerShape = slide->get_Shapes()->AddAutoShape(ShapeType::Bevel, 20.0f, 20.0f, 100.0f, 40.0f);
triggerShape->get_TextFrame()->set_Text(u"Move");
auto interactiveSequence = slide->get_Timeline()->get_InteractiveSequences()->Add(triggerShape);
interactiveSequence->AddEffect(targetShape, EffectType::PathFootball, EffectSubtype::None, EffectTriggerType::OnClick);
presentation->Save(u"shape-animations.pptx", SaveFormat::Pptx);
presentation->Dispose();
Триггер определяет, когда эффект начинается:
- EffectTriggerType::OnClick ожидает щелчка в главной последовательности или щелчка по форме‑триггеру в интерактивной последовательности.
- EffectTriggerType::WithPrevious начинается одновременно с предыдущим эффектом.
- EffectTriggerType::AfterPrevious начинается после завершения предыдущего эффекта.
Чтобы анимировать изображение, диаграмму или другой тип формы, передайте соответствующий объект в ISequence::AddEffect вместо targetShape. Для параметров группировки, специфичных для диаграмм, см. Animated Charts.
Чтение анимаций фигур
Используйте ISequence::GetEffectsByShape когда известна целевая форма. Чтобы просмотреть каждый эффект, перечислите главную последовательность и все интерактивные последовательности. Перебор избавляет от предположения, что в последовательности есть эффект с индексом 0.
Следующий пример создает форму с эффектами главной и интерактивной последовательностей, получает эффекты, направленные на форму, а затем перечисляет каждую последовательность на слайде.
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/Animation/ISequenceCollection.h>
#include <DOM/Animation/ITiming.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAutoShape.h>
#include <DOM/IShape.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/ITextFrame.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <system/console.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace System;
auto printSequence = [](const String& label, const SharedPtr<ISequence>& sequence)
{
Console::WriteLine(String::Format(u" {0}: {1} effect(s)", label, sequence->get_Count()));
for (const auto& effect : sequence)
{
auto targetName = effect->get_TargetShape() == nullptr ? u"unknown" : effect->get_TargetShape()->get_Name();
auto effectDescription = String::Format(u"{0} {1}; target: {2}; trigger: {3}", effect->get_Type(), effect->get_Subtype(), targetName, effect->get_Timing()->get_TriggerType());
Console::WriteLine(u" " + effectDescription);
}
};
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto targetShape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 120.0f, 100.0f, 320.0f, 80.0f);
targetShape->get_TextFrame()->set_Text(u"Animated shape");
auto mainSequence = slide->get_Timeline()->get_MainSequence();
mainSequence->AddEffect(targetShape, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
auto triggerShape = slide->get_Shapes()->AddAutoShape(ShapeType::Bevel, 20.0f, 20.0f, 100.0f, 40.0f);
triggerShape->get_TextFrame()->set_Text(u"Move");
auto interactiveSequence = slide->get_Timeline()->get_InteractiveSequences()->Add(triggerShape);
interactiveSequence->AddEffect(targetShape, EffectType::PathFootball, EffectSubtype::None, EffectTriggerType::OnClick);
auto targetEffects = mainSequence->GetEffectsByShape(targetShape);
Console::WriteLine(String::Format(u"The main sequence contains {0} effect(s) for {1}.", targetEffects->get_Length(), targetShape->get_Name()));
printSequence(u"Main sequence", mainSequence);
int32_t interactiveIndex = 1;
for (const auto& sequence : slide->get_Timeline()->get_InteractiveSequences())
{
auto triggerName = sequence->get_TriggerShape() == nullptr ? u"unknown" : sequence->get_TriggerShape()->get_Name();
auto sequenceLabel = String::Format(u"Interactive sequence {0}, trigger: {1}", interactiveIndex, triggerName);
printSequence(sequenceLabel, sequence);
interactiveIndex++;
}
presentation->Dispose();
Если нужны эффекты только для одной формы, сначала определите форму по имени, типу заполнителя или другому стабильному свойству; затем вызовите ISequence::GetEffectsByShape. Не полагайтесь на то, что IShapeCollection::idx_get с индексом 0 всегда возвращает нужный объект.
Работа с наследуемыми эффектами заполнителей
Заполнитель на обычном слайде может наследовать поведение анимации от соответствующего заполнителя на слайде‑макете и слайде‑шаблоне. IShape::GetBasePlaceholder возвращает родительский заполнитель или nullptr, если родитель не существует.
В приведенной ниже демонстрации футер имеет Random Bars на обычном слайде, Split на слайде‑макете и Fly In на слайде‑шаблоне.



Следующий пример создает иерархию заполнителей. Он добавляет эффекты к заполнителю шаблона, заполнителю макета и соответствующему заполнителю на обычном слайде. Каждый вызов IShape::GetBasePlaceholder проверяется до использования возвращенной формы.
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAutoShape.h>
#include <DOM/IGlobalLayoutSlideCollection.h>
#include <DOM/ILayoutPlaceholderManager.h>
#include <DOM/ILayoutSlide.h>
#include <DOM/IMasterSlide.h>
#include <DOM/IShape.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/Presentation.h>
#include <DOM/SlideLayoutType.h>
#include <Export/SaveFormat.h>
#include <system/array.h>
#include <system/console.h>
#include <system/exceptions.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace Aspose::Slides::Export;
using namespace System;
auto findPlaceholderWithBase = [](const SharedPtr<ISlide>& slide) -> SharedPtr<IShape>
{
for (const auto& shape : slide->get_Shapes())
{
if (shape->GetBasePlaceholder() != nullptr)
return shape;
}
return nullptr;
};
auto printEffects = [](const String& source, const ArrayPtr<SharedPtr<IEffect>>& effects)
{
Console::WriteLine(String::Format(u"{0}: {1} effect(s)", source, effects->get_Length()));
for (const auto& effect : effects)
Console::WriteLine(String::Format(u" {0} {1}", effect->get_Type(), effect->get_Subtype()));
};
auto presentation = MakeObject<Presentation>();
auto layoutSlide = presentation->get_LayoutSlides()->GetByType(SlideLayoutType::Blank);
auto layoutPlaceholder = layoutSlide->get_PlaceholderManager()->AddTextPlaceholder(100.0f, 100.0f, 400.0f, 80.0f);
layoutSlide->get_Timeline()->get_MainSequence()->AddEffect(layoutPlaceholder, EffectType::Split, EffectSubtype::VerticalIn, EffectTriggerType::OnClick);
auto masterPlaceholder = layoutPlaceholder->GetBasePlaceholder();
if (masterPlaceholder != nullptr)
{
auto masterSequence = layoutSlide->get_MasterSlide()->get_Timeline()->get_MainSequence();
masterSequence->AddEffect(masterPlaceholder, EffectType::Fly, EffectSubtype::Bottom, EffectTriggerType::OnClick);
}
auto slide = presentation->get_Slides()->AddEmptySlide(layoutSlide);
auto slidePlaceholder = findPlaceholderWithBase(slide);
if (slidePlaceholder == nullptr)
throw InvalidOperationException(u"The slide does not contain a placeholder linked to its layout slide.");
slide->get_Timeline()->get_MainSequence()->AddEffect(slidePlaceholder, EffectType::RandomBars, EffectSubtype::Horizontal, EffectTriggerType::OnClick);
printEffects(u"Normal slide", slide->get_Timeline()->get_MainSequence()->GetEffectsByShape(slidePlaceholder));
auto baseLayoutPlaceholder = slidePlaceholder->GetBasePlaceholder();
if (baseLayoutPlaceholder != nullptr)
{
printEffects(u"Layout slide", layoutSlide->get_Timeline()->get_MainSequence()->GetEffectsByShape(baseLayoutPlaceholder));
auto baseMasterPlaceholder = baseLayoutPlaceholder->GetBasePlaceholder();
if (baseMasterPlaceholder != nullptr)
printEffects(u"Master slide", layoutSlide->get_MasterSlide()->get_Timeline()->get_MainSequence()->GetEffectsByShape(baseMasterPlaceholder));
}
presentation->Save(u"placeholder-animations.pptx", SaveFormat::Pptx);
presentation->Dispose();
Изменение тайминга анимации
Диалог PowerPoint Timing соответствует методам ITiming.

- Start соответствует ITiming::set_TriggerType.
- Duration соответствует ITiming::set_Duration, в секундах.
- Delay соответствует ITiming::set_TriggerDelayTime, в секундах.
- Repeat соответствует ITiming::set_RepeatCount, ITiming::set_RepeatUntilNextClick, или ITiming::set_RepeatUntilEndSlide.
- Rewind when done playing соответствует ITiming::set_Rewind.
Этот независимый пример добавляет эффект, изменяет его тайминг через объект, возвращённый ISequence::AddEffect, и сохраняет результат. Сохранение ссылки на возвращённый IEffect избавляет от необходимости использовать индекс коллекции.
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/Animation/ITiming.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAutoShape.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/ITextFrame.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 120.0f, 100.0f, 320.0f, 80.0f);
shape->get_TextFrame()->set_Text(u"Timed animation");
auto effect = slide->get_Timeline()->get_MainSequence()->AddEffect(shape, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
effect->get_Timing()->set_TriggerType(EffectTriggerType::OnClick);
effect->get_Timing()->set_Duration(2.0f);
effect->get_Timing()->set_TriggerDelayTime(0.5f);
effect->get_Timing()->set_RepeatUntilNextClick(false);
effect->get_Timing()->set_RepeatUntilEndSlide(false);
effect->get_Timing()->set_RepeatCount(2.0f);
effect->get_Timing()->set_Rewind(true);
presentation->Save(u"shape-animation-timing.pptx", SaveFormat::Pptx);
presentation->Dispose();
Используйте один режим повторения намеренно. Сочетание количества повторов с флагом «until» может приводить к запутанным результатам в разных просмотрщиках. При изменении режимов повторения вызывайте ITiming::set_RepeatUntilNextClick и ITiming::set_RepeatUntilEndSlide перед ITiming::set_RepeatCount, так как установка любого из флагов также меняет активный режим повторения.
Добавление и извлечение звуков анимации
Эффект анимации может ссылаться на встроенный аудиофайл через IEffect::set_Sound. IEffect::set_StopPreviousSound указывает эффекту остановить звук, начатый предыдущим эффектом.
Добавление звука к эффекту
Следующий пример ожидает локальный аудиофайл с именем animation-sound.wav. Он создаёт два эффекта, встраивает этот файл как звук первого эффекта и настраивает второй эффект на остановку звука. Для этого используются объекты, возвращённые ISequence::AddEffect, поэтому индекс последовательности не требуется.
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAudio.h>
#include <DOM/IAudioCollection.h>
#include <DOM/IAutoShape.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/ITextFrame.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <system/io/file.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::IO;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto firstShape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 80.0f, 100.0f, 240.0f, 80.0f);
auto secondShape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 400.0f, 100.0f, 240.0f, 80.0f);
firstShape->get_TextFrame()->set_Text(u"Starts sound");
secondShape->get_TextFrame()->set_Text(u"Stops sound");
auto sequence = slide->get_Timeline()->get_MainSequence();
auto firstEffect = sequence->AddEffect(firstShape, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
auto secondEffect = sequence->AddEffect(secondShape, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
auto audioData = File::ReadAllBytes(u"animation-sound.wav");
auto effectSound = presentation->get_Audios()->AddAudio(audioData);
firstEffect->set_Sound(effectSound);
secondEffect->set_StopPreviousSound(true);
presentation->Save(u"shape-animation-sound.pptx", SaveFormat::Pptx);
presentation->Dispose();
Извлечение встроенных звуков эффектов
Следующий пример ожидает локальную презентацию с именем presentation-with-animation-sounds.pptx. Он сканирует как главные, так и интерактивные последовательности и записывает каждый встроенный звук эффекта в каталог extracted-animation-sounds. Расширение выбирается по MIME‑типу аудио, полученному через IAudio::get_ContentType.
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/Animation/ISequenceCollection.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAudio.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/Presentation.h>
#include <system/console.h>
#include <system/io/directory.h>
#include <system/io/file.h>
#include <system/io/path.h>
#include <system/string.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace System;
using namespace System::IO;
auto getAudioExtension = [](const String& contentType)
{
auto normalizedType = String::IsNullOrEmpty(contentType) ? String::Empty : contentType.ToLowerInvariant();
if (normalizedType == u"audio/mpeg")
return String(u".mp3");
if (normalizedType == u"audio/mp4")
return String(u".m4a");
if (normalizedType == u"audio/ogg")
return String(u".ogg");
if (normalizedType == u"audio/wav" || normalizedType == u"audio/x-wav")
return String(u".wav");
return String(u".bin");
};
auto saveSounds = [&getAudioExtension](const SharedPtr<ISequence>& sequence, const String& outputDirectory, int32_t& soundIndex)
{
for (const auto& effect : sequence)
{
if (effect->get_Sound() == nullptr)
continue;
auto extension = getAudioExtension(effect->get_Sound()->get_ContentType());
auto outputPath = Path::Combine(outputDirectory, String::Format(u"effect-sound-{0}{1}", soundIndex, extension));
File::WriteAllBytes(outputPath, effect->get_Sound()->get_BinaryData());
soundIndex++;
}
};
auto inputPath = String(u"presentation-with-animation-sounds.pptx");
auto outputDirectory = String(u"extracted-animation-sounds");
Directory::CreateDirectory_(outputDirectory);
auto presentation = MakeObject<Presentation>(inputPath);
int32_t soundIndex = 1;
for (const auto& slide : presentation->get_Slides())
{
saveSounds(slide->get_Timeline()->get_MainSequence(), outputDirectory, soundIndex);
for (const auto& sequence : slide->get_Timeline()->get_InteractiveSequences())
saveSounds(sequence, outputDirectory, soundIndex);
}
Console::WriteLine(String::Format(u"Extracted {0} sound file(s) to {1}.", soundIndex - 1, Path::GetFullPath(outputDirectory)));
presentation->Dispose();
Для больших аудио‑объектов используйте IAudio::GetStream и копируйте поток в файл вместо загрузки всего объекта в массив байтов.
Установка поведения после анимации
Параметр After animation определяет, что происходит с фигурой после завершения её эффекта.

Перечисление AfterAnimationType поддерживает варианты оставлять фигуру без изменения, менять её цвет, скрывать её после анимации или скрывать её при следующем щелчке. Когда тип равен AfterAnimationType::Color, вызовите IEffect::get_AfterAnimationColor, чтобы также задать цвет.
Этот независимый пример создаёт эффект, задаёт его поведение после анимации через полученный объект эффекта и сохраняет результат.
#include <DOM/Animation/AfterAnimationType.h>
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAutoShape.h>
#include <DOM/IColorFormat.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/ITextFrame.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
#include <drawing/color.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace Aspose::Slides::Export;
using namespace System;
using namespace System::Drawing;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto shape = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 120.0f, 100.0f, 320.0f, 80.0f);
shape->get_TextFrame()->set_Text(u"Dim after animation");
auto effect = slide->get_Timeline()->get_MainSequence()->AddEffect(shape, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
effect->set_AfterAnimationType(AfterAnimationType::Color);
effect->get_AfterAnimationColor()->set_Color(Color::get_LightGray());
presentation->Save(u"shape-animation-after-effect.pptx", SaveFormat::Pptx);
presentation->Dispose();
Изменение типа от AfterAnimationType::Color очищает настройку цвета после анимации.
Анимация текста
Анимация текста имеет два связанных параметра:
- ITextAnimation::set_BuildType управляет тем, появляются ли абзацы вместе или по уровням абзацев.
- IEffect::set_AnimateTextType управляет тем, появляется ли текст сразу, по словам или по буквам. IEffect::set_DelayBetweenTextParts задаёт задержку между словами или буквами. Положительное значение — процент от длительности эффекта; отрицательное значение — задержка в секундах.
Следующий независимый пример анимирует отдельные слова в текстовом блоке. BuildType::AsOneObject отключает построение по абзацам, чтобы параметр слова применялся ко всему текстовому фрейму.
#include <DOM/Animation/AnimateTextType.h>
#include <DOM/Animation/BuildType.h>
#include <DOM/Animation/EffectSubtype.h>
#include <DOM/Animation/EffectTriggerType.h>
#include <DOM/Animation/EffectType.h>
#include <DOM/Animation/IEffect.h>
#include <DOM/Animation/ISequence.h>
#include <DOM/Animation/ITextAnimation.h>
#include <DOM/IAnimationTimeLine.h>
#include <DOM/IAutoShape.h>
#include <DOM/IShapeCollection.h>
#include <DOM/ISlide.h>
#include <DOM/ISlideCollection.h>
#include <DOM/ITextFrame.h>
#include <DOM/Presentation.h>
#include <DOM/ShapeType.h>
#include <Export/SaveFormat.h>
using namespace Aspose::Slides;
using namespace Aspose::Slides::Animation;
using namespace Aspose::Slides::Export;
using namespace System;
auto presentation = MakeObject<Presentation>();
auto slide = presentation->get_Slide(0);
auto textBox = slide->get_Shapes()->AddAutoShape(ShapeType::Rectangle, 80.0f, 80.0f, 560.0f, 100.0f);
textBox->get_TextFrame()->set_Text(u"Aspose.Slides animates this sentence word by word.");
auto effect = slide->get_Timeline()->get_MainSequence()->AddEffect(textBox, EffectType::Fade, EffectSubtype::None, EffectTriggerType::OnClick);
effect->get_TextAnimation()->set_BuildType(BuildType::AsOneObject);
effect->set_AnimateTextType(AnimateTextType::ByWord);
effect->set_DelayBetweenTextParts(20.0f);
presentation->Save(u"animated-text.pptx", SaveFormat::Pptx);
presentation->Dispose();
Чтобы построить текстовый блок по абзацу, используйте ITextAnimation::set_BuildType с BuildType::ByLevelParagraphs1 или другим уровнем абзаца. Чтобы задать отдельный эффект для одного абзаца, используйте перегрузку ISequence::AddEffect, принимающую объект IParagraph. См. Animated Text для примеров на уровне абзацев.
Заметки об экспорте и совместимости
- Сохранение в PPT или PPTX сохраняет модель анимации, но окончательное воспроизведение зависит от просмотрщика презентаций.
- PDF и статические изображения не воспроизводят анимацию. Используйте HTML5 export, анимированный GIF или video conversion, когда требуется демонстрация движения.
- Для HTML5 включите Html5Options::set_AnimateShapes и, при необходимости, Html5Options::set_AnimateTransitions.
- При рендеринге видео поддерживаются многие стандартные эффекты входа, акцента, выхода и траекторий движения, но не каждый эффект PowerPoint поддерживается. Проверьте актуальный список supported animations and effects и протестируйте критические презентации с используемой версией Aspose.Slides.
- Продвинутые пользовательские эффекты и эффекты, импортированные из других форматов, могут сохраняться в файле, но отображаться иначе в PowerPoint, HTML5 или видео. Проверяйте экспортированный результат, а не только название эффекта.
Вопросы и ответы
Почему анимация отображается в PowerPoint, но не в PDF?
PDF — статический формат, поэтому анимация и переходы слайдов не воспроизводятся. Экспортируйте в HTML5, анимированный GIF или видео, когда необходимо сохранить движение.
Почему эффект воспроизводится иначе в видео?
Экспорт в видео рендерит анимацию, а не сохраняет оригинальное поведение PowerPoint. Некоторые сложные эффекты не поддерживаются или приближенно имитируются. Ознакомьтесь с таблицей поддерживаемых эффектов и протестируйте презентацию перед массовым использованием.
Изменит ли перемещение формы вверх или вниз порядок её анимации?
Нет. Порядок наложения (z‑order) влияет только на перекрытие форм, тогда как порядок последовательности и триггеры определяют порядок воспроизведения анимаций. Меняйте временную шкалу, если нужен иной порядок воспроизведения.