JSONGenerator.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. using DocumentFormat.OpenXml.Presentation;
  2. using HTEXLib.Models;
  3. using HTEXLib.Models.Inner;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Globalization;
  7. using System.Linq;
  8. namespace HTEXLib.Animations
  9. {
  10. public class JSONGenerator
  11. {
  12. public PPTSlide Slide { get; set; }
  13. public JSONGenerator(PPTSlide slide)
  14. {
  15. this.Slide = slide;
  16. }
  17. public JSONGenerator(List<PPTSlide> slides)
  18. {
  19. this.Slide = slides.ElementAt(0); //TODO: add support for more than one slide
  20. }
  21. public string GetAnimaVariable()
  22. {
  23. return GetAnimationsJSON() ;
  24. }
  25. /*
  26. * Fix the timing for animations that need to start without a click. Make the tree simpler by removing nodes that are empty or nested.
  27. *
  28. * When a node has a start type != ClickEffect , we add the Animations from this timenode to the animations list in the previous time node.
  29. * If it is type After the previous one we need to set Delay = Length of the previous one.
  30. *
  31. * Removing nested nodes:
  32. * Example 1: Node -> Node -> Node - every node has a single child. In this case we can create one time node with the timing for both.
  33. * Example 2: We have only one node (one simple animation) and all the other are nested (inner animations) - we remove the parent time node and
  34. * add its timing to the timing of the nested animations.
  35. *
  36. */
  37. private List<IAnimation> fixAnimationTimings(List<IAnimation> animations)
  38. {
  39. animations = fixNestedAnimations(animations);
  40. List<IAnimation> result = new List<IAnimation>();
  41. if (animations == null || animations.Count == 0)
  42. return result;
  43. //If we have only one animation and all the others are nested - add the delay to the inner animations and remove this one.
  44. if (animations.Count == 1 && animations[0].InnerAnimations != null && animations[0].InnerAnimations.Count > 0)
  45. {
  46. foreach (IAnimation anim in animations[0].InnerAnimations)
  47. anim.Start += animations[0].Start;
  48. return fixAnimationTimings(animations[0].InnerAnimations);
  49. }
  50. IAnimation previousAnimation = null;
  51. foreach (IAnimation animation in animations)
  52. {
  53. SimpleAnimation sAnimation = (SimpleAnimation)animation;
  54. if (previousAnimation == null)
  55. {
  56. previousAnimation = sAnimation;
  57. continue;
  58. }
  59. //These are the cases where animation starts without a click. There migth be other cases which are not handled yet.
  60. else if (sAnimation.timingType!=null && sAnimation.timingType.HasValue && (
  61. TimeNodeValues.WithEffect.Equals(sAnimation.timingType.Value) ||
  62. TimeNodeValues.AfterEffect.Equals(sAnimation.timingType.Value) ||
  63. TimeNodeValues.WithGroup.Equals(sAnimation.timingType.Value) ||
  64. TimeNodeValues.AfterGroup.Equals(sAnimation.timingType.Value)))
  65. {
  66. int newLenegth = 0;
  67. if (TimeNodeValues.AfterEffect.Equals(sAnimation.timingType.Value) ||
  68. TimeNodeValues.AfterGroup.Equals(sAnimation.timingType.Value))
  69. {
  70. /*If animation is a part of a group then it has delay according to the start of the parent time node (animation).
  71. * In this case we use this delay because it is the proper way power point handles such animations.
  72. * If by some reason there isn't such delay and the animation type is set to 'After' previous
  73. * we set the start point to right after the previous animation ends." */
  74. if (sAnimation.Start <= previousAnimation.Length + previousAnimation.Start)
  75. sAnimation.Start = previousAnimation.Length + previousAnimation.Start;
  76. if (sAnimation.InnerAnimations != null)
  77. foreach (IAnimation anim in sAnimation.InnerAnimations)
  78. anim.Start = anim.Start + sAnimation.Start;
  79. newLenegth = sAnimation.Length + sAnimation.Start;
  80. }
  81. else
  82. {
  83. newLenegth = (sAnimation.Length + sAnimation.Start >
  84. previousAnimation.Length + previousAnimation.Start)
  85. ? sAnimation.Length + sAnimation.Start
  86. : previousAnimation.Length + previousAnimation.Start;
  87. }
  88. /*Joins the current animation and the previous one and recalculates the length*/
  89. if (previousAnimation.InnerAnimations != null && previousAnimation.InnerAnimations.Count > 0)
  90. {
  91. previousAnimation.Length = newLenegth;
  92. if (sAnimation.InnerAnimations == null || sAnimation.InnerAnimations.Count == 0)
  93. previousAnimation.InnerAnimations.Add(sAnimation);
  94. else
  95. previousAnimation.InnerAnimations.AddRange(sAnimation.InnerAnimations);
  96. continue;
  97. }
  98. else
  99. {
  100. SimpleAnimation tempAnimation = new SimpleAnimation();
  101. tempAnimation.Length = newLenegth;
  102. tempAnimation.timingType = ((SimpleAnimation)previousAnimation).timingType;
  103. tempAnimation.InnerAnimations = new List<IAnimation>();
  104. if (previousAnimation.InnerAnimations == null || previousAnimation.InnerAnimations.Count == 0)
  105. tempAnimation.InnerAnimations.Add(previousAnimation);
  106. else
  107. tempAnimation.InnerAnimations.AddRange(previousAnimation.InnerAnimations);
  108. if (sAnimation.InnerAnimations == null || sAnimation.InnerAnimations.Count == 0)
  109. tempAnimation.InnerAnimations.Add(sAnimation);
  110. else
  111. tempAnimation.InnerAnimations.AddRange(sAnimation.InnerAnimations);
  112. previousAnimation = tempAnimation;
  113. continue;
  114. }
  115. }
  116. result.Add(previousAnimation);
  117. previousAnimation = sAnimation;
  118. }
  119. result.Add(previousAnimation);
  120. return result;
  121. }
  122. /*
  123. * When the animation has only one inner animation then return the inner animation. Do this recursive until we get the real one.
  124. */
  125. private IAnimation getAnimationFromNested(IAnimation sAnimation)
  126. {
  127. if (sAnimation.InnerAnimations != null && sAnimation.InnerAnimations.Count == 1)
  128. {
  129. sAnimation.InnerAnimations[0].Start += sAnimation.Start;
  130. return getAnimationFromNested(sAnimation.InnerAnimations[0]);
  131. }
  132. if (((SimpleAnimation)sAnimation).timingType == null && sAnimation.InnerAnimations != null && sAnimation.InnerAnimations.Count>0)
  133. ((SimpleAnimation)sAnimation).timingType = ((SimpleAnimation)getAnimationFromNested(sAnimation.InnerAnimations[0])).timingType;
  134. return sAnimation;
  135. }
  136. /*
  137. * Generating the JSON for the animations for one slide only. It has some support for nested animations but not everything works.
  138. */
  139. public string GetAnimationsJSON()
  140. {
  141. if (Slide == null)
  142. {
  143. return "{s1:{t:{i:1000,c:1,v:0,n:0},g:0,a:0,f:0,c:0}}";
  144. }
  145. String result = "";
  146. int animations = 0;
  147. List<IAnimation> fixedAnimations = fixAnimationTimings(Slide.Animations);
  148. animations = fixedAnimations.Count;
  149. if (Slide.Transition == null)
  150. {
  151. result = "{s1:{t:{i:0,c:1,v:0,n:0},g:0,a:0,f:0,c:##ANIMATIONS_PLACEHOLDER##}}";
  152. }
  153. else
  154. {
  155. result = "{s1:{t:{i:" + (Slide.Transition.Length + Slide.Transition.Start) +
  156. ",c:" + Slide.Transition.GetJsonString() + "},g:0,a:0,f:0,c:##ANIMATIONS_PLACEHOLDER##}}";
  157. }
  158. if (animations == 0)
  159. {
  160. result = result.Replace("##ANIMATIONS_PLACEHOLDER##", "0");
  161. return result;
  162. }
  163. SimpleAnimation checkEffectFirstAnim = (SimpleAnimation)fixedAnimations[0];
  164. if (checkEffectFirstAnim.timingType != null && checkEffectFirstAnim.timingType.HasValue && checkEffectFirstAnim.timingType.Value != TimeNodeValues.ClickEffect)
  165. {
  166. result = result.Replace("n:0", "n:1");
  167. //If it is just one Animation we change this in the transition! - the transition is like the first Animation!
  168. }
  169. string animationsString = "{i:" + animations + getAnimationsString(fixedAnimations, true) + "}";
  170. result = result.Replace("##ANIMATIONS_PLACEHOLDER##", animationsString);
  171. return result;
  172. }
  173. /*
  174. * Generate JSON for animation tree. Recursive going into the tree - there is some difference in the animation string
  175. * for the first level and the next levels.
  176. */
  177. private string getAnimationsString(List<IAnimation> animations, bool firstLevel)
  178. {
  179. String animationList = "";
  180. int index = 0;
  181. foreach (IAnimation animation in animations)
  182. {
  183. if (animation.InnerAnimations == null || animation.InnerAnimations.Count == 0)
  184. {
  185. if (!firstLevel)
  186. animationList = animationList + ",c" + index++ + ":" + animation.GetJsonString();
  187. else
  188. animationList = animationList + ",c" + index++ + ":{i:" + (((SimpleAnimation)animation).getCalculatedLength() + animation.Start) + ",c0:" + animation.GetJsonString() + "}";
  189. }
  190. else
  191. // Nested animatons (several animations in one time node, or in different time nodes that start together!
  192. {
  193. String innerAnimationsString = getAnimationsString(animation.InnerAnimations, false);
  194. animationList = animationList + ",c" + index++ + ":{i:" + (((SimpleAnimation)animation).getCalculatedLength() + animation.Start) +
  195. innerAnimationsString + "}";
  196. }
  197. }
  198. return animationList;
  199. }
  200. public static IAnimation GenerateTransitionAnimationObject(Transition trans)
  201. {
  202. if (trans == null || trans.FirstChild == null)
  203. return null;
  204. TransitionAnimation result = new TransitionAnimation();
  205. if (trans.Speed != null && TransitionSpeedValues.Fast.Equals(trans.Speed.Value))
  206. result.Length = 500;
  207. else if (trans.Speed != null && TransitionSpeedValues.Slow.Equals(trans.Speed.Value))
  208. result.Length = 2000;
  209. else if (trans.Duration != null)
  210. result.Length = int.Parse(trans.Duration.Value);
  211. else
  212. result.Length = 1000;
  213. result.Start = 0;
  214. result.InitialState = -1;
  215. result.Repetitions = 1;
  216. if (trans.AdvanceOnClick != null)
  217. result.AdvanceOnClick = trans.AdvanceOnClick.Value;
  218. else result.AdvanceOnClick = true;
  219. if (typeof(StripsTransition) == trans.FirstChild.GetType())
  220. {
  221. StripsTransition transition = (StripsTransition)trans.FirstChild;
  222. result.Type = AnimationTypes.Strips;
  223. if (transition.Direction != null &&
  224. TransitionCornerDirectionValues.RightUp.Equals(transition.Direction.Value))
  225. result.AdditionalData = "7";
  226. else if (transition.Direction != null &&
  227. TransitionCornerDirectionValues.LeftDown.Equals(transition.Direction.Value))
  228. result.AdditionalData = "9";
  229. else if (transition.Direction != null &&
  230. TransitionCornerDirectionValues.RightDown.Equals(transition.Direction.Value))
  231. result.AdditionalData = "8";
  232. else
  233. result.AdditionalData = "6";
  234. }
  235. else if (typeof(PushTransition) == trans.FirstChild.GetType())
  236. {
  237. PushTransition transition = (PushTransition)trans.FirstChild;
  238. result.Type = AnimationTypes.Push;
  239. if (transition.Direction != null &&
  240. TransitionSlideDirectionValues.Right.Equals(transition.Direction.Value))
  241. result.AdditionalData = "3";
  242. else if (transition.Direction != null &&
  243. TransitionSlideDirectionValues.Up.Equals(transition.Direction.Value))
  244. result.AdditionalData = "4";
  245. else if (transition.Direction != null &&
  246. TransitionSlideDirectionValues.Left.Equals(transition.Direction.Value))
  247. result.AdditionalData = "2";
  248. else result.AdditionalData = "1";
  249. }
  250. else if (typeof(WipeTransition) == trans.FirstChild.GetType())
  251. {
  252. WipeTransition transition = (WipeTransition)trans.FirstChild;
  253. result.Type = AnimationTypes.Wipe;
  254. if (transition.Direction != null &&
  255. TransitionSlideDirectionValues.Right.Equals(transition.Direction.Value))
  256. result.AdditionalData = "4";
  257. else if (transition.Direction != null &&
  258. TransitionSlideDirectionValues.Up.Equals(transition.Direction.Value))
  259. result.AdditionalData = "3";
  260. else if (transition.Direction != null &&
  261. TransitionSlideDirectionValues.Left.Equals(transition.Direction.Value))
  262. result.AdditionalData = "2";
  263. else result.AdditionalData = "1";
  264. }
  265. else if (typeof(FadeTransition) == trans.FirstChild.GetType())
  266. {
  267. FadeTransition transition = (FadeTransition)trans.FirstChild;
  268. result.Type = AnimationTypes.Fade;
  269. if (transition.ThroughBlack != null && transition.ThroughBlack.Value)
  270. result.Type = AnimationTypes.FadeThroughBlack;
  271. result.AdditionalData = "1";
  272. }
  273. else if (typeof(CutTransition) == trans.FirstChild.GetType())
  274. {
  275. CutTransition transition = (CutTransition)trans.FirstChild;
  276. result.Type = AnimationTypes.Cut;
  277. result.AdditionalData = "2";
  278. if (transition.ThroughBlack != null && transition.ThroughBlack.Value)
  279. {
  280. result.Type = AnimationTypes.CutThroughBlack;
  281. result.AdditionalData = "3";
  282. }
  283. }
  284. else if (typeof(DissolveTransition) == trans.FirstChild.GetType())
  285. {
  286. result.Type = AnimationTypes.DissolveIn;
  287. result.AdditionalData = "1";
  288. }
  289. else if (typeof(WedgeTransition) == trans.FirstChild.GetType())
  290. {
  291. result.Type = AnimationTypes.Wedge;
  292. result.AdditionalData = "1";
  293. }
  294. else if (typeof(PullTransition) == trans.FirstChild.GetType())
  295. {
  296. PullTransition transition = (PullTransition)trans.FirstChild;
  297. result.Type = AnimationTypes.UnCover;
  298. if (transition.Direction != null && "d".Equals(transition.Direction.Value.ToString()))
  299. result.AdditionalData = "9";
  300. else if (transition.Direction != null && "r".Equals(transition.Direction.Value.ToString()))
  301. result.AdditionalData = "11";
  302. else if (transition.Direction != null && "u".Equals(transition.Direction.Value.ToString()))
  303. result.AdditionalData = "12";
  304. else if (transition.Direction != null && "ld".Equals(transition.Direction.Value.ToString()))
  305. result.AdditionalData = "13";
  306. else if (transition.Direction != null && "lu".Equals(transition.Direction.Value.ToString()))
  307. result.AdditionalData = "14";
  308. else if (transition.Direction != null && "rd".Equals(transition.Direction.Value.ToString()))
  309. result.AdditionalData = "15";
  310. else if (transition.Direction != null && "ru".Equals(transition.Direction.Value.ToString()))
  311. result.AdditionalData = "16";
  312. else result.AdditionalData = "10";
  313. }
  314. else if (typeof(ZoomTransition) == trans.FirstChild.GetType())
  315. {
  316. ZoomTransition transition = (ZoomTransition)trans.FirstChild;
  317. result.Type = AnimationTypes.Box;
  318. if (transition.Direction != null && TransitionInOutDirectionValues.In == transition.Direction.Value)
  319. result.AdditionalData = "19";
  320. else result.AdditionalData = "20";
  321. }
  322. else if (typeof(ZoomTransition) == trans.FirstChild.GetType())
  323. {
  324. ZoomTransition transition = (ZoomTransition)trans.FirstChild;
  325. result.Type = AnimationTypes.Box;
  326. if (transition.Direction != null && TransitionInOutDirectionValues.In == transition.Direction.Value)
  327. result.AdditionalData = "19";
  328. else result.AdditionalData = "20";
  329. }
  330. else if (typeof(WheelTransition) == trans.FirstChild.GetType())
  331. {
  332. WheelTransition transition = (WheelTransition)trans.FirstChild;
  333. result.Type = AnimationTypes.Wheel;
  334. if (transition.Spokes != null && transition.Spokes.Value == 1)
  335. result.AdditionalData = "1";
  336. else if (transition.Spokes != null && transition.Spokes.Value == 2)
  337. result.AdditionalData = "2";
  338. else if (transition.Spokes != null && transition.Spokes.Value == 3)
  339. result.AdditionalData = "3";
  340. else if (transition.Spokes != null && transition.Spokes.Value == 8)
  341. result.AdditionalData = "8";
  342. else result.AdditionalData = "4";
  343. }
  344. else if (typeof(SplitTransition) == trans.FirstChild.GetType())
  345. {
  346. SplitTransition transition = (SplitTransition)trans.FirstChild;
  347. result.Type = AnimationTypes.Split;
  348. if (transition.Direction != null && TransitionInOutDirectionValues.In == transition.Direction.Value)
  349. {
  350. if (transition.Orientation != null && DirectionValues.Vertical.Equals(transition.Orientation.Value))
  351. result.AdditionalData = "25";
  352. else
  353. result.AdditionalData = "23";
  354. }
  355. else
  356. {
  357. if (transition.Orientation != null && DirectionValues.Vertical.Equals(transition.Orientation.Value))
  358. result.AdditionalData = "26";
  359. else
  360. result.AdditionalData = "24";
  361. }
  362. }
  363. else if (typeof(CircleTransition) == trans.FirstChild.GetType())
  364. {
  365. result.Type = AnimationTypes.Circle;
  366. result.AdditionalData = "20";
  367. }
  368. else if (typeof(DiamondTransition) == trans.FirstChild.GetType())
  369. {
  370. result.Type = AnimationTypes.Diamond;
  371. result.AdditionalData = "20";
  372. }
  373. else if (typeof(PlusTransition) == trans.FirstChild.GetType())
  374. {
  375. result.Type = AnimationTypes.Plus;
  376. result.AdditionalData = "20";
  377. }
  378. else if (typeof(NewsflashTransition) == trans.FirstChild.GetType())
  379. {
  380. result.Type = AnimationTypes.Newsflash;
  381. result.AdditionalData = "20";
  382. }
  383. return result;
  384. }
  385. /// <summary>
  386. /// 动画emph (Preset Type Enum ( Emphasis )) Emphasis Preset
  387. ///entr(Preset Type Enum (Entrance )) Entrance Preset
  388. ///exit(Exit) Exit Preset
  389. ///mediacall(Preset Type Enum (Media Call )) Media Call Preset
  390. ///path(Preset Type Enum (Path )) Path Preset
  391. ///verb(Preset Type Enum (Verb )) Verb Preset
  392. /// </summary>
  393. /// <param name="commonTimeNode"></param>
  394. /// <param name="SlideSizes"></param>
  395. /// <returns></returns>
  396. public SimpleAnimation getSimpleAnimationFromCommonTimeNodePreset(CommonTimeNode commonTimeNode, SlideSize SlideSizes)
  397. {
  398. SimpleAnimation result = new SimpleAnimation();
  399. ///路径方式
  400. if (AnimationTypes.TypePath.Equals(commonTimeNode.PresetClass))
  401. {
  402. return new MotionPathAnimation(commonTimeNode, Slide.slideIndex, SlideSizes);
  403. }
  404. ///进入
  405. else if (AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass))
  406. {
  407. result.InitialState = 1;
  408. }
  409. ///退出
  410. else if (AnimationTypes.TypeExit.Equals(commonTimeNode.PresetClass))
  411. {
  412. result.InitialState = 2;
  413. }
  414. ///强调
  415. else if (AnimationTypes.TypeEmphasis.Equals(commonTimeNode.PresetClass))
  416. {
  417. result.InitialState = 3;
  418. }
  419. /*
  420. 1 emph (Preset Type Enum ( Emphasis )) Emphasis Preset
  421. 1 entr (Preset Type Enum ( Entrance )) Entrance Preset
  422. 1 exit (Exit) Exit Preset
  423. mediacall (Preset Type Enum ( Media Call )) Media Call Preset
  424. path (Preset Type Enum ( Path )) Path Preset
  425. verb (Preset Type Enum ( Verb )) Verb Preset
  426. */
  427. /// TODO 其他类型 mediacall(Preset Type Enum (Media Call )) Media Call Preset
  428. /// verb(Preset Type Enum (Verb )) Verb Preset
  429. else return null;
  430. if (commonTimeNode.PresetId == null)
  431. return null;
  432. result.timingType = commonTimeNode.NodeType;
  433. //Get the speed from one of the nodes common behavior. Hopefully all nodes have the same speed (since the animation is the same).
  434. foreach (Object xmlEl in commonTimeNode.Descendants())
  435. if (xmlEl.GetType().Equals(typeof(CommonBehavior)))
  436. {
  437. CommonBehavior bhvr = ((CommonBehavior)xmlEl);
  438. if (bhvr.CommonTimeNode != null)
  439. {
  440. result.FixAnimationTimings(bhvr, Slide.slideIndex);
  441. if (result.Length <= 1)
  442. continue;
  443. if (result.Start == 0)
  444. {
  445. Condition condition = commonTimeNode.StartConditionList.FirstChild as Condition;
  446. if (!condition.Delay.Equals("indefinite"))
  447. result.Start = int.Parse(condition.Delay);
  448. }
  449. break;
  450. }
  451. }
  452. if (result.Length <= 1)
  453. result.Length = 100; //Default value??
  454. if (AnimationTypes.TypeEmphasis.Equals(commonTimeNode.PresetClass))
  455. result = handleEmphasisAnimation(commonTimeNode, result);
  456. else
  457. result = handleEntranceAnimation(commonTimeNode, result);
  458. if (result.AdditionalData == null || result.AdditionalData == "0") //There are default values. Horizontal In = horizontal + in ;)
  459. //此属性是位标志,指定一个方向或一些其他属性的效果。 例如它可以设置指定"从底部"飞入效果或"加粗"更改字体样式效果。
  460. switch (commonTimeNode.PresetSubtype.Value)
  461. {
  462. case 0: result.AdditionalData = "0"; break;
  463. case 4: result.AdditionalData = "3"; break; //From bottom
  464. case 2: result.AdditionalData = "2"; break; //From right
  465. case 1: result.AdditionalData = "1"; break; //From top
  466. case 8: result.AdditionalData = "4"; break; //From left
  467. case 6: result.AdditionalData = "8"; break; //Bottom right
  468. case 3: result.AdditionalData = "7"; break; //Top right
  469. case 9: result.AdditionalData = "6"; break; //Top right
  470. case 12: result.AdditionalData = "9"; break; //Bottom left
  471. case 10: result.AdditionalData = "16"; break; //Horizontal
  472. case 5: result.AdditionalData = "17"; break; //Vertical
  473. case 26: result.AdditionalData = "23"; break; //Horizontal in
  474. case 42: result.AdditionalData = "24"; break; //Horizontal out
  475. case 21: result.AdditionalData = "25"; break; //Vertical in
  476. case 37: result.AdditionalData = "26"; break; //Vertical out
  477. case 16: result.AdditionalData = "19"; break; //in
  478. case 32: result.AdditionalData = "20"; break; //out
  479. }
  480. checkIsText(result);
  481. return result;
  482. }
  483. private void checkIsText(SimpleAnimation result)
  484. {
  485. int res;
  486. bool isTextWithEffect = int.TryParse(result.ObjectId, out res) && PPTShape.effectShapes.Contains(Slide.slideIndex + "_" + res);
  487. int tryParse = 0;
  488. if (!int.TryParse(result.ObjectId, out tryParse) || isTextWithEffect)
  489. {
  490. return;//if it is like 123p -> return;
  491. }
  492. foreach (PPTShapeBase shape in Slide.ContainerShape.Elements)
  493. if (typeof(PPTShape).Equals(shape.GetType()) && ((PPTShape)shape).IsText)
  494. {
  495. string shapeId = shape.NonVisualShapeProp.Id;
  496. string shapeObjectId = "s1s" + result.ObjectId;
  497. if (shapeId.Equals(shapeObjectId))
  498. {
  499. result.ObjectId = result.ObjectId + "p0";// TODO check when multiple paragraphs
  500. }
  501. }
  502. }
  503. /// <summary>
  504. /// 获取强调
  505. /// </summary>
  506. /// <param name="commonTimeNode"></param>
  507. /// <param name="simpleAnim"></param>
  508. /// <returns></returns>
  509. private EmphasisAnimation handleEmphasisAnimation(CommonTimeNode commonTimeNode, SimpleAnimation simpleAnim)
  510. {
  511. EmphasisAnimation result = new EmphasisAnimation(simpleAnim);
  512. result.setRgbColor(commonTimeNode, Slide);
  513. switch (commonTimeNode.PresetId.Value) //Presets for Entrance/Exit
  514. {
  515. case 3: result.Type = AnimationTypes.ChangeFontColor; break;
  516. case 19: result.Type = AnimationTypes.ColorBlend; break;
  517. case 14: result.Type = AnimationTypes.Blast; break;
  518. case 26: result.Type = AnimationTypes.FlashBulb; break;
  519. case 35: result.Type = AnimationTypes.Blink; break;
  520. case 9:
  521. {
  522. result.Type = AnimationTypes.Transparency;
  523. result.Transparency = getTransparence(commonTimeNode);
  524. }
  525. break;
  526. case 20:
  527. {
  528. result.Type = AnimationTypes.ColorWave;
  529. result.Length *= 2;
  530. result.e2 = result.Length / 10;
  531. result.e1 = 2;
  532. }
  533. break;
  534. case 16:
  535. {
  536. result.Type = AnimationTypes.BrushOnColor;
  537. result.e2 = result.Length / 25;
  538. result.e1 = 2;
  539. }
  540. break;
  541. case 33:
  542. {
  543. result.Type = AnimationTypes.VerticalHighlight;
  544. result.Length *= 2;
  545. }
  546. break;
  547. case 27:
  548. {
  549. result.Type = AnimationTypes.Flicker;
  550. result.Length *= 2;
  551. }
  552. break;
  553. case 36:
  554. {
  555. result.Type = AnimationTypes.Shimmer;
  556. result.e2 = result.Length / 5;
  557. result.Length *= 2;
  558. foreach (Object obj in commonTimeNode.Descendants())
  559. if (obj.GetType().Equals(typeof(AnimateScale)))
  560. {
  561. ((EmphasisAnimation)result).ScaleX = ((AnimateScale)obj).ToPosition.X.Value / 1000;
  562. ((EmphasisAnimation)result).ScaleY = ((AnimateScale)obj).ToPosition.Y.Value / 1000;
  563. break;
  564. }
  565. }
  566. break;
  567. case 28:
  568. {
  569. result.Type = AnimationTypes.GrowwithColor;
  570. result.e2 = result.Length / 10;
  571. result.e1 = 2;
  572. }
  573. break;
  574. case 32:
  575. {
  576. result.Type = AnimationTypes.Teeter;
  577. result.Length *= 2;
  578. }
  579. break;
  580. case 34:
  581. {
  582. result.Type = AnimationTypes.Wave;
  583. result.e2 = result.Length / 5;
  584. result.Length *= 2;
  585. }
  586. break;
  587. case 8:
  588. {
  589. result.Type = AnimationTypes.Spin;
  590. foreach (Object obj in commonTimeNode.Descendants())
  591. if (obj.GetType().Equals(typeof(AnimateRotation)))
  592. {
  593. ((EmphasisAnimation)result).RotationDegrees = ((AnimateRotation)obj).By / 60000;
  594. break;
  595. }
  596. }
  597. break;
  598. case 6:
  599. {
  600. result.Type = AnimationTypes.GrowShrink;
  601. foreach (Object obj in commonTimeNode.Descendants())
  602. if (obj.GetType().Equals(typeof(AnimateScale)))
  603. {
  604. ((EmphasisAnimation)result).ScaleX = ((AnimateScale)obj).ByPosition.X.Value / 1000;
  605. ((EmphasisAnimation)result).ScaleY = ((AnimateScale)obj).ByPosition.Y.Value / 1000;
  606. break;
  607. }
  608. }
  609. break;
  610. default: result.Type = "defaul+" + commonTimeNode.PresetId.Value; return result;
  611. }
  612. return result;
  613. }
  614. /// <summary>
  615. /// 获取进入
  616. /// </summary>
  617. /// <param name="commonTimeNode"></param>
  618. /// <param name="result"></param>
  619. /// <returns></returns>
  620. private SimpleAnimation handleEntranceAnimation(CommonTimeNode commonTimeNode, SimpleAnimation result)
  621. {
  622. switch (commonTimeNode.PresetId.Value) //Presets for Entrance/Exit
  623. {
  624. case 1: result.Type = AnimationTypes.Appear; break;
  625. case 54: result.Type = AnimationTypes.Glide; break;
  626. case 19: result.Type = AnimationTypes.Swivel; break;
  627. case 42: result.Type = AnimationTypes.Ascend; break;
  628. case 3: result.Type = AnimationTypes.Blinds; break;
  629. case 4: result.Type = AnimationTypes.Box; break;
  630. case 25: result.Type = AnimationTypes.Boomerang; break;
  631. case 43: result.Type = AnimationTypes.CenterRevolve; break;
  632. case 5: result.Type = AnimationTypes.Checkerboard; break;
  633. case 50: result.Type = AnimationTypes.Compress; break;
  634. case 7: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.CrawlIn : AnimationTypes.CrawlOut; break;
  635. case 47: result.Type = AnimationTypes.Descend; break;
  636. case 48: result.Type = AnimationTypes.Sling; break;
  637. case 29: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.EaseIn : AnimationTypes.EaseOut; break;
  638. case 55: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.Expand : AnimationTypes.Contract; break;
  639. case 10: result.Type = AnimationTypes.Fade; break;
  640. case 53: result.Type = AnimationTypes.FadedZoom; break;
  641. case 11: result.Type = AnimationTypes.FlashOnce; break;
  642. case 2: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.FlyIn : AnimationTypes.FlyOut; break;
  643. case 58: result.Type = AnimationTypes.Fold; break;
  644. case 31: result.Type = AnimationTypes.GrowTurn; break;
  645. case 12: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.PeekIn : AnimationTypes.PeekOut; break;
  646. case 16: result.Type = AnimationTypes.Split; break;
  647. case 35: result.Type = AnimationTypes.Pinwheel; break;
  648. case 14: result.Type = AnimationTypes.RandomBars; break;
  649. case 37: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.RiseUp : AnimationTypes.SinkDown; break;
  650. case 49: result.Type = AnimationTypes.Spinner; break;
  651. case 22: result.Type = AnimationTypes.Wipe; break;
  652. case 18: result.Type = AnimationTypes.Strips; break;
  653. case 26: result.Type = AnimationTypes.Bounce; result.Length = (int)((result.Length * 100) / 29); break;//time tunning
  654. case 6: result.Type = AnimationTypes.Circle; break;
  655. case 28: result.Type = AnimationTypes.Credits; break;
  656. case 52: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.CurveUp : AnimationTypes.CurveDown; break;
  657. case 8: result.Type = AnimationTypes.Diamond; break;
  658. case 9: result.Type = AnimationTypes.Dissolve; break;
  659. case 30: result.Type = AnimationTypes.Float; break;
  660. case 34: result.Type = AnimationTypes.LightSpeed; result.Length = (int)((result.Length * 5) / 3); break;//time tunning
  661. case 51: result.Type = AnimationTypes.Magnify; result.Length = (int)((result.Length * 200) / 77); break;//time tunning
  662. case 13: result.Type = AnimationTypes.Plus; break;
  663. case 15: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.SpiralIn : AnimationTypes.SpiralOut; break;
  664. case 17: result.Type = AnimationTypes.Stretch; break;
  665. case 39: result.Type = AnimationTypes.Thread; break;
  666. case 20: result.Type = AnimationTypes.Wedge; break;
  667. case 21: result.Type = AnimationTypes.Wheel; result.AdditionalData = "" + commonTimeNode.PresetSubtype.Value; break;
  668. case 23: result.Type = AnimationTypes.Zoom; break;
  669. ///补充
  670. // case 45:result.Type= AnimationTypes.Zoom; break;
  671. default: result.Type = "defaul+"+ commonTimeNode.PresetId.Value; return result;
  672. }
  673. return result;
  674. }
  675. private double getTransparence(CommonTimeNode commonTimeNode)
  676. {
  677. if (typeof(AnimateEffect) == commonTimeNode.LastChild.LastChild.GetType())
  678. {
  679. AnimateEffect animEffect = (AnimateEffect)commonTimeNode.LastChild.LastChild;
  680. string value = animEffect.PropertyList.Value;
  681. if (value != null && value.IndexOf("opacity:") != -1)
  682. {
  683. string opacityStr = value.Substring(9);//we need 0.75 from "opacity: 0.75"
  684. double opacity = double.Parse(opacityStr, CultureInfo.GetCultureInfo("en-US").NumberFormat);
  685. return 1 - opacity;
  686. }
  687. }
  688. return 0;
  689. }
  690. private List<IAnimation> fixNestedAnimations(List<IAnimation> animations)
  691. {
  692. if (animations == null || animations.Count == 0)
  693. return null;
  694. List<IAnimation> result = new List<IAnimation>();
  695. foreach (IAnimation anim in animations)
  696. {
  697. IAnimation animation = getAnimationFromNested(anim);
  698. animation.InnerAnimations = fixNestedAnimations(animation.InnerAnimations);
  699. result.Add(animation);
  700. }
  701. return result;
  702. }
  703. }
  704. }