JSONGenerator.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  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. //u up 默认 d down l left r right
  203. if (trans == null || trans.FirstChild == null)
  204. return null;
  205. TransitionAnimation result = new TransitionAnimation();
  206. if (trans.Speed != null && TransitionSpeedValues.Fast.Equals(trans.Speed.Value))
  207. result.Length = 500;
  208. else if (trans.Speed != null && TransitionSpeedValues.Slow.Equals(trans.Speed.Value))
  209. result.Length = 2000;
  210. else if (trans.Duration != null)
  211. result.Length = int.Parse(trans.Duration.Value);
  212. else
  213. result.Length = 1000;
  214. result.Start = 0;
  215. result.InitialState = -1;
  216. result.Repetitions = 1;
  217. if (trans.AdvanceOnClick != null)
  218. result.AdvanceOnClick = trans.AdvanceOnClick.Value;
  219. else result.AdvanceOnClick = true;
  220. if (typeof(StripsTransition) == trans.FirstChild.GetType())
  221. {
  222. StripsTransition transition = (StripsTransition)trans.FirstChild;
  223. result.Type = AnimationTypes.Strips;
  224. if (transition.Direction != null &&
  225. TransitionCornerDirectionValues.RightUp.Equals(transition.Direction.Value))
  226. result.AdditionalData = "7";
  227. else if (transition.Direction != null &&
  228. TransitionCornerDirectionValues.LeftDown.Equals(transition.Direction.Value))
  229. result.AdditionalData = "9";
  230. else if (transition.Direction != null &&
  231. TransitionCornerDirectionValues.RightDown.Equals(transition.Direction.Value))
  232. result.AdditionalData = "8";
  233. else
  234. result.AdditionalData = "6";
  235. }
  236. else if (typeof(PushTransition) == trans.FirstChild.GetType())
  237. {
  238. PushTransition transition = (PushTransition)trans.FirstChild;
  239. result.Type = AnimationTypes.Push;
  240. if (transition.Direction != null &&
  241. TransitionSlideDirectionValues.Right.Equals(transition.Direction.Value))
  242. result.AdditionalData = "3";
  243. else if (transition.Direction != null &&
  244. TransitionSlideDirectionValues.Up.Equals(transition.Direction.Value))
  245. result.AdditionalData = "4";
  246. else if (transition.Direction != null &&
  247. TransitionSlideDirectionValues.Left.Equals(transition.Direction.Value))
  248. result.AdditionalData = "2";
  249. else result.AdditionalData = "1";
  250. }
  251. else if (typeof(WipeTransition) == trans.FirstChild.GetType())
  252. {
  253. WipeTransition transition = (WipeTransition)trans.FirstChild;
  254. result.Type = AnimationTypes.Wipe;
  255. if (transition.Direction != null &&
  256. TransitionSlideDirectionValues.Right.Equals(transition.Direction.Value))
  257. result.AdditionalData = "4";
  258. else if (transition.Direction != null &&
  259. TransitionSlideDirectionValues.Up.Equals(transition.Direction.Value))
  260. result.AdditionalData = "3";
  261. else if (transition.Direction != null &&
  262. TransitionSlideDirectionValues.Left.Equals(transition.Direction.Value))
  263. result.AdditionalData = "2";
  264. else result.AdditionalData = "1";
  265. }
  266. else if (typeof(FadeTransition) == trans.FirstChild.GetType())
  267. {
  268. FadeTransition transition = (FadeTransition)trans.FirstChild;
  269. result.Type = AnimationTypes.Fade;
  270. if (transition.ThroughBlack != null && transition.ThroughBlack.Value)
  271. result.Type = AnimationTypes.FadeThroughBlack;
  272. result.AdditionalData = "1";
  273. }
  274. else if (typeof(CutTransition) == trans.FirstChild.GetType())
  275. {
  276. CutTransition transition = (CutTransition)trans.FirstChild;
  277. result.Type = AnimationTypes.Cut;
  278. result.AdditionalData = "2";
  279. if (transition.ThroughBlack != null && transition.ThroughBlack.Value)
  280. {
  281. result.Type = AnimationTypes.CutThroughBlack;
  282. result.AdditionalData = "3";
  283. }
  284. }
  285. else if (typeof(DissolveTransition) == trans.FirstChild.GetType())
  286. {
  287. result.Type = AnimationTypes.DissolveIn;
  288. result.AdditionalData = "1";
  289. }
  290. else if (typeof(WedgeTransition) == trans.FirstChild.GetType())
  291. {
  292. result.Type = AnimationTypes.Wedge;
  293. result.AdditionalData = "1";
  294. }
  295. else if (typeof(PullTransition) == trans.FirstChild.GetType())
  296. {
  297. PullTransition transition = (PullTransition)trans.FirstChild;
  298. result.Type = AnimationTypes.UnCover;
  299. if (transition.Direction != null && "d".Equals(transition.Direction.Value.ToString()))
  300. result.AdditionalData = "9";
  301. else if (transition.Direction != null && "r".Equals(transition.Direction.Value.ToString()))
  302. result.AdditionalData = "11";
  303. else if (transition.Direction != null && "u".Equals(transition.Direction.Value.ToString()))
  304. result.AdditionalData = "12";
  305. else if (transition.Direction != null && "ld".Equals(transition.Direction.Value.ToString()))
  306. result.AdditionalData = "13";
  307. else if (transition.Direction != null && "lu".Equals(transition.Direction.Value.ToString()))
  308. result.AdditionalData = "14";
  309. else if (transition.Direction != null && "rd".Equals(transition.Direction.Value.ToString()))
  310. result.AdditionalData = "15";
  311. else if (transition.Direction != null && "ru".Equals(transition.Direction.Value.ToString()))
  312. result.AdditionalData = "16";
  313. else result.AdditionalData = "10";
  314. }
  315. else if (typeof(ZoomTransition) == trans.FirstChild.GetType())
  316. {
  317. ZoomTransition transition = (ZoomTransition)trans.FirstChild;
  318. result.Type = AnimationTypes.Box;
  319. if (transition.Direction != null && TransitionInOutDirectionValues.In == transition.Direction.Value)
  320. result.AdditionalData = "19";
  321. else result.AdditionalData = "20";
  322. }
  323. else if (typeof(ZoomTransition) == trans.FirstChild.GetType())
  324. {
  325. ZoomTransition transition = (ZoomTransition)trans.FirstChild;
  326. result.Type = AnimationTypes.Box;
  327. if (transition.Direction != null && TransitionInOutDirectionValues.In == transition.Direction.Value)
  328. result.AdditionalData = "19";
  329. else result.AdditionalData = "20";
  330. }
  331. else if (typeof(WheelTransition) == trans.FirstChild.GetType())
  332. {
  333. WheelTransition transition = (WheelTransition)trans.FirstChild;
  334. result.Type = AnimationTypes.Wheel;
  335. if (transition.Spokes != null && transition.Spokes.Value == 1)
  336. result.AdditionalData = "1";
  337. else if (transition.Spokes != null && transition.Spokes.Value == 2)
  338. result.AdditionalData = "2";
  339. else if (transition.Spokes != null && transition.Spokes.Value == 3)
  340. result.AdditionalData = "3";
  341. else if (transition.Spokes != null && transition.Spokes.Value == 8)
  342. result.AdditionalData = "8";
  343. else result.AdditionalData = "4";
  344. }
  345. else if (typeof(SplitTransition) == trans.FirstChild.GetType())
  346. {
  347. SplitTransition transition = (SplitTransition)trans.FirstChild;
  348. result.Type = AnimationTypes.Split;
  349. if (transition.Direction != null && TransitionInOutDirectionValues.In == transition.Direction.Value)
  350. {
  351. if (transition.Orientation != null && DirectionValues.Vertical.Equals(transition.Orientation.Value))
  352. result.AdditionalData = "25";
  353. else
  354. result.AdditionalData = "23";
  355. }
  356. else
  357. {
  358. if (transition.Orientation != null && DirectionValues.Vertical.Equals(transition.Orientation.Value))
  359. result.AdditionalData = "26";
  360. else
  361. result.AdditionalData = "24";
  362. }
  363. }
  364. else if (typeof(CircleTransition) == trans.FirstChild.GetType())
  365. {
  366. result.Type = AnimationTypes.Circle;
  367. result.AdditionalData = "20";
  368. }
  369. else if (typeof(DiamondTransition) == trans.FirstChild.GetType())
  370. {
  371. result.Type = AnimationTypes.Diamond;
  372. result.AdditionalData = "20";
  373. }
  374. else if (typeof(PlusTransition) == trans.FirstChild.GetType())
  375. {
  376. result.Type = AnimationTypes.Plus;
  377. result.AdditionalData = "20";
  378. }
  379. else if (typeof(NewsflashTransition) == trans.FirstChild.GetType())
  380. {
  381. result.Type = AnimationTypes.Newsflash;
  382. result.AdditionalData = "20";
  383. }
  384. return result;
  385. }
  386. /// <summary>
  387. /// 动画emph (Preset Type Enum ( Emphasis )) Emphasis Preset
  388. ///entr(Preset Type Enum (Entrance )) Entrance Preset
  389. ///exit(Exit) Exit Preset
  390. ///mediacall(Preset Type Enum (Media Call )) Media Call Preset
  391. ///path(Preset Type Enum (Path )) Path Preset
  392. ///verb(Preset Type Enum (Verb )) Verb Preset
  393. /// </summary>
  394. /// <param name="commonTimeNode"></param>
  395. /// <param name="SlideSizes"></param>
  396. /// <returns></returns>
  397. public SimpleAnimation getSimpleAnimationFromCommonTimeNodePreset(CommonTimeNode commonTimeNode, SlideSize SlideSizes)
  398. {
  399. SimpleAnimation result = new SimpleAnimation();
  400. ///路径方式
  401. if (AnimationTypes.TypePath.Equals(commonTimeNode.PresetClass))
  402. {
  403. return new MotionPathAnimation(commonTimeNode, Slide.slideIndex, SlideSizes);
  404. }
  405. ///进入
  406. else if (AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass))
  407. {
  408. result.InitialState = 1;
  409. }
  410. ///退出
  411. else if (AnimationTypes.TypeExit.Equals(commonTimeNode.PresetClass))
  412. {
  413. result.InitialState = 2;
  414. }
  415. ///强调
  416. else if (AnimationTypes.TypeEmphasis.Equals(commonTimeNode.PresetClass))
  417. {
  418. result.InitialState = 3;
  419. }
  420. else if (AnimationTypes.Verb.Equals(commonTimeNode.PresetClass))
  421. {
  422. ///未用到
  423. result.InitialState = 4;
  424. }
  425. else if (AnimationTypes.Mediacall.Equals(commonTimeNode.PresetClass))
  426. {
  427. ///未用到
  428. result.InitialState = 5;
  429. }
  430. /*
  431. 1 emph (Preset Type Enum ( Emphasis )) Emphasis Preset
  432. 1 entr (Preset Type Enum ( Entrance )) Entrance Preset
  433. 1 exit (Exit) Exit Preset
  434. mediacall (Preset Type Enum ( Media Call )) Media Call Preset
  435. path (Preset Type Enum ( Path )) Path Preset
  436. verb (Preset Type Enum ( Verb )) Verb Preset
  437. */
  438. /// TODO 其他类型 mediacall(Preset Type Enum (Media Call )) Media Call Preset
  439. /// verb(Preset Type Enum (Verb )) Verb Preset
  440. else return null;
  441. if (commonTimeNode.PresetId == null)
  442. return null;
  443. result.timingType = commonTimeNode.NodeType;
  444. result.Subtype = commonTimeNode.PresetSubtype;
  445. //Get the speed from one of the nodes common behavior. Hopefully all nodes have the same speed (since the animation is the same).
  446. var a = commonTimeNode.Descendants();
  447. foreach (Object xmlEl in commonTimeNode.Descendants())
  448. if (xmlEl.GetType().Equals(typeof(CommonBehavior)))
  449. {
  450. CommonBehavior bhvr = ((CommonBehavior)xmlEl);
  451. if (bhvr.CommonTimeNode != null)
  452. {
  453. result.FixAnimationTimings(bhvr, Slide.slideIndex);
  454. if (result.Length <= 1)
  455. continue;
  456. if (result.Start == 0)
  457. {
  458. Condition condition = commonTimeNode.StartConditionList.FirstChild as Condition;
  459. if (!condition.Delay.Equals("indefinite"))
  460. result.Start = int.Parse(condition.Delay);
  461. }
  462. break;
  463. }
  464. }
  465. if (result.Length <= 1)
  466. result.Length = 100; //Default value??
  467. if (AnimationTypes.TypeEmphasis.Equals(commonTimeNode.PresetClass))
  468. result = handleEmphasisAnimation(commonTimeNode, result);
  469. else
  470. result = handleEntranceAnimation(commonTimeNode, result);
  471. if (result.AdditionalData == null || result.AdditionalData == "0") //There are default values. Horizontal In = horizontal + in ;)
  472. //此属性是位标志,指定一个方向或一些其他属性的效果。 例如它可以设置指定"从底部"飞入效果或"加粗"更改字体样式效果。
  473. switch (commonTimeNode.PresetSubtype.Value)
  474. {
  475. case 0: result.AdditionalData = "0"; break;
  476. case 4: result.AdditionalData = "3"; break; //From bottom
  477. case 2: result.AdditionalData = "2"; break; //From right
  478. case 1: result.AdditionalData = "1"; break; //From top
  479. case 8: result.AdditionalData = "4"; break; //From left
  480. case 6: result.AdditionalData = "8"; break; //Bottom right
  481. case 3: result.AdditionalData = "7"; break; //Top right
  482. case 9: result.AdditionalData = "6"; break; //Top right
  483. case 12: result.AdditionalData = "9"; break; //Bottom left
  484. case 10: result.AdditionalData = "16"; break; //Horizontal
  485. case 5: result.AdditionalData = "17"; break; //Vertical
  486. case 26: result.AdditionalData = "23"; break; //Horizontal in
  487. case 42: result.AdditionalData = "24"; break; //Horizontal out
  488. case 21: result.AdditionalData = "25"; break; //Vertical in
  489. case 37: result.AdditionalData = "26"; break; //Vertical out
  490. case 16: result.AdditionalData = "19"; break; //in
  491. case 32: result.AdditionalData = "20"; break; //out
  492. default: result.AdditionalData = commonTimeNode.PresetSubtype.Value+"";break;
  493. }
  494. checkIsText(result);
  495. return result;
  496. }
  497. private void checkIsText(SimpleAnimation result)
  498. {
  499. int res;
  500. bool isTextWithEffect = int.TryParse(result.ObjectId, out res) && PPTShape.effectShapes.Contains(Slide.slideIndex + "_" + res);
  501. int tryParse = 0;
  502. if (!int.TryParse(result.ObjectId, out tryParse) || isTextWithEffect)
  503. {
  504. return;//if it is like 123p -> return;
  505. }
  506. foreach (PPTShapeBase shape in Slide.ContainerShape.Elements)
  507. if (typeof(PPTShape).Equals(shape.GetType()) && ((PPTShape)shape).IsText)
  508. {
  509. string shapeId = shape.NonVisualShapeProp.Id;
  510. string shapeObjectId = "s1s" + result.ObjectId;
  511. if (shapeId.Equals(shapeObjectId))
  512. {
  513. result.ObjectId = result.ObjectId + "p0";// TODO check when multiple paragraphs
  514. }
  515. }
  516. }
  517. /// <summary>
  518. /// 获取强调
  519. /// </summary>
  520. /// <param name="commonTimeNode"></param>
  521. /// <param name="simpleAnim"></param>
  522. /// <returns></returns>
  523. private EmphasisAnimation handleEmphasisAnimation(CommonTimeNode commonTimeNode, SimpleAnimation simpleAnim)
  524. {
  525. EmphasisAnimation result = new EmphasisAnimation(simpleAnim);
  526. result.setRgbColor(commonTimeNode, Slide);
  527. switch (commonTimeNode.PresetId.Value) //Presets for Entrance/Exit
  528. {
  529. case 3: result.Type = AnimationTypes.ChangeFontColor; break;
  530. case 19: result.Type = AnimationTypes.ColorBlend; break;
  531. case 14: result.Type = AnimationTypes.Blast; break;
  532. case 26: result.Type = AnimationTypes.FlashBulb; break;
  533. case 35: result.Type = AnimationTypes.Blink; break;
  534. case 9:
  535. {
  536. result.Type = AnimationTypes.Transparency;
  537. result.Transparency = getTransparence(commonTimeNode);
  538. }
  539. break;
  540. case 20:
  541. {
  542. result.Type = AnimationTypes.ColorWave;
  543. result.Length *= 2;
  544. result.e2 = result.Length / 10;
  545. result.e1 = 2;
  546. }
  547. break;
  548. case 16:
  549. {
  550. result.Type = AnimationTypes.BrushOnColor;
  551. result.e2 = result.Length / 25;
  552. result.e1 = 2;
  553. }
  554. break;
  555. case 33:
  556. {
  557. result.Type = AnimationTypes.VerticalHighlight;
  558. result.Length *= 2;
  559. }
  560. break;
  561. case 27:
  562. {
  563. result.Type = AnimationTypes.Flicker;
  564. result.Length *= 2;
  565. }
  566. break;
  567. case 36:
  568. {
  569. result.Type = AnimationTypes.Shimmer;
  570. result.e2 = result.Length / 5;
  571. result.Length *= 2;
  572. foreach (Object obj in commonTimeNode.Descendants())
  573. if (obj.GetType().Equals(typeof(AnimateScale)))
  574. {
  575. ((EmphasisAnimation)result).ScaleX = ((AnimateScale)obj).ToPosition.X.Value / 1000;
  576. ((EmphasisAnimation)result).ScaleY = ((AnimateScale)obj).ToPosition.Y.Value / 1000;
  577. break;
  578. }
  579. }
  580. break;
  581. case 28:
  582. {
  583. result.Type = AnimationTypes.GrowwithColor;
  584. result.e2 = result.Length / 10;
  585. result.e1 = 2;
  586. }
  587. break;
  588. case 32:
  589. {
  590. result.Type = AnimationTypes.Teeter;
  591. result.Length *= 2;
  592. }
  593. break;
  594. case 34:
  595. {
  596. result.Type = AnimationTypes.Wave;
  597. result.e2 = result.Length / 5;
  598. result.Length *= 2;
  599. }
  600. break;
  601. case 8:
  602. {
  603. result.Type = AnimationTypes.Spin;
  604. foreach (Object obj in commonTimeNode.Descendants())
  605. if (obj.GetType().Equals(typeof(AnimateRotation)))
  606. {
  607. ((EmphasisAnimation)result).RotationDegrees = ((AnimateRotation)obj).By / 60000;
  608. break;
  609. }
  610. }
  611. break;
  612. case 6:
  613. {
  614. result.Type = AnimationTypes.GrowShrink;
  615. foreach (Object obj in commonTimeNode.Descendants())
  616. if (obj.GetType().Equals(typeof(AnimateScale)))
  617. {
  618. ((EmphasisAnimation)result).ScaleX = ((AnimateScale)obj).ByPosition.X.Value / 1000;
  619. ((EmphasisAnimation)result).ScaleY = ((AnimateScale)obj).ByPosition.Y.Value / 1000;
  620. break;
  621. }
  622. }
  623. break;
  624. default: result.Type = "defaul+" + commonTimeNode.PresetId.Value; return result;
  625. }
  626. return result;
  627. }
  628. /// <summary>
  629. /// 获取进入
  630. /// </summary>
  631. /// <param name="commonTimeNode"></param>
  632. /// <param name="result"></param>
  633. /// <returns></returns>
  634. private SimpleAnimation handleEntranceAnimation(CommonTimeNode commonTimeNode, SimpleAnimation result)
  635. {
  636. switch (commonTimeNode.PresetId.Value) //Presets for Entrance/Exit
  637. {
  638. case 1: result.Type = AnimationTypes.Appear; break;
  639. case 54: result.Type = AnimationTypes.Glide; break;
  640. case 19: result.Type = AnimationTypes.Swivel; break;
  641. case 42: result.Type = AnimationTypes.Ascend; break;
  642. case 3: result.Type = AnimationTypes.Blinds; break;
  643. case 4: result.Type = AnimationTypes.Box; break;
  644. case 25: result.Type = AnimationTypes.Boomerang; break;
  645. case 43: result.Type = AnimationTypes.CenterRevolve; break;
  646. case 5: result.Type = AnimationTypes.Checkerboard; break;
  647. case 50: result.Type = AnimationTypes.Compress; break;
  648. case 7: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.CrawlIn : AnimationTypes.CrawlOut; break;
  649. case 47: result.Type = AnimationTypes.Descend; break;
  650. case 48: result.Type = AnimationTypes.Sling; break;
  651. case 29: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.EaseIn : AnimationTypes.EaseOut; break;
  652. case 55: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.Expand : AnimationTypes.Contract; break;
  653. case 10: result.Type = AnimationTypes.Fade; break;
  654. case 53: result.Type = AnimationTypes.FadedZoom; break;
  655. case 11: result.Type = AnimationTypes.FlashOnce; break;
  656. case 2: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.FlyIn : AnimationTypes.FlyOut; break;
  657. case 58: result.Type = AnimationTypes.Fold; break;
  658. case 31: result.Type = AnimationTypes.GrowTurn; break;
  659. case 12: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.PeekIn : AnimationTypes.PeekOut; break;
  660. case 16: result.Type = AnimationTypes.Split; break;
  661. case 35: result.Type = AnimationTypes.Pinwheel; break;
  662. case 14: result.Type = AnimationTypes.RandomBars; break;
  663. case 37: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.RiseUp : AnimationTypes.SinkDown; break;
  664. case 49: result.Type = AnimationTypes.Spinner; break;
  665. case 22: result.Type = AnimationTypes.Wipe; break;
  666. case 18: result.Type = AnimationTypes.Strips; break;
  667. case 26: result.Type = AnimationTypes.Bounce; result.Length = (int)((result.Length * 100) / 29); break;//time tunning
  668. case 6: result.Type = AnimationTypes.Circle; break;
  669. case 28: result.Type = AnimationTypes.Credits; break;
  670. case 52: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.CurveUp : AnimationTypes.CurveDown; break;
  671. case 8: result.Type = AnimationTypes.Diamond; break;
  672. case 9: result.Type = AnimationTypes.Dissolve; break;
  673. case 30: result.Type = AnimationTypes.Float; break;
  674. case 34: result.Type = AnimationTypes.LightSpeed; result.Length = (int)((result.Length * 5) / 3); break;//time tunning
  675. case 51: result.Type = AnimationTypes.Magnify; result.Length = (int)((result.Length * 200) / 77); break;//time tunning
  676. case 13: result.Type = AnimationTypes.Plus; break;
  677. case 15: result.Type = AnimationTypes.TypeEntrance.Equals(commonTimeNode.PresetClass) ? AnimationTypes.SpiralIn : AnimationTypes.SpiralOut; break;
  678. case 17: result.Type = AnimationTypes.Stretch; break;
  679. case 39: result.Type = AnimationTypes.Thread; break;
  680. case 20: result.Type = AnimationTypes.Wedge; break;
  681. case 21: result.Type = AnimationTypes.Wheel; result.AdditionalData = "" + commonTimeNode.PresetSubtype.Value; break;
  682. case 23: result.Type = AnimationTypes.Zoom; break;
  683. ///补充
  684. // case 45:result.Type= AnimationTypes.Zoom; break;
  685. default:Console.WriteLine(commonTimeNode.PresetId.Value+" "); result.Type = "defaul+"+ commonTimeNode.PresetId.Value; return result;
  686. }
  687. return result;
  688. }
  689. private double getTransparence(CommonTimeNode commonTimeNode)
  690. {
  691. if (typeof(AnimateEffect) == commonTimeNode.LastChild.LastChild.GetType())
  692. {
  693. AnimateEffect animEffect = (AnimateEffect)commonTimeNode.LastChild.LastChild;
  694. string value = animEffect.PropertyList.Value;
  695. if (value != null && value.IndexOf("opacity:") != -1)
  696. {
  697. string opacityStr = value.Substring(9);//we need 0.75 from "opacity: 0.75"
  698. double opacity = double.Parse(opacityStr, CultureInfo.GetCultureInfo("en-US").NumberFormat);
  699. return 1 - opacity;
  700. }
  701. }
  702. return 0;
  703. }
  704. private List<IAnimation> fixNestedAnimations(List<IAnimation> animations)
  705. {
  706. if (animations == null || animations.Count == 0)
  707. return null;
  708. List<IAnimation> result = new List<IAnimation>();
  709. foreach (IAnimation anim in animations)
  710. {
  711. IAnimation animation = getAnimationFromNested(anim);
  712. animation.InnerAnimations = fixNestedAnimations(animation.InnerAnimations);
  713. result.Add(animation);
  714. }
  715. return result;
  716. }
  717. }
  718. }