Blame synfig-studio/plugins/lottie-exporter/lottie-exporter.py

AnishGulati 0f1f11
# pylint: disable=line-too-long
AnishGulati 3e50dd
"""
AnishGulati 3e50dd
Python plugin to convert the .sif format into lottie json format
AnishGulati 794688
input   : FILE_NAME.sif
AnishGulati 794688
output  : FILE_NAME.json
AnishGulati decf6d
        : FILE_NAME.html
AnishGulati 8f8d53
        : FILE_NAME.log
AnishGulati 3e50dd
AnishGulati decf6d
Supported Layers are mentioned below
AnishGulati 3e50dd
"""
AnishGulati b81c59
import os
AnishGulati 3e50dd
import json
AnishGulati 3e50dd
import sys
AnishGulati 0cd7ab
import logging
AnishGulati 4d87a1
from lxml import etree
AnishGulati 1c4546
from canvas import gen_canvas
AnishGulati 5b8f00
from layers.driver import gen_layers
AnishGulati 1f6b9a
from common.misc import modify_final_dump
AnishGulati 8a6b29
from common.Canvas import Canvas
AnishGulati 1c4546
import settings
AnishGulati 3e50dd
AnishGulati decf6d
AnishGulati decf6d
def write_to(filename, extension, data):
AnishGulati 0f1f11
    """
AnishGulati 0f1f11
    Helps in writing data to a specified file name
AnishGulati 0f1f11
AnishGulati 0f1f11
    Args:
AnishGulati 0f1f11
        filename  (str) : Original file name
AnishGulati 0f1f11
        extension (str) : original file name needs to be converted to this
AnishGulati 0f1f11
        data      (str) : Data that needs to be written
AnishGulati 0f1f11
AnishGulati 0f1f11
    Returns:
AnishGulati 0f1f11
        (str) : changed file name according to the extension specified
AnishGulati 0f1f11
    """
AnishGulati decf6d
    new_name = filename.split(".")
AnishGulati decf6d
    new_name[-1] = extension
AnishGulati decf6d
    new_name = ".".join(new_name)
AnishGulati 0f1f11
    with open(new_name, "w") as fil:
AnishGulati 0f1f11
        fil.write(data)
AnishGulati decf6d
    return new_name
AnishGulati decf6d
AnishGulati decf6d
AnishGulati 4d87a1
def parse(file_name):
AnishGulati 4d87a1
    """
AnishGulati 4d87a1
    Driver function for parsing .sif to lottie(.json) format
AnishGulati 0f1f11
AnishGulati 0f1f11
    Args:
AnishGulati 0f1f11
        file_name (str) : Synfig file name that needs to be parsed to Lottie format
AnishGulati 0f1f11
AnishGulati 0f1f11
    Returns:
AnishGulati 0f1f11
        (str) : File name in json format
AnishGulati 4d87a1
    """
AnishGulati 4d87a1
    tree = etree.parse(file_name)
AnishGulati 3e50dd
    root = tree.getroot()  # canvas
AnishGulati 1c4546
    gen_canvas(settings.lottie_format, root)
AnishGulati 3e50dd
AnishGulati b81c59
    # Storing the file name
AnishGulati b81c59
    settings.file_name["fn"] = file_name
AnishGulati b81c59
AnishGulati b81c59
    # Storing the file directory
AnishGulati b81c59
    settings.file_name["fd"] = os.path.dirname(file_name)
AnishGulati b81c59
AnishGulati 0cd7ab
    # Initialize the logging
AnishGulati 0cd7ab
    init_logs()
AnishGulati 0cd7ab
AnishGulati 1c4546
    settings.lottie_format["layers"] = []
AnishGulati 8a6b29
    canvas = Canvas(root)
AnishGulati 8a6b29
    gen_layers(settings.lottie_format["layers"], canvas, canvas.get_num_layers() - 1)
AnishGulati 3e50dd
AnishGulati 65f05e
    lottie_string = json.dumps(modify_final_dump(settings.lottie_format))
AnishGulati decf6d
    return write_to(file_name, "json", lottie_string)
AnishGulati decf6d
AnishGulati 22e7c0
AnishGulati 22e7c0
def gen_html(file_name):
AnishGulati 22e7c0
    """
AnishGulati 22e7c0
    Generates an HTML file which will allow end user to easily playback
AnishGulati 22e7c0
    animation in a web browser
AnishGulati 0f1f11
AnishGulati 0f1f11
    Args:
AnishGulati 0f1f11
        file_name (str) : Stores the HTML file name
AnishGulati 0f1f11
AnishGulati 0f1f11
    Returns:
AnishGulati 0f1f11
        (None)
AnishGulati 22e7c0
    """
