本文告诉大家,如何判断 PPT 的某个元素动画属于进入或退出或强调等类型的动画
根据 ECMA-376 文档可以了解到,在 PPT 动画中,通过 cTn
也就是 OpenXML sdk 定义的 CommonTimeNode
类型的 PresetClass 属性,即可用来判断当前的动画类型
例如新建一个空白的 PPT 文件,在里面放一个元素,然后设置飞入动画,此时的飞入动画是进入动画。通过 解压缩文档为文件夹工具 解压缩此文件,可以看到在 Slide1.xml 有如下代码
<p:cTn id="5" presetID="2" presetClass="entr" presetSubtype="4" fill="hold" grpId="0" nodeType="clickEffect">
可以使用如下代码进行读取判断
using var presentationDocument =
DocumentFormat.OpenXml.Packaging.PresentationDocument.Open("Test.pptx", false);
var presentationPart = presentationDocument.PresentationPart;
var slidePart = presentationPart!.SlideParts.First();
var slide = slidePart.Slide;
var timing = slide.Timing;
// 第一级里面默认只有一项
var commonTimeNode = timing?.TimeNodeList?.ParallelTimeNode?.CommonTimeNode;
if (commonTimeNode?.NodeType?.Value == TimeNodeValues.TmingRoot)
{
// 这是符合约定
// nodeType="tmRoot"
}
if (commonTimeNode?.ChildTimeNodeList == null) return;
// 理论上只有一项,而且一定是 SequenceTimeNode 类型
var sequenceTimeNode = commonTimeNode.ChildTimeNodeList.GetFirstChild<SequenceTimeNode>();
var mainSequenceTimeNode = sequenceTimeNode.CommonTimeNode;
if (mainSequenceTimeNode?.NodeType?.Value == TimeNodeValues.MainSequence)
{
// [TimeLine 对象 (PowerPoint) | Microsoft Docs](https://docs.microsoft.com/zh-cn/office/vba/api/PowerPoint.TimeLine )
// MainSequence 主动画序列
var mainParallelTimeNode = mainSequenceTimeNode.ChildTimeNodeList
.GetFirstChild<ParallelTimeNode>().CommonTimeNode.ChildTimeNodeList
.GetFirstChild<ParallelTimeNode>().CommonTimeNode.ChildTimeNodeList
.GetFirstChild<ParallelTimeNode>();
switch (mainParallelTimeNode.CommonTimeNode.PresetClass.Value)
{
case TimeNodePresetClassValues.Entrance:
// 进入动画
break;
case TimeNodePresetClassValues.Exit:
// 退出动画
break;
case TimeNodePresetClassValues.Emphasis:
// 强调动画
break;
case TimeNodePresetClassValues.Path:
// 路径动画
break;
case TimeNodePresetClassValues.Verb:
break;
case TimeNodePresetClassValues.MediaCall:
// 播放动画
break;
default:
throw new ArgumentOutOfRangeException();
}
}
可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码
git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin f7c152959666fe9b6d543834fcb30a7ff6cf7e15
以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源
git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
获取代码之后,进入 PptxDemo 文件夹
如需获取强调的课件,请使用 git 切换到 b8092ac9d12f315ae94ee2e53c3b4748d866b31b 这个 commit 即可拿到 Test.pptx 带强调动画,内容大概如下
<p:cTn id="5" presetID="25" presetClass="emph" presetSubtype="0" fill="hold" grpId="0" nodeType="clickEffect">
如需获取路径动画的课件,请使用 git 切换到 08c7d7a13b19cfa120b7a9971f88da5af96b4c75 这个 commit 即可拿到 Test.pptx 带路径动画,路径动画的内容大概如下
<p:cTn id="5" presetID="42" presetClass="path" presetSubtype="0" accel="50000" decel="50000" fill="hold" grpId="0" nodeType="clickEffect">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<p:animMotion origin="layout" path="M 0 0 L 0 0.25 E" pathEditMode="relative" ptsTypes="">
<p:cBhvr>
<p:cTn id="6" dur="2000" fill="hold" />
<p:tgtEl>
<p:spTgt spid="2" />
</p:tgtEl>
<p:attrNameLst>
<p:attrName>ppt_x</p:attrName>
<p:attrName>ppt_y</p:attrName>
</p:attrNameLst>
</p:cBhvr>
</p:animMotion>
</p:childTnLst>
</p:cTn>
如需获取退出动画的课件,请使用 git 切换到 1521fdf2c9c94f13efe06dea25572e18847c11f3 这个 commit 即可拿到 Test.pptx 带退出动画,退出动画的内容大概如下
<p:cTn id="5" presetID="16" presetClass="exit" presetSubtype="21" fill="hold" grpId="0" nodeType="clickEffect">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<p:animEffect transition="out" filter="barn(inVertical)">
<p:cBhvr>
<p:cTn id="6" dur="500" />
<p:tgtEl>
<p:spTgt spid="2" />
</p:tgtEl>
</p:cBhvr>
</p:animEffect>
<p:set>
<p:cBhvr>
<p:cTn id="7" dur="1" fill="hold">
<p:stCondLst>
<p:cond delay="499" />
</p:stCondLst>
</p:cTn>
<p:tgtEl>
<p:spTgt spid="2" />
</p:tgtEl>
<p:attrNameLst>
<p:attrName>style.visibility</p:attrName>
</p:attrNameLst>
</p:cBhvr>
<p:to>
<p:strVal val="hidden" />
</p:to>
</p:set>
</p:childTnLst>
</p:cTn>
如需获取多媒体动画的课件,请使用 git 切换到 4338d948558f7748c865b47672d4a579dea8353c 这个 commit 即可拿到 Test.pptx 带播放视频动画,内容大概如下
<p:par>
<p:cTn id="5" presetID="1" presetClass="mediacall" presetSubtype="0" fill="hold" nodeType="clickEffect">
<p:stCondLst>
<p:cond delay="0" />
</p:stCondLst>
<p:childTnLst>
<p:cmd type="call" cmd="playFrom(0.0)">
<p:cBhvr>
<p:cTn id="6" dur="1137" fill="hold" />
<p:tgtEl>
<p:spTgt spid="3" />
</p:tgtEl>
</p:cBhvr>
</p:cmd>
</p:childTnLst>
</p:cTn>
</p:par>
本文的属性是依靠 dotnet OpenXML 解压缩文档为文件夹工具 工具协助测试的,这个工具是开源免费的工具,欢迎使用
本文会经常更新,请阅读原文: https://blog.lindexi.com/post/dotnet-OpenXML-%E8%AF%BB%E5%8F%96-PPT-%E5%8A%A8%E7%94%BB%E8%BF%9B%E5%85%A5%E9%80%80%E5%87%BA%E5%BC%BA%E8%B0%83%E5%8A%A8%E7%94%BB%E7%B1%BB%E5%9E%8B.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。
无盈利,不卖课,做纯粹的技术博客
以下是广告时间
推荐关注 Edi.Wang 的公众号
欢迎进入 Eleven 老师组建的 .NET 社区
以上广告全是友情推广,无盈利