File indexing completed on 2025-06-01 04:02:27

0001 from .. import base
0002 from lottie import objects, NVector
0003 from .test_helpers import TestTransform
0004 
0005 
0006 class TestAnimation(base.TestCase):
0007     def test_default(self):
0008         an = objects.Animation()
0009         self.assertDictEqual(
0010             an.to_dict(),
0011             {
0012                 "ip": 0,
0013                 "op": 60,
0014                 "fr": 60,
0015                 "w": 512,
0016                 "h": 512,
0017                 "ddd": 0,
0018                 "v": objects.Animation._version,
0019                 "layers": [],
0020                 "assets": [],
0021             }
0022         )
0023 
0024     def test_name(self):
0025         an = objects.Animation()
0026         an.name = "Foobar"
0027         self.assertDictEqual(
0028             an.to_dict(),
0029             {
0030                 "ip": 0,
0031                 "op": 60,
0032                 "fr": 60,
0033                 "w": 512,
0034                 "h": 512,
0035                 "ddd": 0,
0036                 "v": objects.Animation._version,
0037                 "layers": [],
0038                 "assets": [],
0039                 "nm": "Foobar"
0040             }
0041         )
0042 
0043     def test_n_frames(self):
0044         an = objects.Animation(180)
0045         self.assertDictEqual(
0046             an.to_dict(),
0047             {
0048                 "ip": 0,
0049                 "op": 180,
0050                 "fr": 60,
0051                 "w": 512,
0052                 "h": 512,
0053                 "ddd": 0,
0054                 "v": objects.Animation._version,
0055                 "layers": [],
0056                 "assets": [],
0057             }
0058         )
0059 
0060     def test_framerate(self):
0061         an = objects.Animation(60, 24)
0062         self.assertDictEqual(
0063             an.to_dict(),
0064             {
0065                 "ip": 0,
0066                 "op": 60,
0067                 "fr": 24,
0068                 "w": 512,
0069                 "h": 512,
0070                 "ddd": 0,
0071                 "v": objects.Animation._version,
0072                 "layers": [],
0073                 "assets": [],
0074             }
0075         )
0076 
0077     def test_layers(self):
0078         an = objects.Animation()
0079         an.add_layer(objects.NullLayer())
0080         an.add_layer(objects.ShapeLayer())
0081         an.insert_layer(0, objects.NullLayer())
0082         self.assertDictEqual(
0083             an.to_dict(),
0084             {
0085                 "ip": 0,
0086                 "op": 60,
0087                 "fr": 60,
0088                 "w": 512,
0089                 "h": 512,
0090                 "ddd": 0,
0091                 "v": objects.Animation._version,
0092                 "layers": [
0093                     {
0094                         "ty": 3,
0095                         "ks": TestTransform._plain_out,
0096                         "ao": 0,
0097                         "ddd": 0,
0098                         "st": 0,
0099                         "sr": 1,
0100                         "ind": 2,
0101                         "ip": 0,
0102                         "op": 60,
0103                         "bm": 0,
0104                     },
0105                     {
0106                         "ty": 3,
0107                         "ks": TestTransform._plain_out,
0108                         "ao": 0,
0109                         "ddd": 0,
0110                         "st": 0,
0111                         "sr": 1,
0112                         "ind": 0,
0113                         "ip": 0,
0114                         "op": 60,
0115                         "bm": 0,
0116                     },
0117                     {
0118                         "ty": 4,
0119                         "ks": TestTransform._plain_out,
0120                         "ao": 0,
0121                         "bm": 0,
0122                         "ddd": 0,
0123                         "st": 0,
0124                         "sr": 1,
0125                         "shapes": [],
0126                         "ind": 1,
0127                         "ip": 0,
0128                         "op": 60,
0129                     }
0130                 ],
0131                 "assets": [],
0132             }
0133         )
0134 
0135     def test_layers_preserve(self):
0136         an = objects.Animation()
0137         nl = objects.NullLayer()
0138         nl.index = 42
0139         nl.in_point = 10
0140         nl.out_point = 20
0141         an.add_layer(nl)
0142         self.assertDictEqual(
0143             an.to_dict(),
0144             {
0145                 "ip": 0,
0146                 "op": 60,
0147                 "fr": 60,
0148                 "w": 512,
0149                 "h": 512,
0150                 "ddd": 0,
0151                 "v": objects.Animation._version,
0152                 "layers": [
0153                     {
0154                         "ty": 3,
0155                         "ks": TestTransform._plain_out,
0156                         "ao": 0,
0157                         "ddd": 0,
0158                         "st": 0,
0159                         "sr": 1,
0160                         "bm": 0,
0161                         "ind": 42,
0162                         "ip": 10,
0163                         "op": 20,
0164                     },
0165                 ],
0166                 "assets": [],
0167             }
0168         )
0169 
0170     def test_clone_same(self):
0171         an = objects.Animation()
0172         nl = objects.NullLayer()
0173         nl.in_point = 10
0174         nl.out_point = 20
0175         an.add_layer(nl)
0176         an2 = an.clone()
0177 
0178         self.assertDictEqual(
0179             an2.to_dict(),
0180             {
0181                 "ip": 0,
0182                 "op": 60,
0183                 "fr": 60,
0184                 "w": 512,
0185                 "h": 512,
0186                 "ddd": 0,
0187                 "v": objects.Animation._version,
0188                 "layers": [
0189                     {
0190                         "ty": 3,
0191                         "ks": TestTransform._plain_out,
0192                         "ao": 0,
0193                         "ddd": 0,
0194                         "st": 0,
0195                         "sr": 1,
0196                         "bm": 0,
0197                         "ind": 0,
0198                         "ip": 10,
0199                         "op": 20,
0200                     },
0201                 ],
0202                 "assets": [],
0203             }
0204         )
0205 
0206     def test_clone_noalias(self):
0207         an = objects.Animation()
0208         nl = objects.NullLayer()
0209         nl.in_point = 10
0210         nl.out_point = 20
0211         an.add_layer(nl)
0212         an2 = an.clone()
0213 
0214         nl.in_point = 14
0215         nl.out_point = 24
0216         an.width = 100
0217         an.height = 200
0218         an.add_layer(objects.NullLayer())
0219 
0220         self.assertDictEqual(
0221             an2.to_dict(),
0222             {
0223                 "ip": 0,
0224                 "op": 60,
0225                 "fr": 60,
0226                 "w": 512,
0227                 "h": 512,
0228                 "ddd": 0,
0229                 "v": objects.Animation._version,
0230                 "layers": [
0231                     {
0232                         "ty": 3,
0233                         "ks": TestTransform._plain_out,
0234                         "ao": 0,
0235                         "ddd": 0,
0236                         "st": 0,
0237                         "sr": 1,
0238                         "bm": 0,
0239                         "ind": 0,
0240                         "ip": 10,
0241                         "op": 20,
0242                     },
0243                 ],
0244                 "assets": [],
0245             }
0246         )
0247 
0248         self.assertNotEqual(an2.to_dict(), an.to_dict())
0249 
0250     def test_sanitize_noanim(self):
0251         an = objects.Animation()
0252         an.add_layer(objects.NullLayer())
0253         an.width = 128
0254         an.height = 256
0255         an.frame_rate = 69
0256         an.tgs_sanitize()
0257         self.assertEqual(
0258             an.to_dict(),
0259             {
0260                 "ip": 0,
0261                 "op": 60,
0262                 "fr": 60,
0263                 "w": 512,
0264                 "h": 512,
0265                 "ddd": 0,
0266                 "v": objects.Animation._version,
0267                 "layers": [
0268                     {
0269                         "ty": 3,
0270                         "ks": {
0271                             "a": {"a": 0, "k": [0, 0]},
0272                             "p": {"a": 0, "k": [0, 0]},
0273                             "s": {"a": 0, "k": [200, 200]},
0274                             "r": {"a": 0, "k": 0},
0275                             "o": {"a": 0, "k": 100},
0276                             "sk": {"a": 0, "k": 0},
0277                             "sa": {"a": 0, "k": 0},
0278                         },
0279                         "ao": 0,
0280                         "ddd": 0,
0281                         "st": 0,
0282                         "sr": 1,
0283                         "bm": 0,
0284                         "ind": 0,
0285                         "ip": 0,
0286                         "op": 60,
0287                     },
0288                 ],
0289                 "assets": [],
0290             }
0291         )
0292 
0293     def test_sanitize_noop(self):
0294         an = objects.Animation()
0295         an.add_layer(objects.NullLayer())
0296         an.tgs_sanitize()
0297         self.assertEqual(
0298             an.to_dict(),
0299             {
0300                 "ip": 0,
0301                 "op": 60,
0302                 "fr": 60,
0303                 "w": 512,
0304                 "h": 512,
0305                 "ddd": 0,
0306                 "v": objects.Animation._version,
0307                 "layers": [
0308                     {
0309                         "ty": 3,
0310                         "ks": {
0311                             "a": {"a": 0, "k": [0, 0]},
0312                             "p": {"a": 0, "k": [0, 0]},
0313                             "s": {"a": 0, "k": [100, 100]},
0314                             "r": {"a": 0, "k": 0},
0315                             "o": {"a": 0, "k": 100},
0316                             "sk": {"a": 0, "k": 0},
0317                             "sa": {"a": 0, "k": 0},
0318                         },
0319                         "ao": 0,
0320                         "ddd": 0,
0321                         "st": 0,
0322                         "sr": 1,
0323                         "bm": 0,
0324                         "ind": 0,
0325                         "ip": 0,
0326                         "op": 60,
0327                     },
0328                 ],
0329                 "assets": [],
0330             }
0331         )
0332 
0333     def test_sanitize_anim(self):
0334         an = objects.Animation()
0335         nl = an.add_layer(objects.NullLayer())
0336         nl.transform.scale.add_keyframe(0, NVector(50, 50))
0337         nl.transform.scale.add_keyframe(60, NVector(200, 200))
0338         nl.transform.scale.keyframes[-1].start = None
0339         an.width = 128
0340         an.height = 256
0341         an.frame_rate = 69
0342         an.tgs_sanitize()
0343         self.assertEqual(
0344             an.to_dict(),
0345             {
0346                 "ip": 0,
0347                 "op": 60,
0348                 "fr": 60,
0349                 "w": 512,
0350                 "h": 512,
0351                 "ddd": 0,
0352                 "v": objects.Animation._version,
0353                 "layers": [
0354                     {
0355                         "ty": 3,
0356                         "ks": {
0357                             "a": {"a": 0, "k": [0, 0]},
0358                             "p": {"a": 0, "k": [0, 0]},
0359                             "s": {"a": 1, "k": [
0360                                 {
0361                                     "s": [100, 100],
0362                                     "e": [400, 400],
0363                                     "t": 0,
0364                                     "o": {"x": [0], "y": [0]},
0365                                     "i": {"x": [1], "y": [1]},
0366                                 },
0367                                 {
0368                                     "t": 60,
0369                                 },
0370                             ]},
0371                             "r": {"a": 0, "k": 0},
0372                             "o": {"a": 0, "k": 100},
0373                             "sk": {"a": 0, "k": 0},
0374                             "sa": {"a": 0, "k": 0},
0375                         },
0376                         "ao": 0,
0377                         "ddd": 0,
0378                         "st": 0,
0379                         "sr": 1,
0380                         "bm": 0,
0381                         "ind": 0,
0382                         "ip": 0,
0383                         "op": 60,
0384                     },
0385                 ],
0386                 "assets": [],
0387             }
0388         )
0389 
0390     def test_sanitize_lowfr(self):
0391         an = objects.Animation()
0392         an.add_layer(objects.NullLayer())
0393         an.frame_rate = 23
0394         an.tgs_sanitize()
0395         self.assertEqual(
0396             an.to_dict(),
0397             {
0398                 "ip": 0,
0399                 "op": 60,
0400                 "fr": 30,
0401                 "w": 512,
0402                 "h": 512,
0403                 "ddd": 0,
0404                 "v": objects.Animation._version,
0405                 "layers": [
0406                     {
0407                         "ty": 3,
0408                         "ks": {
0409                             "a": {"a": 0, "k": [0, 0]},
0410                             "p": {"a": 0, "k": [0, 0]},
0411                             "s": {"a": 0, "k": [100, 100]},
0412                             "r": {"a": 0, "k": 0},
0413                             "o": {"a": 0, "k": 100},
0414                             "sk": {"a": 0, "k": 0},
0415                             "sa": {"a": 0, "k": 0},
0416                         },
0417                         "ao": 0,
0418                         "ddd": 0,
0419                         "st": 0,
0420                         "sr": 1,
0421                         "bm": 0,
0422                         "ind": 0,
0423                         "ip": 0,
0424                         "op": 60,
0425                     },
0426                 ],
0427                 "assets": [],
0428             }
0429         )
0430 
0431     def test_remove_layer(self):
0432         an = objects.Animation()
0433         l0 = objects.layers.NullLayer()
0434         l1 = objects.layers.NullLayer()
0435         l2 = objects.layers.NullLayer()
0436         l3 = objects.layers.NullLayer()
0437 
0438         an.add_layer(l0)
0439         an.add_layer(l1)
0440         an.add_layer(l2)
0441         an.add_layer(l3)
0442 
0443         l2.parent = l1
0444 
0445         self.assertIn(l0, an.layers)
0446         self.assertIn(l1, an.layers)
0447         self.assertIn(l2, an.layers)
0448         self.assertIn(l3, an.layers)
0449 
0450         an.remove_layer(l1)
0451 
0452         self.assertIn(l0, an.layers)
0453         self.assertNotIn(l1, an.layers)
0454         self.assertNotIn(l2, an.layers)
0455         self.assertIn(l3, an.layers)