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 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)
import math 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.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)
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(120) layer = objects.ShapeLayer() an.add_layer(layer) # Build a sphere out of circles balls = [] axes = [ Point(1, 0), Point(0, 1), ] for i in range(20): a = i / 20 * math.pi * 2 for axis in axes: g = layer.add_shape(objects.Group()) b = g.add_shape(objects.Ellipse()) b.size.value = Size(20, 20) xz = axis * math.sin(a) * 128 pos = Point3D(256 + xz[0], 256 + math.cos(a) * 128, xz[1]) b.position.value = pos balls.append(b) g.add_shape(objects.Fill(Color(0, 1, 0))) # Animate the circles using depth rotation dr = anutils.DepthRotationDisplacer(Point3D(256, 256, 0), 0, 120, 10, Point3D(0, 2, -1)) for b in balls: dr.animate_point(b.position) script.script_main(an)
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.utils.animation import follow_path from lottie import Point, Color an = objects.Animation(180) 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))
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 Point, Color an = objects.Animation(60) layer = objects.ShapeLayer() an.add_layer(layer) shapes = layer.add_shape(objects.Group()) circle = shapes.add_shape(objects.Ellipse()) circle.size.add_keyframe(0, Point(100, 100)) circle.size.add_keyframe(30, Point(50, 120)) circle.size.add_keyframe(60, Point(100, 100)) circle.position.add_keyframe(0, Point(220, 110)) circle.position.add_keyframe(20, Point(180, 110)) circle.position.add_keyframe(40, Point(220, 110)) star = shapes.add_shape(objects.Star()) star.inner_radius.add_keyframe(0, 20) star.inner_radius.add_keyframe(30, 50) star.inner_radius.add_keyframe(60, 20) star.outer_radius.value = 50 #star.inner_roundness.value = 100
(easing.EaseIn(1), Color(0, 1, 0)), (easing.EaseIn(1 / 2), Color(0, 1 / 2, 0)), (easing.EaseIn(1 / 3), Color(0, 1 / 3, 0)), (easing.EaseIn(1 / 5), Color(0, 1 / 5, 0)), (easing.EaseIn(1 / 10), Color(0, 1 / 10, 0)), (easing.Sigmoid(1), Color(0, 0, 1)), (easing.Sigmoid(1 / 2), Color(0, 0, 1 / 2)), (easing.Sigmoid(1 / 3), Color(0, 0, 1 / 3)), (easing.Sigmoid(1 / 5), Color(0, 0, 1 / 5)), (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()
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 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())
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