Coverage for lib/lottie/exporters/core.py: 31%

64 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-20 16:17 +0100

1import sys 

2import json 

3import gzip 

4import codecs 

5 

6from .base import exporter 

7from ..utils.file import open_file 

8from ..parsers.baseporter import ExtraOption 

9from .tgs_validator import TgsValidator 

10 

11 

12@exporter("Lottie JSON", ["json"], [], {"pretty"}, "lottie") 

13def export_lottie(animation, file, pretty=False): 

14 with open_file(file) as fp: 

15 kw = {} 

16 if pretty: 

17 kw = dict(indent=4) 

18 json.dump(animation.to_dict(), fp, **kw) 

19 

20 

21@exporter("Telegram Animated Sticker", ["tgs"], [ 

22 ExtraOption("no_sanitize", help="Disable Sticker fit", action="store_false", dest="sanitize"), 

23 ExtraOption("no_validate", help="Disable feature validation", action="store_false", dest="validate"), 

24]) 

25def export_tgs(animation, file, sanitize=False, validate=False): 

26 if sanitize: 

27 animation.tgs_sanitize() 

28 

29 with gzip.open(file, "wb") as gzfile: 

30 lottie_dict = animation.to_dict() 

31 lottie_dict["tgs"] = 1 

32 json.dump(lottie_dict, codecs.getwriter('utf-8')(gzfile)) 

33 

34 if validate: 

35 validator = TgsValidator() 

36 validator(animation) 

37 validator.check_file_size(file) 

38 if validator.errors: 

39 sys.stdout.write("\n".join(map(str, validator.errors))+"\n") 

40 

41 

42class HtmlOutput: 

43 def __init__(self, animation, file): 

44 self.animation = animation 

45 self.file = file 

46 

47 def style(self): 

48 self.file.write(""" 

49 <style> 

50 #bodymovin { width: %spx; height: %spx; margin: auto; 

51 background-color: white; 

52 background-size: 64px 64px; 

53 background-image: 

54 linear-gradient(to right, rgba(0, 0, 0, .3) 50%%, transparent 50%%), 

55 linear-gradient(to bottom, rgba(0, 0, 0, .3) 50%%, transparent 50%%), 

56 linear-gradient(to bottom, white 50%%, transparent 50%%), 

57 linear-gradient(to right, transparent 50%%, rgba(0, 0, 0, .5) 50%%); 

58 } 

59 </style> 

60 <script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.5.3/lottie.js"></script> 

61 """ % (self.animation.width, self.animation.height)) 

62 

63 def body_pre(self): 

64 self.file.write(""" 

65<div id="bodymovin"></div> 

66 

67<script> 

68 var animData = { 

69 container: document.getElementById('bodymovin'), 

70 renderer: 'svg', 

71 loop: true, 

72 autoplay: true, 

73 """) 

74 

75 def body_embedded(self): 

76 self.file.write("animationData: ") 

77 export_lottie(self.animation, self.file, True) 

78 

79 def body_post(self): 

80 self.file.write(""" 

81 }; 

82 var anim = bodymovin.loadAnimation(animData); 

83</script>""") 

84 

85 def html_begin(self): 

86 self.file.write("""<!DOCTYPE html> 

87<html> 

88<head> 

89 <meta charset="utf-8" /> 

90 <style> 

91 html, body { width: 100%; height: 100%; margin: 0; } 

92 body { display: flex; } 

93 </style>""") 

94 self.style() 

95 self.file.write("</head><body>") 

96 

97 def html_end(self): 

98 self.file.write("</body></html>") 

99 

100 

101@exporter("Lottie HTML", ["html", "htm"]) 

102def export_embedded_html(animation, file): 

103 with open_file(file) as fp: 

104 out = HtmlOutput(animation, fp) 

105 out.html_begin() 

106 out.body_pre() 

107 out.body_embedded() 

108 out.body_post() 

109 out.html_end() 

110 

111 

112def export_linked_html(animation, file, path): 

113 with open_file(file) as fp: 

114 out = HtmlOutput(animation, fp) 

115 out.html_begin() 

116 out.body_pre() 

117 file.write("path: %r" % path) 

118 out.body_post() 

119 out.html_end()