def test_group_rotate(self): lot = objects.Animation() ref_sl = lot.add_layer(objects.ShapeLayer()) ref_rect = ref_sl.add_shape(objects.Rect()) ref_rect.position.value = NVector(128, 128) ref_rect.size.value = NVector(256, 256) ref_sl.add_shape(objects.Fill(Color(1, 0, 0))) ref_sl.transform.opacity.value = 80 sl = lot.add_layer(objects.ShapeLayer()) rect = sl.add_shape(objects.Rect()) rect.position.value = NVector(128, 128) rect.size.value = NVector(256, 256) sl.add_shape(objects.Fill(Color(1, 1, 0))) sl.transform.rotation.value = 20 sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 2) self.assertIsInstance(sif.layers[0], api.GroupLayer) self.assertIsInstance(sif.layers[1], api.GroupLayer) self.assertAlmostEqual(sif.layers[0].amount.value, 1) self.assertAlmostEqual(sif.layers[1].amount.value, 0.8) self.assertAlmostEqual(sif.layers[0].transformation.angle.value, 20) self.assertAlmostEqual(sif.layers[1].transformation.angle.value, 0)
def test_group_scale(self): lot = objects.Animation() ref_sl = lot.add_layer(objects.ShapeLayer()) ref_rect = ref_sl.add_shape(objects.Rect()) ref_rect.position.value = NVector(128, 128) ref_rect.size.value = NVector(256, 256) ref_sl.add_shape(objects.Fill(Color(1, 0, 0))) ref_sl.transform.opacity.value = 80 sl = lot.add_layer(objects.ShapeLayer()) rect = sl.add_shape(objects.Rect()) rect.position.value = NVector(128, 128) rect.size.value = NVector(256, 256) sl.add_shape(objects.Fill(Color(1, 1, 0))) sl.transform.scale.value = NVector(180, 50) sl.transform.position.value = NVector(256, 256) sl.transform.anchor_point.value = NVector(128, 128) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 2) self.assertIsInstance(sif.layers[0], api.GroupLayer) self.assertIsInstance(sif.layers[1], api.GroupLayer) self.assertAlmostEqual(sif.layers[0].amount.value, 1) self.assertAlmostEqual(sif.layers[1].amount.value, 0.8) self.assert_nvector_equal(sif.layers[0].transformation.offset.value, NVector(256, 256)) self.assert_nvector_equal(sif.layers[0].origin.value, NVector(128, 128)) self.assert_nvector_equal(sif.layers[0].transformation.scale.value, NVector(1.8, .5)) self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0)) self.assert_nvector_equal(sif.layers[1].origin.value, NVector(0, 0)) self.assert_nvector_equal(sif.layers[1].transformation.scale.value, NVector(1, 1))
def test_animated_real(self): lot = objects.Animation() ref_sl = lot.add_layer(objects.ShapeLayer()) ref_rect = ref_sl.add_shape(objects.Rect()) ref_rect.position.value = NVector(128, 128) ref_rect.size.value = NVector(256, 256) ref_sl.add_shape(objects.Fill(Color(1, 0, 0))) ref_sl.transform.opacity.add_keyframe(0, 100) ref_sl.transform.opacity.add_keyframe(30, 0) ref_sl.transform.opacity.add_keyframe(60, 100) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) amount = sif.layers[0].amount self.assertAlmostEqual(amount.keyframes[0].value, 1) self.assertAlmostEqual(amount.keyframes[1].value, 0) self.assertAlmostEqual(amount.keyframes[2].value, 1) self.assertEqual(amount.keyframes[0].time, api.FrameTime.frame(0)) self.assertEqual(amount.keyframes[1].time, api.FrameTime.frame(30)) self.assertEqual(amount.keyframes[2].time, api.FrameTime.frame(60))
def test_star_hidden(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) star = sl.add_shape(objects.Star()) star.hidden = True star.name = "Star" star.rotation.value = 20 star.inner_radius.value = 64 star.outer_radius.value = 128 star.position.value = NVector(256, 256) sl.add_shape(objects.Fill(Color(1, 1, 0))) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) grp = sif.layers[0] self.assertEqual(len(grp.layers), 1) self.assertIsInstance(grp.layers[0], api.RegionLayer) self.assertTrue(grp.active) rgl = grp.layers[0] self.assertEqual(rgl.desc, "Star") self.assertEqual(len(rgl.bline.points), 10) self.assert_nvector_equal(rgl.origin.value, star.position.value) self.assert_nvector_equal(rgl.color.value, sif.make_color(1, 1, 0, 1)) self.assertFalse(rgl.active)
def test_animated_vector(self): lot = objects.Animation() ref_sl = lot.add_layer(objects.ShapeLayer()) ref_rect = ref_sl.add_shape(objects.Rect()) ref_rect.position.value = NVector(128, 128) ref_rect.size.value = NVector(256, 256) ref_sl.add_shape(objects.Fill(Color(1, 0, 0))) ref_sl.transform.opacity.value = 80 sl = lot.add_layer(objects.ShapeLayer()) rect = sl.add_shape(objects.Rect()) rect.position.value = NVector(128, 128) rect.size.value = NVector(256, 256) sl.add_shape(objects.Fill(Color(1, 1, 0))) sl.transform.position.add_keyframe(0, NVector(0, 0)) sl.transform.position.add_keyframe(30, NVector(256, 256)) sl.transform.position.add_keyframe(60, NVector(0, 0)) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 2) self.assertIsInstance(sif.layers[0], api.GroupLayer) self.assertIsInstance(sif.layers[1], api.GroupLayer) self.assertAlmostEqual(sif.layers[0].amount.value, 1) self.assertAlmostEqual(sif.layers[1].amount.value, 0.8) self.assert_nvector_equal(sif.layers[1].transformation.offset.value, NVector(0, 0)) off = sif.layers[0].transformation.offset self.assert_nvector_equal(off.keyframes[0].value, NVector(0, 0)) self.assert_nvector_equal(off.keyframes[1].value, NVector(256, 256)) self.assert_nvector_equal(off.keyframes[2].value, NVector(0, 0)) self.assertEqual(off.keyframes[0].time, api.FrameTime.frame(0)) self.assertEqual(off.keyframes[1].time, api.FrameTime.frame(30)) self.assertEqual(off.keyframes[2].time, api.FrameTime.frame(60)) self.assertEqual(off.keyframes[0].before, api.Interpolation.Linear) self.assertEqual(off.keyframes[1].before, api.Interpolation.Linear) self.assertEqual(off.keyframes[2].before, api.Interpolation.Linear) self.assertEqual(off.keyframes[0].after, api.Interpolation.Linear) self.assertEqual(off.keyframes[1].after, api.Interpolation.Linear) self.assertEqual(off.keyframes[2].after, api.Interpolation.Linear)
def test_repeater(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) group = sl.add_shape(objects.Group()) star = group.add_shape(objects.Star()) star.inner_radius.value = 16 star.outer_radius.value = 32 star.position.value = NVector(256, 40) group.add_shape(objects.Fill(Color(1, 1, 0))) group.add_shape(objects.Stroke(Color(0, 0, 0), 3)) group.name = "Star" rep = sl.add_shape(objects.Repeater(4)) rep.name = "Repeater" rep.transform.position.value = NVector(20, 80) rep.transform.end_opacity.value = 20 sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) self.assertEqual(len(sif.layers[0].layers), 1) self.assertIsInstance(sif.layers[0].layers[0], api.GroupLayer) self.assertEqual(sif.layers[0].layers[0].desc, "Repeater") self.assertEqual(len(sif.layers[0].layers[0].layers), 2) duplicate_lay = sif.layers[0].layers[0].layers[1] self.assertIsInstance(duplicate_lay, api.DuplicateLayer) self.assertEqual(duplicate_lay.desc, "Repeater") duplicate = sif.get_object(duplicate_lay.index.id) self.assertIsInstance(duplicate, api.Duplicate) self.assertEqual(duplicate.from_.value, 3) self.assertEqual(duplicate.to.value, 0) self.assertEqual(duplicate.step.value, -1) dup_trans = sif.layers[0].layers[0].layers[0] self.assertIsInstance(dup_trans, api.GroupLayer) self.assertEqual(dup_trans.desc, "Transformation for Repeater") dup_origin = sif.get_object(dup_trans.origin.id) self.assert_nvector_equal(dup_origin.value.value, NVector(0, 0)) trans = dup_trans.transformation self.assertIsInstance(trans.offset, ast.SifAdd) self.assertEqual(trans.offset.rhs.value.id, dup_origin.id) self.assertIsInstance(trans.offset.lhs, ast.SifScale) self.assert_nvector_equal(trans.offset.lhs.link.value, NVector(20, 80)) self.assertEqual(trans.offset.lhs.scalar.value.id, duplicate.id) self.assertIsInstance(trans.angle, ast.SifScale) self.assertEqual(trans.angle.link.value, 0) self.assertEqual(trans.angle.scalar.value.id, duplicate.id) self.assertIsInstance(dup_trans.amount, ast.SifSubtract) self.assertEqual(dup_trans.amount.lhs.value, 1) self.assertIsInstance(dup_trans.amount.rhs, ast.SifScale) self.assertAlmostEqual(dup_trans.amount.rhs.link.value, 0.266666666) self.assertEqual(dup_trans.amount.rhs.scalar.value.id, duplicate.id) self.assertEqual(len(dup_trans.layers), 1) self.assertEqual(dup_trans.layers[0].desc, "Star")
def test_shape_group(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) gr1 = sl.add_shape(objects.Group()) gr1.name = "Group Shape 1" rect = gr1.add_shape(objects.Rect()) rect.position.value = NVector(128, 256) rect.size.value = NVector(128, 256) gr1.add_shape(objects.Fill(Color(1, .25, 0))) gr2 = sl.add_shape(objects.Group()) gr2.name = "Group Shape 2" rect = gr2.add_shape(objects.Rect()) rect.position.value = NVector(256+128, 256) rect.size.value = NVector(128, 256) gr2.add_shape(objects.Fill(Color(.25, 0, 1))) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) grp = sif.layers[0] self.assertEqual(len(grp.layers), 2) sg1 = grp.layers[1] sg2 = grp.layers[0] self.assertIsInstance(sg1, api.GroupLayer) self.assertIsInstance(sg2, api.GroupLayer) self.assertEqual(sg1.desc, "Group Shape 1") self.assertEqual(sg2.desc, "Group Shape 2") self.assertEqual(len(sg1.layers), 1) self.assertEqual(len(sg2.layers), 1) self.assertIsInstance(sg1.layers[0], api.RegionLayer) self.assertIsInstance(sg2.layers[0], api.RegionLayer) self.assert_nvector_equal(sg1.layers[0].color.value, sif.make_color(1, .25, 0)) self.assert_nvector_equal(sg2.layers[0].color.value, sif.make_color(.25, 0, 1))
def test_bezier(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) shape = sl.add_shape(objects.Path()) sl.add_shape(objects.Fill(Color(0, .25, 1))) shape.shape.value.closed = True shape.shape.value.add_point(NVector(256, 0)) shape.shape.value.add_point(NVector(256+128, 256), NVector(0, 0), NVector(64, 128)) shape.shape.value.add_smooth_point(NVector(256, 512), NVector(128, 0)) shape.shape.value.add_point(NVector(256-128, 256), NVector(-64, 128), NVector(0, 0)) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) grp = sif.layers[0] self.assertEqual(len(grp.layers), 1) self.assertIsInstance(grp.layers[0], api.RegionLayer) self.assertTrue(grp.active) rgl = grp.layers[0] self.assertEqual(len(rgl.bline.points), 4) self.assert_nvector_equal(rgl.color.value, sif.make_color(0, .25, 1)) self.assertTrue(rgl.active) self.assertTrue(rgl.bline.loop) for i in range(len(rgl.bline.points)): sp = rgl.bline.points[i] lp = shape.shape.value.vertices[i] - NVector(256, 256) self.assert_nvector_equal( sp.point.value, lp, msg="Point %s mismatch %s != %s" % (i, sp.point.value, lp) ) lt1 = shape.shape.value.in_tangents[i] * -3 self.assert_nvector_equal( sp.t1.value, lt1, msg="In Tangent %s mismatch %s != %s" % (i, sp.t1.value, lt1) ) lt2 = shape.shape.value.out_tangents[i] * 3 self.assert_nvector_equal( sp.t2.value, lt2, msg="Out Tangent %s mismatch %s != %s" % (i, sp.t2.value, lt2) )
def test_circle(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) ellipse = sl.add_shape(objects.Ellipse()) ellipse.position.value = NVector(256, 256) ellipse.size.value = NVector(512, 512) sl.add_shape(objects.Fill(Color(.25, .25, .25))) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) grp = sif.layers[0] self.assertEqual(len(grp.layers), 1) self.assertIsInstance(grp.layers[0], api.RegionLayer) self.assertTrue(grp.active) rgl = grp.layers[0] self.assertEqual(len(rgl.bline.points), 4) self.assert_nvector_equal(rgl.origin.value, ellipse.position.value) self.assert_nvector_equal(rgl.color.value, sif.make_color(.25, .25, .25)) self.assertTrue(rgl.active) self.assert_nvector_equal(rgl.bline.points[0].point.value, NVector(0, 256)) self.assert_nvector_equal(rgl.bline.points[1].point.value, NVector(-256, 0)) self.assert_nvector_equal(rgl.bline.points[2].point.value, NVector(0, -256)) self.assert_nvector_equal(rgl.bline.points[3].point.value, NVector(256, 0)) self.assertNotAlmostEqual(rgl.bline.points[0].t1.value.x, 0) self.assertAlmostEqual(rgl.bline.points[0].t1.value.y, 0) self.assertNotAlmostEqual(rgl.bline.points[1].t1.value.y, 0) self.assertAlmostEqual(rgl.bline.points[1].t1.value.x, 0) self.assertNotAlmostEqual(rgl.bline.points[2].t1.value.x, 0) self.assertAlmostEqual(rgl.bline.points[2].t1.value.y, 0) self.assertNotAlmostEqual(rgl.bline.points[3].t1.value.y, 0) self.assertAlmostEqual(rgl.bline.points[3].t1.value.x, 0) for i in range(4): self.assert_nvector_equal(rgl.bline.points[i].t1.value, rgl.bline.points[i].t2.value)
def test_animated_fill(self): lot = objects.Animation() ref_sl = lot.add_layer(objects.ShapeLayer()) ref_rect = ref_sl.add_shape(objects.Rect()) ref_rect.position.value = NVector(128, 128) ref_rect.size.value = NVector(256, 256) fill = ref_sl.add_shape(objects.Fill()) fill.opacity.add_keyframe(0, 100) fill.opacity.add_keyframe(30, 50) fill.opacity.add_keyframe(60, 100) fill.color.add_keyframe(0, NVector(1, 0, 0)) fill.color.add_keyframe(30, NVector(0, 1, 0)) fill.color.add_keyframe(60, NVector(1, 0, 0)) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) amount = sif.layers[0].layers[0].amount self.assertAlmostEqual(amount.keyframes[0].value, 1) self.assertAlmostEqual(amount.keyframes[1].value, 0.5) self.assertAlmostEqual(amount.keyframes[2].value, 1) self.assertEqual(amount.keyframes[0].time, api.FrameTime.frame(0)) self.assertEqual(amount.keyframes[1].time, api.FrameTime.frame(30)) self.assertEqual(amount.keyframes[2].time, api.FrameTime.frame(60)) color = sif.layers[0].layers[0].color self.assert_nvector_equal(color.keyframes[0].value, sif.make_color(1, 0, 0)) self.assert_nvector_equal(color.keyframes[1].value, sif.make_color(0, 1, 0)) self.assert_nvector_equal(color.keyframes[2].value, sif.make_color(1, 0, 0)) self.assertEqual(color.keyframes[0].time, api.FrameTime.frame(0)) self.assertEqual(color.keyframes[1].time, api.FrameTime.frame(30)) self.assertEqual(color.keyframes[2].time, api.FrameTime.frame(60))
def test_rect(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) rect = sl.add_shape(objects.Rect()) rect.position.value = NVector(256, 256) rect.size.value = NVector(128, 256) sl.add_shape(objects.Fill(Color(1, .25, 0))) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) grp = sif.layers[0] self.assertEqual(len(grp.layers), 1) self.assertIsInstance(grp.layers[0], api.RegionLayer) self.assertTrue(grp.active) rgl = grp.layers[0] self.assertEqual(len(rgl.bline.points), 4) self.assert_nvector_equal(rgl.origin.value, rect.position.value) self.assert_nvector_equal(rgl.color.value, sif.make_color(1, .25, 0)) self.assertTrue(rgl.active) self.assert_nvector_equal(rgl.bline.points[0].point.value, NVector(-64, -128)) self.assert_nvector_equal(rgl.bline.points[1].point.value, NVector(+64, -128)) self.assert_nvector_equal(rgl.bline.points[2].point.value, NVector(+64, +128)) self.assert_nvector_equal(rgl.bline.points[3].point.value, NVector(-64, +128)) self.assert_nvector_equal(rgl.bline.points[0].t1.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[1].t1.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[2].t1.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[3].t1.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[0].t2.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[1].t2.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[2].t2.value, NVector(0, 0)) self.assert_nvector_equal(rgl.bline.points[3].t2.value, NVector(0, 0))
def particle(): g = layer.add_shape(objects.Group()) b = g.add_shape(objects.Ellipse()) fill = objects.Fill() g.add_shape(fill) t = random.random() if t < 1/2: lf = t * 2 fill.color.add_keyframe(0, color1.lerp(color2, lf)) fill.color.add_keyframe(last_frame*t, color2) fill.color.add_keyframe((1 - t) * last_frame, color3, easing.Jump()) fill.color.add_keyframe((1 - t) * last_frame+1, color1) fill.color.add_keyframe(last_frame, color1.lerp(color2, lf)) else: lf = (t-0.5) * 2 tf = (1-lf)/2 fill.color.add_keyframe(0, color2.lerp(color3, lf)) fill.color.add_keyframe(last_frame*tf, color3, easing.Jump()) fill.color.add_keyframe(last_frame*tf+1, color1) fill.color.add_keyframe((.5 + tf) * last_frame, color2) fill.color.add_keyframe(last_frame, color2.lerp(color3, lf)) fill.opacity.add_keyframe(0, opacity_start + (opacity_end - opacity_start) * t) fill.opacity.add_keyframe((1 - t) * last_frame, opacity_end) fill.opacity.add_keyframe((1 - t) * last_frame+1, opacity_start) fill.opacity.add_keyframe(last_frame, opacity_start + (opacity_end - opacity_start) * t) bezier = objects.Bezier() outp = PolarVector(random.uniform(start_len_min, start_len_max), random.random() * math.pi) inp = Point(0, random.random() * (particle_end.y - particle_start.y) / 3) bezier.add_point(particle_start, outp=outp) bezier.add_point(particle_end, outp) b.size.value = particle_size anutils.follow_path(b.position, bezier, 0, last_frame, 10, start_t=t)
"lib")) from lottie.utils import script from lottie import objects from lottie.utils import animation as anutils from lottie import Size, Point3D, Point, Color an = objects.Animation(120) layer = objects.ShapeLayer() an.add_layer(layer) g = layer.add_shape(objects.Group()) b = g.add_shape(objects.Ellipse()) b.size.value = Size(256, 256) b.position.value = Point(256, 256) g.add_shape(objects.Fill(Color(1, 1, 0))) g = layer.insert_shape(0, objects.Group()) eye1 = g.add_shape(objects.Ellipse()) eye1.size.value = Size(20, 20) eye1.position.value = Point3D(256 - 50, 256 - 50, -100) g.add_shape(objects.Fill(Color(0, 0, 0))) g = layer.insert_shape(0, objects.Group()) eye2 = g.add_shape(objects.Ellipse()) eye2.size.value = Size(20, 20) eye2.position.value = Point3D(256 + 50, 256 - 50, -100) g.add_shape(objects.Fill(Color(0, 0, 0))) g = layer.insert_shape(0, objects.Group()) nose = g.add_shape(objects.Ellipse())
)) from lottie.utils import script from lottie import objects from lottie import Point, Color an = objects.Animation(59) layer = objects.ShapeLayer() an.add_layer(layer) g1 = layer.add_shape(objects.Group()) circle = g1.add_shape(objects.Ellipse()) circle.size.value = Point(100, 100) circle.position.value = Point(200, 100) g1.add_shape(objects.Fill(Color(1, 0, 0))) g1.add_shape(objects.Stroke(Color(0, 0, 0), 5)) g2 = layer.add_shape(objects.Group()) star = g2.add_shape(objects.Star()) star.inner_radius.value = 20 star.outer_radius.value = 50 star.position.value = Point(300, 100) g2.add_shape(objects.Fill(Color(0, 1, 0))) g2.add_shape(objects.Stroke(Color(0, 0, 0), 5)) g3 = layer.add_shape(objects.Group()) rect = g3.add_shape(objects.Rect()) rect.size.value = Point(100, 100) rect.position.value = Point(100, 100) g3.add_shape(objects.Fill(Color(0, 0, 1)))
"lib" )) from lottie.utils import script from lottie import objects from lottie.utils.animation import spring_pull from lottie import Point, Color an = objects.Animation(100) layer = objects.ShapeLayer() an.add_layer(layer) settings = [ (Color(1, 1, 0), 128, 7), (Color(1, 0, 0), 256, 15), (Color(0, .5, 1), 384, 30), ] for color, x, falloff in settings: group = layer.add_shape(objects.Group()) ball = group.add_shape(objects.Ellipse()) ball.size.value = Point(100, 100) group.add_shape(objects.Fill(color)) group.transform.position.value = Point(x, -100) spring_pull(group.transform.position, Point(x, 256), 0, 60, falloff, 7) group.transform.position.add_keyframe(85, Point(x, -100)) script.script_main(an)
def test_animated_bezier(self): lot = objects.Animation() sl = lot.add_layer(objects.ShapeLayer()) shape = sl.add_shape(objects.Path()) sl.add_shape(objects.Fill(Color(0, .25, 1))) bez = objects.Bezier() bez.closed = True bez.add_point(NVector(256, 0)) bez.add_point(NVector(256+128, 256), NVector(0, 0), NVector(64, 128)) bez.add_smooth_point(NVector(256, 512), NVector(128, 0)) bez.add_point(NVector(256-128, 256), NVector(-64, 128), NVector(0, 0)) new_bez = bez.clone() new_bez.vertices[2] = NVector(256, 256+128) new_bez.in_tangents[2] = NVector(64, 64) new_bez.out_tangents[2] = NVector(-64, 64) shape.shape.add_keyframe(0, bez) shape.shape.add_keyframe(30, new_bez) shape.shape.add_keyframe(60, bez) sif = builder.to_sif(lot) self.assertEqual(len(sif.layers), 1) self.assertIsInstance(sif.layers[0], api.GroupLayer) grp = sif.layers[0] self.assertEqual(len(grp.layers), 1) self.assertIsInstance(grp.layers[0], api.RegionLayer) self.assertTrue(grp.active) rgl = grp.layers[0] self.assertEqual(len(rgl.bline.points), 4) self.assert_nvector_equal(rgl.color.value, sif.make_color(0, .25, 1)) self.assertTrue(rgl.active) self.assertTrue(rgl.bline.loop) for i in range(4): sp = rgl.bline.points[i] lp = bez.vertices[i] - NVector(256, 256) lt1 = bez.in_tangents[i] * -3 lt2 = bez.out_tangents[i] * 3 new_lp = new_bez.vertices[i] - NVector(256, 256) new_lt1 = new_bez.in_tangents[i] * -3 new_lt2 = new_bez.out_tangents[i] * 3 self.assertEqual(sp.point.keyframes[0].time, api.FrameTime.frame(0)) self.assert_nvector_equal(sp.point.keyframes[0].value, lp) self.assert_nvector_equal(sp.t1.keyframes[0].value, lt1) self.assert_nvector_equal(sp.t2.keyframes[0].value, lt2) self.assertEqual(sp.point.keyframes[1].time, api.FrameTime.frame(30)) self.assert_nvector_equal(sp.point.keyframes[1].value, new_lp) self.assert_nvector_equal(sp.t1.keyframes[1].value, new_lt1) self.assert_nvector_equal(sp.t2.keyframes[1].value, new_lt2) self.assertEqual(sp.point.keyframes[2].time, api.FrameTime.frame(60)) self.assert_nvector_equal(sp.point.keyframes[2].value, lp) self.assert_nvector_equal(sp.t1.keyframes[2].value, lt1) self.assert_nvector_equal(sp.t2.keyframes[2].value, lt2)
(easing.Sigmoid(1 / 10), Color(0, 0, 1 / 10)), ] height = 512 / len(easings) width = height for i in range(len(easings)): group = layer.add_shape(objects.Group()) rectgroup = group.add_shape(objects.Group()) rect = rectgroup.add_shape(objects.Rect()) rect.size.value = Size(width, height) y = i * height + height / 2 group.transform.position.add_keyframe(0, Point(width / 2, y), easings[i][0]) group.transform.position.add_keyframe(90, Point(512 - width / 2, y), easings[i][0]) group.transform.position.add_keyframe(180, Point(width / 2, y), easings[i][0]) rectgroup.add_shape(objects.Fill(easings[i][1])) bezgroup = group.insert_shape(0, objects.Group()) bez = group.transform.position.keyframes[0].bezier() bezgroup.transform.scale.value = Size(100 * width, -100 * height) bezgroup.transform.position.value = Point(-width / 2, width / 2) bezgroup.add_shape(objects.Path()).shape.value = bez sc = Color(0, 0, 0) if easings[i][1].length == math.sqrt(3) else Color( 1, 1, 1) bezgroup.add_shape(objects.Stroke(sc, 0.1)) script.script_main(an)
an = objects.Animation(last_frame) base = an.add_layer(objects.NullLayer()) base.transform.anchor_point.value = base.transform.position.value = Point(256, 256) base.transform.rotation.add_keyframe(0, 0) base.transform.rotation.add_keyframe(last_frame, 360) star_layer = objects.ShapeLayer() base.add_child(star_layer) star = star_layer.add_shape(objects.Star()) star.inner_radius.value = 20 star.outer_radius.value = 50 star.position.value = Point(50, 50) star_layer.add_shape(objects.Fill(Color(1, 1, 0))) star_layer.add_shape(objects.Stroke(Color(0, 0, 0), 5)) star_layer.transform.anchor_point = star.position star_layer.transform.position.value = Point(50, 256) star_layer.transform.rotation.add_keyframe(0, 0) star_layer.transform.rotation.add_keyframe(last_frame, -360) circle_layer = objects.ShapeLayer() an.add_layer(circle_layer) circle_layer.parent = base circle = circle_layer.add_shape(objects.Ellipse()) circle.size.value = NVector(100, 100) circle_layer.add_shape(objects.Fill(Color(1, 0, 0))) circle_layer.add_shape(objects.Stroke(Color(0, 0, 0), 5)) circle_layer.transform.position.add_keyframe(0, Point(256, 512-50))
#!/usr/bin/env python3 import sys import os sys.path.insert( 0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "lib")) from lottie.utils import script from lottie import objects from lottie import Color, Point from lottie.utils.font import FontStyle an = objects.Animation(120) layer = objects.ShapeLayer() an.add_layer(layer) # The font name "Ubuntu" here, can be detected among the system fonts if fontconfig is available # Otherwise you can use the full path to the font file # `emoji_svg` needs to point to a directory with the supported emoji as svg style = FontStyle("Ubuntu", 128, emoji_svg="twemoji/assets/svg/") t = layer.add_shape(style.render("Hello\nWorld\nF\U0001F600O\nE🇪🇺U")) t.transform.position.value.y += t.line_height layer.add_shape(objects.Fill(Color(0, 0, 0))) layer.add_shape(objects.Stroke(Color(1, 1, 1), 2)) script.script_main(an)
an = objects.Animation(80) precomp = objects.Precomp("myid", an) # Define stuff in the precomposition (a circle moving left to right) layer = objects.ShapeLayer() precomp.add_layer(layer) layer.out_point = 60 circle = layer.add_shape(objects.Ellipse()) circle.size.value = NVector(100, 100) circle.position.add_keyframe(0, NVector(-50, 50)) circle.position.add_keyframe(60, NVector(512 + 50, 50)) fill = layer.add_shape(objects.Fill()) fill.color.add_keyframe(0, Color(1, 1, 0)) fill.color.add_keyframe(60, Color(1, 0, 0)) # plays the precomp as it is pcl0 = an.add_layer(objects.PreCompLayer("myid")) # plays the precomp, offset in time by 20 frames and in space by 100 pixels pcl1 = an.add_layer(objects.PreCompLayer("myid")) pcl1.start_time = 20 pcl1.transform.position.value = NVector(0, 100) # playes the composition, but starts it with negative time, so it's farther ahead pcl2 = an.add_layer(objects.PreCompLayer("myid")) pcl2.start_time = -20 pcl2.transform.position.value = NVector(0, 200)
layer = objects.ShapeLayer() an.add_layer(layer) group = layer.add_shape(objects.Group()) ball = group.add_shape(objects.Ellipse()) ball.size.value = Point(10, 10) r1 = group.add_shape(objects.Rect()) r1.size.value = Point(50, 10) r2 = group.add_shape(objects.Group()) r2.add_shape(objects.Rect()).size.value = Point(50, 10) r2 = r2.transform group.add_shape(objects.Fill(Color(0, 1, 0))) group = layer.add_shape(objects.Group()) bez = group.add_shape(objects.Path()) bez.shape.value.add_point(Point(256, 128), Point(0, 0), Point(64, 64)) bez.shape.value.add_point(Point(256, 256), Point(-64, -64), Point(-64, 64)) bez.shape.value.add_point(Point(256, 256 + 120), Point(0, 0), Point(0, 0)) group.add_shape(objects.Stroke(Color(1, 0, 0), 10)) follow_path(ball.position, bez.shape.value, 0, 90, 30, False, Point(0, 0)) follow_path(ball.position, bez.shape.value, 90, 180, 30, True, Point(0, 0)) follow_path(r1.position, bez.shape.value, 0, 90, 30, False, Point(150, 0)) follow_path(r1.position, bez.shape.value, 90, 180, 30, True, Point(150, 0)) follow_path(r2.position, bez.shape.value, 0, 90, 30, False, Point(-150, 0), 0,
rect = shapes.add_shape(objects.Rect()) rect.size.add_keyframe(0, Point(100, 100)) rect.size.add_keyframe(30, Point(50, 120)) rect.size.add_keyframe(60, Point(100, 100)) rect.position.add_keyframe(0, Point(110, 110)) rect.position.add_keyframe(20, Point(80, 110)) rect.position.add_keyframe(40, Point(110, 110)) rrect = shapes.add_shape(objects.Rect()) rrect.size.value = Point(100, 100) rrect.position.value = Point(440, 110) rrect.rounded.add_keyframe(0, 0) rrect.rounded.add_keyframe(30, 30) rrect.rounded.add_keyframe(60, 0) fill = shapes.add_shape(objects.Fill(Color(1, 1, 0))) stroke = shapes.add_shape(objects.Stroke(Color(0, 0, 0), 5)) beziers = layer.add_shape(objects.Group()) beziers.transform.position.value = Point(0, 130) beziers.add_shape(rect.to_bezier()) beziers.add_shape(rrect.to_bezier()) beziers.add_shape(circle.to_bezier()) beziers.add_shape(star.to_bezier()) fill = beziers.add_shape(objects.Fill(Color(0, 0, 1))) stroke = beziers.add_shape(objects.Stroke(Color(1, 1, 1), 5)) script.script_main(an)
layer = objects.ShapeLayer() an.add_layer(layer) heart = objects.Bezier() heart.add_point(Point(50, 20), Point(50, -20), Point(-50, -20)) heart.add_smooth_point(Point(0, 50), Point(-5, -10)) heart.add_smooth_point(Point(50, 100), Point(-10, 0)) heart.add_smooth_point(Point(100, 50), Point(-5, 10)) heart.closed = True antiheart = (objects.Bezier().add_smooth_point(Point(50, 0), Point( 10, 0)).add_smooth_point(Point(0, 50), Point(0, -20)).add_point( Point(50, 80), Point(-50, 20), Point(50, 20)).add_smooth_point(Point(100, 50), Point(0, 20)).close()) g1 = layer.add_shape(objects.Group()) g1.transform.position.value = Point(100, 200) shape = g1.add_shape(objects.Path()) shape.shape.value = heart g2 = layer.add_shape(objects.Group()) g2.transform.position.value = Point(300, 200) animated = g2.add_shape(objects.Path()) animated.shape.add_keyframe(0, heart) animated.shape.add_keyframe(30, antiheart) animated.shape.add_keyframe(59, heart) fill = layer.add_shape(objects.Fill(color.from_uint8(255, 0, 0))) stroke = layer.add_shape(objects.Stroke(Color(0, 0, 0), 5)) script.script_main(an)
def add_shape(shape, color, parent): g = parent.add_shape(objects.Group()) s = g.add_shape(shape) g.add_shape(objects.Fill(color)) return s
sys.path.insert( 0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "lib")) from lottie.utils import script from lottie import objects from lottie.parsers.svg import parse_svg_file from lottie import Point, Color an = parse_svg_file( os.path.join(os.path.dirname(os.path.abspath(__file__)), "blep.svg")) maskshape = objects.Star() maskshape.inner_radius.value = 100 maskshape.outer_radius.value = 200 maskshape.rotation.value = 180 maskshape.position.value = Point(256, 256) #maskshape.size.value = Point(256, 256) maskbez = maskshape.to_bezier() mask = objects.Mask(maskbez.shape.value) an.layers[0].masks = [mask] g = an.layers[0].add_shape(objects.Group()) r = g.add_shape(objects.Rect()) r.position.value = Point(256, 256) r.size.value = Point(512, 512) g.add_shape(objects.Fill(Color(1, 1, 1))) script.script_main(an)
an = objects.Animation(59) layer = objects.ShapeLayer() an.add_layer(layer) bezier = objects.Bezier() radius = 128 angle = -math.pi / 2 for i in range(5+1): bezier.add_point(PolarVector(radius, angle)) angle += 2 * math.pi * 2 / 5 bezier.closed = True bezier.reverse() g = layer.add_shape(objects.Group()) g.transform.position.value = Point(radius, radius) g.add_shape(objects.Path(bezier)) fill = g.add_shape(objects.Fill(color.from_uint8(255, 0, 100))) fill.fill_rule = objects.FillRule.NonZero g = layer.add_shape(objects.Group()) g.transform.position.value = Point(512-radius, 512-radius) g.add_shape(objects.Path(bezier)) fill = g.add_shape(objects.Fill(color.from_uint8(255, 100, 0))) fill.fill_rule = objects.FillRule.EvenOdd script.script_main(an)
os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "lib" )) from lottie.utils import script from lottie import objects from lottie import Point, Color an = objects.Animation(59) layer = objects.ShapeLayer() an.add_layer(layer) circle = layer.add_shape(objects.Ellipse()) circle.size.value = Point(100, 100) circle.position.add_keyframe(0, Point(0, 256)) circle.position.add_keyframe(20, Point(256, 256)) circle.position.add_keyframe(40, Point(256, 0)) circle.position.add_keyframe(60, Point(0, 256)) fill = layer.add_shape(objects.Fill(Color(1, 1, 0))) fill.opacity.add_keyframe(0, 100) fill.opacity.add_keyframe(30, 10) fill.opacity.add_keyframe(60, 100) script.script_main(an)
an = objects.Animation(last_frame) layer = objects.ShapeLayer() an.add_layer(layer) layer.auto_orient = True group = layer.add_shape(objects.Group()) star = objects.Star() star.inner_radius.value = 20 star.outer_radius.value = 50 star.position.value = Point(0, 0) group.add_shape(star) group.add_shape(objects.Ellipse(NVector(0, 35), NVector(16, 16))) layer.add_shape(objects.Fill(Color(1, 1, 0))) tl = 120 layer.transform.position.add_keyframe(last_frame / 4 * 0, Point(+50, 256), out_tan=NVector(0, -tl), in_tan=NVector(-tl, 0)) layer.transform.position.add_keyframe(last_frame / 4 * 1, Point(256, +50), out_tan=NVector(+tl, 0), in_tan=NVector(0, -tl)) layer.transform.position.add_keyframe(last_frame / 4 * 2, Point(462, 256), out_tan=NVector(0, +tl), in_tan=NVector(+tl, 0)) layer.transform.position.add_keyframe(last_frame / 4 * 3,