AnishGulati 0d60af
    bodymovin_path = os.path.join(os.path.dirname(sys.argv[0]), "bodymovin.js")
AnishGulati 7cf124
AnishGulati 0d60af
    with open(bodymovin_path, "r") as f:
AnishGulati a4eb43
        bodymovin_script = f.read()
AnishGulati 41d7e3
AnishGulati d108d4
    html_text = \
AnishGulati a4eb43
"""
AnishGulati a4eb43
<meta charset="UTF-8">
AnishGulati d108d4
AnishGulati a4eb43
    <style></style>
AnishGulati a4eb43
        body{{
AnishGulati a4eb43
            background-color:#fff;
AnishGulati a4eb43
            margin: 0px;
AnishGulati a4eb43
            height: 100%;
AnishGulati a4eb43
            overflow: hidden;
AnishGulati a4eb43
        }}
AnishGulati a4eb43
        #lottie{{
AnishGulati a4eb43
            background-color:#fff;
AnishGulati a4eb43
            width:100%;
AnishGulati a4eb43
            height:100%;
AnishGulati a4eb43
            display:block;
AnishGulati a4eb43
            overflow: hidden;
AnishGulati a4eb43
            transform: translate3d(0,0,0);
AnishGulati a4eb43
            text-align: center;
AnishGulati a4eb43
            opacity: 1;
AnishGulati a4eb43
        }}
AnishGulati a4eb43
AnishGulati a4eb43
    
AnishGulati d108d4
AnishGulati a4eb43
AnishGulati 22e7c0
AnishGulati a4eb43
{bodymovin_script}
AnishGulati d108d4
AnishGulati a4eb43
AnishGulati d108d4
<script></script>
AnishGulati a4eb43
    var animationData = {file_name_data};
AnishGulati a4eb43
    var params = {{
AnishGulati a4eb43
        container: document.getElementById('lottie'),
AnishGulati 1db9b5
        renderer: 'svg',
AnishGulati d108d4
        loop: true,
AnishGulati d108d4
        autoplay: true,
AnishGulati a4eb43
        animationData: animationData
AnishGulati decf6d
    }};
AnishGulati a4eb43
AnishGulati a4eb43
    var anim;
AnishGulati a4eb43
AnishGulati a4eb43
    anim = lottie.loadAnimation(params);
AnishGulati a4eb43
AnishGulati d108d4
AnishGulati d108d4
AnishGulati a4eb43
AnishGulati a4eb43
"""
AnishGulati 41d7e3
AnishGulati 65f05e
    write_to(file_name, "html", html_text.format(bodymovin_script=bodymovin_script, file_name_data=json.dumps(modify_final_dump(settings.lottie_format))))
AnishGulati decf6d
AnishGulati 4d87a1
AnishGulati 0cd7ab
def init_logs():
AnishGulati 8f8d53
    """
AnishGulati 8f8d53
    Initializes the logger, sets the file name in which the logs will be stored
AnishGulati 8f8d53
    and sets the level of the logging(DEBUG | INFO : depending on what is
AnishGulati 8f8d53
    specified)
AnishGulati 8f8d53
    """
AnishGulati 0cd7ab
    name = settings.file_name['fn']
AnishGulati 0cd7ab
    name = name.split(".")
AnishGulati 0cd7ab
    name[-1] = 'log'
AnishGulati 0cd7ab
    name = '.'.join(name)
AnishGulati 0cd7ab
    path = os.path.join(settings.file_name['fd'], name)
AnishGulati 0cd7ab
    path = os.path.abspath(name)
AnishGulati 0cd7ab
    logging.basicConfig(filename=path, filemode='w',
AnishGulati 8f8d53
                        format='%(name)s - %(levelname)s - %(message)s')
AnishGulati 0cd7ab
    logging.getLogger().setLevel(logging.DEBUG)
AnishGulati 0cd7ab
AnishGulati 0cd7ab
AnishGulati 4d87a1
if len(sys.argv) < 2:
AnishGulati 4d87a1
    sys.exit()
AnishGulati 4d87a1
else:
AnishGulati 4d87a1
    settings.init()
AnishGulati 4d87a1
    FILE_NAME = sys.argv[1]
AnishGulati 22e7c0
    new_file_name = parse(FILE_NAME)
AnishGulati 22e7c0
    gen_html(new_file_name)