├── examples ├── CMakeLists.txt ├── quick │ ├── qml.qrc │ ├── CMakeLists.txt │ ├── main.cpp │ └── qml │ │ └── main.qml ├── widget │ ├── CMakeLists.txt │ ├── widget.h │ ├── main.cpp │ └── widget.cpp └── lottiefiles │ ├── 41413-brahma-logo.json │ ├── 39506-check.json │ ├── 43846-butterfly-loader.json │ ├── 53175-ball-spinner.json │ ├── 40292-clickable-rainbow.json │ ├── 50486-rocket.json │ ├── 50807-pacman-loading.json │ └── 41446-teh-tarik.json ├── src ├── QtLottieConfig.cmake.in ├── qtlottiedrawenginefactory.h ├── qtlottie_global.h ├── qtlottie.rc ├── qtlottiedrawengine_skottie.h ├── qtlottiedrawengine_rlottie.h ├── qtlottiedrawenginefactory.cpp ├── qtlottieitem.h ├── qtlottiewidget.h ├── qtlottiedrawengine.h ├── CMakeLists.txt ├── qtlottiewidget.cpp ├── qtlottieitem.cpp ├── qtlottiedrawengine_rlottie.cpp └── qtlottiedrawengine_skottie.cpp ├── .gitignore ├── LICENSE ├── CMakeLists.txt └── README.md /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(widget) 2 | add_subdirectory(quick) 3 | -------------------------------------------------------------------------------- /examples/quick/qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | qml/main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/QtLottieConfig.cmake.in: -------------------------------------------------------------------------------- 1 | @PACKAGE_INIT@ 2 | 3 | include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") 4 | 5 | check_required_components(@PROJECT_NAME@) 6 | -------------------------------------------------------------------------------- /examples/quick/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 2 | 3 | set(CMAKE_AUTOUIC ON) 4 | set(CMAKE_AUTOMOC ON) 5 | set(CMAKE_AUTORCC ON) 6 | 7 | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Quick QuickControls2) 8 | find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Quick QuickControls2) 9 | 10 | add_executable(quick WIN32 qml.qrc main.cpp) 11 | 12 | target_link_libraries(quick PRIVATE 13 | Qt${QT_VERSION_MAJOR}::Quick 14 | Qt${QT_VERSION_MAJOR}::QuickControls2 15 | wangwenx190::QtLottie 16 | ) 17 | -------------------------------------------------------------------------------- /examples/widget/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 2 | 3 | set(CMAKE_AUTOUIC ON) 4 | set(CMAKE_AUTOMOC ON) 5 | set(CMAKE_AUTORCC ON) 6 | 7 | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets) 8 | find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets) 9 | 10 | set(SOURCES 11 | main.cpp 12 | widget.h 13 | widget.cpp 14 | ) 15 | 16 | add_executable(widget WIN32 ${SOURCES}) 17 | 18 | target_link_libraries(widget PRIVATE 19 | Qt${QT_VERSION_MAJOR}::Widgets 20 | wangwenx190::QtLottie 21 | ) 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.so.* 10 | *.dll 11 | *.dylib 12 | 13 | # Qt-es 14 | object_script.*.Release 15 | object_script.*.Debug 16 | *_plugin_import.cpp 17 | /.qmake.cache 18 | /.qmake.stash 19 | *.pro.user 20 | *.pro.user.* 21 | *.qbs.user 22 | *.qbs.user.* 23 | *.moc 24 | moc_*.cpp 25 | moc_*.h 26 | qrc_*.cpp 27 | ui_*.h 28 | *.qmlc 29 | *.jsc 30 | Makefile* 31 | *build-* 32 | *.qm 33 | *.prl 34 | 35 | # Qt unit tests 36 | target_wrapper.* 37 | 38 | # QtCreator 39 | *.autosave 40 | 41 | # QtCreator Qml 42 | *.qmlproject.user 43 | *.qmlproject.user.* 44 | 45 | # QtCreator CMake 46 | CMakeLists.txt.user* 47 | 48 | # QtCreator 4.8< compilation database 49 | compile_commands.json 50 | 51 | # QtCreator local machine specific files for imported projects 52 | *creator.user* 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2021 wangwenx190 (Yuhang Zhao) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /examples/widget/widget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | 29 | class Widget : public QWidget 30 | { 31 | Q_OBJECT 32 | 33 | public: 34 | explicit Widget(QWidget *parent = nullptr); 35 | ~Widget() override; 36 | }; 37 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.5) 2 | 3 | project(QtLottie 4 | VERSION 1.0.0.0 5 | DESCRIPTION "QtLottie is a tiny C++ library that can render Adobe After Effects animations exported as JSON with Bodymovin." 6 | HOMEPAGE_URL "https://github.com/wangwenx190/qtlottie" 7 | LANGUAGES CXX 8 | ) 9 | 10 | option(BUILD_EXAMPLES "Build QtLottie demo applications." ON) 11 | 12 | set(CMAKE_CXX_STANDARD 17) 13 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 14 | set(CMAKE_CXX_EXTENSIONS OFF) 15 | 16 | if(NOT DEFINED BUILD_SHARED_LIBS) 17 | set(BUILD_SHARED_LIBS ON) 18 | endif() 19 | 20 | if(NOT DEFINED CMAKE_DEBUG_POSTFIX) 21 | if(WIN32) 22 | set(CMAKE_DEBUG_POSTFIX d) 23 | else() 24 | set(CMAKE_DEBUG_POSTFIX _debug) 25 | endif() 26 | endif() 27 | 28 | if(NOT DEFINED CMAKE_BUILD_TYPE) 29 | set(CMAKE_BUILD_TYPE Release) 30 | endif() 31 | 32 | if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug") 33 | AND BUILD_SHARED_LIBS 34 | AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE) 35 | set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON) 36 | endif() 37 | 38 | if(NOT DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY) 39 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) 40 | endif() 41 | 42 | if(NOT DEFINED CMAKE_LIBRARY_OUTPUT_DIRECTORY) 43 | set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) 44 | endif() 45 | 46 | if(NOT DEFINED CMAKE_ARCHIVE_OUTPUT_DIRECTORY) 47 | set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) 48 | endif() 49 | 50 | add_subdirectory(src) 51 | if(BUILD_EXAMPLES) 52 | add_subdirectory(examples) 53 | endif() 54 | -------------------------------------------------------------------------------- /src/qtlottiedrawenginefactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "qtlottie_global.h" 28 | 29 | class QtLottieDrawEngine; 30 | 31 | namespace QtLottieDrawEngineFactory 32 | { 33 | 34 | enum class Backend 35 | { 36 | Skottie = 0, 37 | RLottie = 1 38 | }; 39 | 40 | QTLOTTIE_API QtLottieDrawEngine *create(const Backend backend); 41 | QTLOTTIE_API QtLottieDrawEngine *create(const char *name); 42 | QTLOTTIE_API QtLottieDrawEngine *create(); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /examples/widget/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include "widget.h" 27 | 28 | int main(int argc, char *argv[]) { 29 | #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 30 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 31 | QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 32 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) 33 | QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); 34 | #endif 35 | #endif 36 | QApplication application(argc, argv); 37 | Widget widget; 38 | widget.show(); 39 | return QApplication::exec(); 40 | } 41 | -------------------------------------------------------------------------------- /src/qtlottie_global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include 28 | 29 | #ifndef QTLOTTIE_API 30 | # ifdef QTLOTTIE_STATIC 31 | # define QTLOTTIE_API 32 | # else 33 | # ifdef QTLOTTIE_BUILD_LIBRARY 34 | # define QTLOTTIE_API Q_DECL_EXPORT 35 | # else 36 | # define QTLOTTIE_API Q_DECL_IMPORT 37 | # endif 38 | # endif 39 | #endif 40 | 41 | #if (defined(Q_OS_WIN) && !defined(Q_OS_WINDOWS)) 42 | # define Q_OS_WINDOWS 43 | #endif 44 | 45 | #ifndef Q_DISABLE_COPY_MOVE 46 | # define Q_DISABLE_COPY_MOVE(Class) \ 47 | Q_DISABLE_COPY(Class) \ 48 | Class(Class &&) = delete; \ 49 | Class &operator=(Class &&) = delete; 50 | #endif 51 | -------------------------------------------------------------------------------- /src/qtlottie.rc: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | 27 | VS_VERSION_INFO VERSIONINFO 28 | FILEVERSION 1,0,0,0 29 | PRODUCTVERSION 1,0,0,0 30 | FILEFLAGSMASK 0x3fL 31 | #ifdef _DEBUG 32 | FILEFLAGS VS_FF_DEBUG 33 | #else 34 | FILEFLAGS 0x0L 35 | #endif 36 | FILEOS VOS_NT_WINDOWS32 37 | FILETYPE VFT_DLL 38 | FILESUBTYPE VFT2_UNKNOWN 39 | BEGIN 40 | BLOCK "StringFileInfo" 41 | BEGIN 42 | BLOCK "040904b0" 43 | BEGIN 44 | VALUE "CompanyName", "wangwenx190" 45 | VALUE "FileDescription", "QtLottie is a tiny C++ library that can render Adobe After Effects animations exported as JSON with Bodymovin." 46 | VALUE "FileVersion", "1.0.0.0" 47 | VALUE "LegalCopyright", "MIT License" 48 | #ifdef _DEBUG 49 | VALUE "OriginalFilename", "QtLottied.dll" 50 | #else 51 | VALUE "OriginalFilename", "QtLottie.dll" 52 | #endif 53 | VALUE "ProductName", "QtLottie" 54 | VALUE "ProductVersion", "1.0.0.0" 55 | END 56 | END 57 | BLOCK "VarFileInfo" 58 | BEGIN 59 | VALUE "Translation", 0x409, 1200 60 | END 61 | END 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QtLottie 2 | 3 | QtLottie is a tiny C++ library that can render [Adobe® After Effects™](http://www.adobe.com/products/aftereffects.html) animations exported as JSON with [Bodymovin](https://github.com/airbnb/lottie-web). 4 | 5 | ## Features 6 | 7 | - Support many After Effects features (depends on the specific backend). 8 | - Cross-platform: support Windows (7~10), Linux and macOS. 9 | - Support both Qt Widgets and Qt Quick. 10 | - Support all versions from Qt5 to Qt6. 11 | - Very easy to build and use. 12 | 13 | ## Build 14 | 15 | ```bash 16 | cmake . 17 | cmake --build . 18 | cmake --install . 19 | ``` 20 | 21 | Currently QtLottie supports two backends: [skottie](https://github.com/xspeed1989/SkottieWrapper) and [rlottie](https://github.com/Samsung/rlottie). QtLottie will load it dynamically at run-time. Make sure you have build it and put it in the executable's directory before you run your application. While this library is initializing, skottie is prefered over rlottie. 22 | 23 | ## Usage 24 | 25 | See [examples](/examples). 26 | 27 | ## Limitation 28 | 29 | If your JSON uses assets, these files can only be placed on the disk, they can't be compressed or embeded into any container-like thing. It's caused by technical limitation, PRs are welcome. 30 | 31 | ## License 32 | 33 | ```text 34 | MIT License 35 | 36 | Copyright (C) 2021 wangwenx190 (Yuhang Zhao) 37 | 38 | Permission is hereby granted, free of charge, to any person obtaining a copy 39 | of this software and associated documentation files (the "Software"), to deal 40 | in the Software without restriction, including without limitation the rights 41 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 42 | copies of the Software, and to permit persons to whom the Software is 43 | furnished to do so, subject to the following conditions: 44 | 45 | The above copyright notice and this permission notice shall be included in all 46 | copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 49 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 50 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 51 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 52 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 53 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 54 | SOFTWARE. 55 | ``` 56 | -------------------------------------------------------------------------------- /examples/lottiefiles/41413-brahma-logo.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.4","fr":30,"ip":0,"op":210,"w":300,"h":300,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"vector Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[150.00000000000006,150.00000000000006,0],"ix":2},"a":{"a":0,"k":[150,150,0],"ix":1},"s":{"a":0,"k":[100.00000000000003,100.00000000000003,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.817},"o":{"x":0.167,"y":0.183},"t":0,"s":[{"i":[[0,44.276],[44.276,0],[0,-44.276],[-44.276,0]],"o":[[0,-44.276],[-44.276,0],[0,44.276],[44.276,0]],"v":[[80.169,0],[0,-80.169],[-80.169,0],[0,80.169]],"c":true}]},{"i":{"x":0.833,"y":0.817},"o":{"x":0.167,"y":0.183},"t":38,"s":[{"i":[[0.442,-33.498],[27.25,31.169],[0.169,-36.5],[-29.177,33.303]],"o":[[-0.419,31.75],[-29.142,-33.333],[-0.141,30.501],[31.25,-35.669]],"v":[[80.169,0],[0.75,-2.169],[-80.169,0],[0.25,-2.331]],"c":true}]},{"i":{"x":0.833,"y":0.817},"o":{"x":0.333,"y":0},"t":74.638,"s":[{"i":[[0.831,-44.5],[40.789,-0.176],[0.306,42.5],[-43.004,-0.077]],"o":[[-0.915,49.026],[-39.25,0.169],[-0.331,-46],[45.5,0.081]],"v":[[80.169,0],[-1.25,79.331],[-80.169,0],[0.5,-81.081]],"c":true}]},{"i":{"x":0.833,"y":0.817},"o":{"x":0.333,"y":0},"t":112.638,"s":[{"i":[[0.831,-44.5],[40.789,-0.176],[0.306,42.5],[-43.004,-0.077]],"o":[[-0.915,49.026],[-39.25,0.169],[-0.331,-46],[45.5,0.081]],"v":[[80.169,0],[-1.25,79.331],[-80.169,0],[0.5,-81.081]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.167,"y":0.183},"t":150,"s":[{"i":[[0.442,-33.498],[27.25,31.169],[0.169,-36.5],[-29.177,33.303]],"o":[[-0.419,31.75],[-29.142,-33.333],[-0.141,30.501],[31.25,-35.669]],"v":[[80.169,0],[0.75,-2.169],[-80.169,0],[0.25,-2.331]],"c":true}]},{"t":191.000007779589,"s":[{"i":[[0,44.276],[44.276,0],[0,-44.276],[-44.276,0]],"o":[[0,-44.276],[-44.276,0],[0,44.276],[44.276,0]],"v":[[80.169,0],[0,-80.169],[-80.169,0],[0,80.169]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.30196078431372547,0.30196078431372547,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":40,"ix":5},"lc":1,"lj":2,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[150,150],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":180,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":899.000036617021,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /examples/quick/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | int main(int argc, char *argv[]) { 31 | #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) 32 | QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); 33 | QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); 34 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) 35 | QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); 36 | #endif 37 | #endif 38 | 39 | QGuiApplication application(argc, argv); 40 | 41 | QQmlApplicationEngine engine; 42 | 43 | #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) 44 | QQuickStyle::setStyle(QStringLiteral("Basic")); 45 | #else 46 | QQuickStyle::setStyle(QStringLiteral("Default")); 47 | #endif 48 | 49 | qmlRegisterType("wangwenx190.Utils", 1, 0, "LottieItem"); 50 | 51 | const QUrl mainQmlUrl(QStringLiteral("qrc:///qml/main.qml")); 52 | const QMetaObject::Connection connection = QObject::connect( 53 | &engine, 54 | &QQmlApplicationEngine::objectCreated, 55 | &application, 56 | [&mainQmlUrl, &connection](QObject *object, const QUrl &url) { 57 | if (url != mainQmlUrl) { 58 | return; 59 | } 60 | if (!object) { 61 | QGuiApplication::exit(-1); 62 | } else { 63 | QObject::disconnect(connection); 64 | } 65 | }, 66 | Qt::QueuedConnection); 67 | 68 | engine.load(mainQmlUrl); 69 | 70 | return QGuiApplication::exec(); 71 | } 72 | -------------------------------------------------------------------------------- /examples/quick/qml/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | import QtQuick 2.0 26 | import QtQuick.Window 2.0 27 | import QtQuick.Controls 2.0 28 | import QtQuick.Layouts 1.0 29 | import Qt.labs.platform 1.0 30 | import wangwenx190.Utils 1.0 31 | 32 | Window { 33 | id: window 34 | width: 800 35 | height: 600 36 | title: qsTr("QtLottie Quick Example") 37 | visible: true 38 | 39 | FileDialog { 40 | id: fileDialog 41 | nameFilters: [qsTr("Bodymovin files (*.json)"), qsTr("All files (*)")] 42 | folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) 43 | } 44 | 45 | LottieItem { 46 | id: lottieItem 47 | anchors.fill: parent 48 | source: fileDialog.file 49 | onSourceSizeChanged: { 50 | window.width = lottieItem.sourceSize.width 51 | window.height = lottieItem.sourceSize.height 52 | } 53 | } 54 | 55 | RowLayout { 56 | anchors { 57 | left: parent.left 58 | leftMargin: 10 59 | right: parent.right 60 | rightMargin: 10 61 | bottom: parent.bottom 62 | bottomMargin: 10 63 | } 64 | height: 40 65 | spacing: 10 66 | 67 | Label { 68 | text: qsTr("Source") 69 | font.bold: true 70 | } 71 | 72 | TextField { 73 | id: inputBox 74 | placeholderText: qsTr("Files on the disk and embeded resources are all supported") 75 | text: fileDialog.file 76 | readOnly: true 77 | Layout.fillWidth: true 78 | } 79 | 80 | Button { 81 | text: qsTr("Browse") 82 | onClicked: fileDialog.open() 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/qtlottiedrawengine_skottie.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "qtlottiedrawengine.h" 28 | 29 | using Skottie_Animation = void; 30 | using Skottie_Pixmap = void; 31 | 32 | class QTLOTTIE_API QtLottieSkottieEngine : public QtLottieDrawEngine 33 | { 34 | Q_OBJECT 35 | Q_DISABLE_COPY_MOVE(QtLottieSkottieEngine) 36 | 37 | public: 38 | explicit QtLottieSkottieEngine(QObject *parent = nullptr); 39 | ~QtLottieSkottieEngine() override; 40 | 41 | void paint(QPainter *painter, const QSize &s) override; 42 | void render(const QSize &s) override; 43 | void release() override; 44 | 45 | QString name() const override; 46 | 47 | QUrl source() const override; 48 | bool setSource(const QUrl &value) override; 49 | 50 | qint64 frameRate() const override; 51 | 52 | qint64 duration() const override; 53 | 54 | QSize size() const override; 55 | 56 | qint64 loops() const override; 57 | void setLoops(const qint64 value) override; 58 | 59 | bool available() const override; 60 | 61 | bool playing() const override; 62 | 63 | qreal devicePixelRatio() const override; 64 | void setDevicePixelRatio(const qreal value) override; 65 | 66 | public Q_SLOTS: 67 | void pause() override; 68 | void resume() override; 69 | 70 | private: 71 | QUrl m_source = {}; 72 | Skottie_Animation *m_animation = nullptr; 73 | quint64 m_currentFrame = 0; 74 | quint64 m_totalFrame = 0; 75 | quint64 m_width = 0; 76 | quint64 m_height = 0; 77 | bool m_hasFirstUpdate = false; 78 | qint64 m_frameRate = 0; 79 | qint64 m_duration = 0; 80 | qint64 m_loops = 0; 81 | qint64 m_loopTimes = 0; 82 | bool m_shouldStop = false; 83 | qreal m_devicePixelRatio = 0.0; 84 | }; 85 | -------------------------------------------------------------------------------- /src/qtlottiedrawengine_rlottie.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "qtlottiedrawengine.h" 28 | 29 | struct Lottie_Animation; 30 | 31 | class QTLOTTIE_API QtLottieRLottieEngine : public QtLottieDrawEngine 32 | { 33 | Q_OBJECT 34 | Q_DISABLE_COPY_MOVE(QtLottieRLottieEngine) 35 | 36 | public: 37 | explicit QtLottieRLottieEngine(QObject *parent = nullptr); 38 | ~QtLottieRLottieEngine() override; 39 | 40 | void paint(QPainter *painter, const QSize &s) override; 41 | void render(const QSize &s) override; 42 | void release() override; 43 | 44 | QString name() const override; 45 | 46 | QUrl source() const override; 47 | bool setSource(const QUrl &value) override; 48 | 49 | qint64 frameRate() const override; 50 | 51 | qint64 duration() const override; 52 | 53 | QSize size() const override; 54 | 55 | qint64 loops() const override; 56 | void setLoops(const qint64 value) override; 57 | 58 | bool available() const override; 59 | 60 | bool playing() const override; 61 | 62 | qreal devicePixelRatio() const override; 63 | void setDevicePixelRatio(const qreal value) override; 64 | 65 | public Q_SLOTS: 66 | void pause() override; 67 | void resume() override; 68 | 69 | private: 70 | QUrl m_source = {}; 71 | Lottie_Animation *m_animation = nullptr; 72 | QScopedArrayPointer m_frameBuffer; 73 | quint64 m_currentFrame = 0; 74 | quint64 m_totalFrame = 0; 75 | quint64 m_width = 0; 76 | quint64 m_height = 0; 77 | bool m_hasFirstUpdate = false; 78 | qint64 m_frameRate = 0; 79 | qint64 m_duration = 0; 80 | qint64 m_loops = 0; 81 | qint64 m_loopTimes = 0; 82 | bool m_shouldStop = false; 83 | qreal m_devicePixelRatio = 0.0; 84 | }; 85 | -------------------------------------------------------------------------------- /src/qtlottiedrawenginefactory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "qtlottiedrawenginefactory.h" 26 | #include "qtlottiedrawengine_skottie.h" 27 | #include "qtlottiedrawengine_rlottie.h" 28 | #include 29 | 30 | static constexpr const char kPreferredEngine[] = "QTLOTTIE_PREFERRED_ENGINE"; 31 | 32 | QtLottieDrawEngine *QtLottieDrawEngineFactory::create(const Backend backend) 33 | { 34 | switch (backend) { 35 | case Backend::Skottie: 36 | return new QtLottieSkottieEngine(); 37 | case Backend::RLottie: 38 | return new QtLottieRLottieEngine(); 39 | } 40 | return nullptr; 41 | } 42 | 43 | QtLottieDrawEngine *QtLottieDrawEngineFactory::create(const char *name) 44 | { 45 | Q_ASSERT(name); 46 | if (!name) { 47 | return nullptr; 48 | } 49 | if (qstricmp(name, "skottie") == 0) { 50 | return create(Backend::Skottie); 51 | } 52 | if (qstricmp(name, "rlottie") == 0) { 53 | return create(Backend::RLottie); 54 | } 55 | qWarning() << "Unsupported lottie backend:" << name; 56 | return nullptr; 57 | } 58 | 59 | QtLottieDrawEngine *QtLottieDrawEngineFactory::create() 60 | { 61 | const QString preferred = qEnvironmentVariable(kPreferredEngine, QStringLiteral("skottie")); 62 | if (const auto engine = create(qUtf8Printable(preferred))) { 63 | if (engine->available()) { 64 | return engine; 65 | } 66 | engine->release(); 67 | qWarning() << preferred << "is not available."; 68 | } 69 | if (const auto engine = create("rlottie")) { 70 | if (engine->available()) { 71 | return engine; 72 | } 73 | engine->release(); 74 | qWarning() << "rlottie is not available."; 75 | } 76 | // ### TODO: Use Qt Lottie (provided by TQtC) as the final fallback. 77 | return nullptr; 78 | } 79 | -------------------------------------------------------------------------------- /examples/widget/widget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "widget.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | Widget::Widget(QWidget *parent) : QWidget(parent) 34 | { 35 | setWindowTitle(tr("QtLottie Widget Example")); 36 | resize(800, 600); 37 | const auto lottieWidget = new QtLottieWidget(this); 38 | const auto lottieLayout = new QVBoxLayout(this); 39 | lottieLayout->setContentsMargins(0, 0, 0, 0); 40 | lottieLayout->setSpacing(0); 41 | lottieLayout->addWidget(lottieWidget); 42 | setLayout(lottieLayout); 43 | const auto label = new QLabel(this); 44 | label->setText(tr("Source")); 45 | const auto lineEdit = new QLineEdit(this); 46 | lineEdit->setReadOnly(true); 47 | lineEdit->setPlaceholderText(tr("Files on the disk and embeded resources are all supported")); 48 | const auto browseBtn = new QPushButton(this); 49 | browseBtn->setText(tr("Browse")); 50 | const auto bottomPanelLayout = new QHBoxLayout(); 51 | bottomPanelLayout->addWidget(label); 52 | bottomPanelLayout->addWidget(lineEdit); 53 | bottomPanelLayout->addWidget(browseBtn); 54 | const auto layout2 = new QVBoxLayout(lottieWidget); 55 | layout2->addStretch(); 56 | layout2->addLayout(bottomPanelLayout); 57 | lottieWidget->setLayout(layout2); 58 | connect(browseBtn, &QPushButton::clicked, this, [this, lineEdit, lottieWidget](){ 59 | const QUrl url = QFileDialog::getOpenFileUrl(this, tr("Select a Bodymovin file"), {}, tr("Bodymovin files (*.json);;All files (*)")); 60 | if (url.isValid()) { 61 | lineEdit->setText(url.toString()); 62 | lottieWidget->setSource(url); 63 | } 64 | }); 65 | connect(lottieWidget, &QtLottieWidget::sourceSizeChanged, this, [this, lottieWidget](){ 66 | resize(lottieWidget->sourceSize()); 67 | }); 68 | } 69 | 70 | Widget::~Widget() = default; 71 | -------------------------------------------------------------------------------- /src/qtlottieitem.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "qtlottie_global.h" 28 | #include 29 | #include 30 | 31 | class QtLottieDrawEngine; 32 | 33 | class QTLOTTIE_API QtLottieItem : public QQuickPaintedItem 34 | { 35 | Q_OBJECT 36 | Q_DISABLE_COPY_MOVE(QtLottieItem) 37 | #ifdef QML_NAMED_ELEMENT 38 | QML_NAMED_ELEMENT(LottieItem) 39 | #endif 40 | Q_PROPERTY(QString backend READ backend CONSTANT FINAL) 41 | Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged FINAL) 42 | Q_PROPERTY(qint64 frameRate READ frameRate NOTIFY frameRateChanged FINAL) 43 | Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged FINAL) 44 | Q_PROPERTY(QSizeF sourceSize READ sourceSize NOTIFY sourceSizeChanged FINAL) 45 | Q_PROPERTY(qint64 loops READ loops WRITE setLoops NOTIFY loopsChanged FINAL) 46 | Q_PROPERTY(bool available READ available CONSTANT FINAL) 47 | Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged FINAL) 48 | 49 | public: 50 | explicit QtLottieItem(QQuickItem *parent = nullptr); 51 | ~QtLottieItem() override; 52 | 53 | void paint(QPainter *painter) override; 54 | 55 | QString backend() const; 56 | 57 | QUrl source() const; 58 | void setSource(const QUrl &value); 59 | 60 | qint64 frameRate() const; 61 | 62 | qint64 duration() const; 63 | 64 | QSizeF sourceSize() const; 65 | 66 | qint64 loops() const; 67 | void setLoops(const qint64 value); 68 | 69 | bool available() const; 70 | 71 | qreal devicePixelRatio() const; 72 | void setDevicePixelRatio(const qreal value); 73 | 74 | public Q_SLOTS: 75 | void dispose(); 76 | void pause(); 77 | void resume(); 78 | 79 | Q_SIGNALS: 80 | void sourceChanged(const QUrl &); 81 | void frameRateChanged(qint64); 82 | void durationChanged(qint64); 83 | void sourceSizeChanged(const QSizeF &); 84 | void loopsChanged(qint64); 85 | void devicePixelRatioChanged(qreal); 86 | 87 | private: 88 | QUrl m_source = {}; 89 | QtLottieDrawEngine *m_drawEngine = nullptr; 90 | QTimer m_timer; 91 | }; 92 | -------------------------------------------------------------------------------- /src/qtlottiewidget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "qtlottie_global.h" 28 | #include 29 | #include 30 | #include 31 | 32 | class QtLottieDrawEngine; 33 | 34 | class QTLOTTIE_API QtLottieWidget : public QWidget 35 | { 36 | Q_OBJECT 37 | Q_DISABLE_COPY_MOVE(QtLottieWidget) 38 | Q_PROPERTY(QString backend READ backend CONSTANT FINAL) 39 | Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged FINAL) 40 | Q_PROPERTY(qint64 frameRate READ frameRate NOTIFY frameRateChanged FINAL) 41 | Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged FINAL) 42 | Q_PROPERTY(QSize sourceSize READ sourceSize NOTIFY sourceSizeChanged FINAL) 43 | Q_PROPERTY(qint64 loops READ loops WRITE setLoops NOTIFY loopsChanged FINAL) 44 | Q_PROPERTY(bool available READ available CONSTANT FINAL) 45 | Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged FINAL) 46 | 47 | public: 48 | explicit QtLottieWidget(QWidget *parent = nullptr); 49 | ~QtLottieWidget() override; 50 | 51 | QSize minimumSizeHint() const override; 52 | 53 | QString backend() const; 54 | 55 | QUrl source() const; 56 | void setSource(const QUrl &value); 57 | 58 | qint64 frameRate() const; 59 | 60 | qint64 duration() const; 61 | 62 | QSize sourceSize() const; 63 | 64 | qint64 loops() const; 65 | void setLoops(const qint64 value); 66 | 67 | bool available() const; 68 | 69 | qreal devicePixelRatio() const; 70 | void setDevicePixelRatio(const qreal value); 71 | 72 | public Q_SLOTS: 73 | void dispose(); 74 | void pause(); 75 | void resume(); 76 | 77 | Q_SIGNALS: 78 | void sourceChanged(const QUrl &); 79 | void frameRateChanged(qint64); 80 | void durationChanged(qint64); 81 | void sourceSizeChanged(const QSize &); 82 | void loopsChanged(qint64); 83 | void devicePixelRatioChanged(qreal); 84 | 85 | protected: 86 | void paintEvent(QPaintEvent *event) override; 87 | 88 | private: 89 | QUrl m_source = {}; 90 | QtLottieDrawEngine *m_drawEngine = nullptr; 91 | QTimer m_timer; 92 | }; 93 | -------------------------------------------------------------------------------- /src/qtlottiedrawengine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2022 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #pragma once 26 | 27 | #include "qtlottie_global.h" 28 | #include 29 | #include 30 | #include 31 | 32 | QT_BEGIN_NAMESPACE 33 | class QPainter; 34 | QT_END_NAMESPACE 35 | 36 | class QTLOTTIE_API QtLottieDrawEngine : public QObject 37 | { 38 | Q_OBJECT 39 | Q_DISABLE_COPY_MOVE(QtLottieDrawEngine) 40 | Q_PROPERTY(QString name READ name CONSTANT FINAL) 41 | Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged FINAL) 42 | Q_PROPERTY(qint64 frameRate READ frameRate NOTIFY frameRateChanged FINAL) 43 | Q_PROPERTY(qint64 duration READ duration NOTIFY durationChanged FINAL) 44 | Q_PROPERTY(QSize size READ size NOTIFY sizeChanged FINAL) 45 | Q_PROPERTY(qint64 loops READ loops WRITE setLoops NOTIFY loopsChanged FINAL) 46 | Q_PROPERTY(bool available READ available CONSTANT FINAL) 47 | Q_PROPERTY(bool playing READ playing NOTIFY playingChanged FINAL) 48 | Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged FINAL) 49 | 50 | public: 51 | explicit QtLottieDrawEngine(QObject *parent = nullptr) : QObject(parent) {} 52 | ~QtLottieDrawEngine() override = default; 53 | 54 | virtual void paint(QPainter *painter, const QSize &s) = 0; 55 | virtual void render(const QSize &s) = 0; 56 | virtual void release() = 0; 57 | 58 | virtual QString name() const = 0; 59 | 60 | virtual QUrl source() const = 0; 61 | virtual bool setSource(const QUrl &value) = 0; 62 | 63 | virtual qint64 frameRate() const = 0; 64 | 65 | virtual qint64 duration() const = 0; 66 | 67 | virtual QSize size() const = 0; 68 | 69 | virtual qint64 loops() const = 0; 70 | virtual void setLoops(const qint64 value) = 0; 71 | 72 | virtual bool available() const = 0; 73 | 74 | virtual bool playing() const = 0; 75 | 76 | virtual qreal devicePixelRatio() const = 0; 77 | virtual void setDevicePixelRatio(const qreal value) = 0; 78 | 79 | public Q_SLOTS: 80 | virtual void pause() = 0; 81 | virtual void resume() = 0; 82 | 83 | Q_SIGNALS: 84 | void sourceChanged(const QUrl &); 85 | void frameRateChanged(qint64); 86 | void durationChanged(qint64); 87 | void sizeChanged(const QSize &); 88 | void loopsChanged(qint64); 89 | void playingChanged(bool); 90 | void devicePixelRatioChanged(qreal); 91 | 92 | void needsRepaint(); 93 | }; 94 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 2 | 3 | set(CMAKE_AUTOUIC ON) 4 | set(CMAKE_AUTOMOC ON) 5 | set(CMAKE_AUTORCC ON) 6 | 7 | find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Gui) 8 | find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui) 9 | 10 | find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets) 11 | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets) 12 | 13 | find_package(QT NAMES Qt6 Qt5 COMPONENTS Quick) 14 | find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Quick) 15 | 16 | set(PUBLIC_HEADERS 17 | qtlottie_global.h 18 | qtlottiedrawengine.h 19 | qtlottiedrawenginefactory.h 20 | ) 21 | 22 | set(PRIVATE_HEADERS 23 | qtlottiedrawengine_skottie.h 24 | qtlottiedrawengine_rlottie.h 25 | ) 26 | 27 | set(SOURCES 28 | qtlottiedrawenginefactory.cpp 29 | qtlottiedrawengine_skottie.cpp 30 | qtlottiedrawengine_rlottie.cpp 31 | ) 32 | 33 | if(TARGET Qt${QT_VERSION_MAJOR}::Widgets) 34 | list(APPEND PUBLIC_HEADERS qtlottiewidget.h) 35 | list(APPEND SOURCES qtlottiewidget.cpp) 36 | endif() 37 | 38 | if(TARGET Qt${QT_VERSION_MAJOR}::Quick) 39 | list(APPEND PUBLIC_HEADERS qtlottieitem.h) 40 | list(APPEND SOURCES qtlottieitem.cpp) 41 | endif() 42 | 43 | if(WIN32 AND BUILD_SHARED_LIBS) 44 | enable_language(RC) 45 | list(APPEND SOURCES qtlottie.rc) 46 | endif() 47 | 48 | add_library(${PROJECT_NAME}) 49 | add_library(wangwenx190::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) 50 | 51 | target_sources(${PROJECT_NAME} PRIVATE 52 | ${PUBLIC_HEADERS} 53 | ${PRIVATE_HEADERS} 54 | ${SOURCES} 55 | ) 56 | 57 | if(NOT BUILD_SHARED_LIBS) 58 | target_compile_definitions(${PROJECT_NAME} PUBLIC 59 | QTLOTTIE_STATIC 60 | ) 61 | endif() 62 | 63 | target_compile_definitions(${PROJECT_NAME} PRIVATE 64 | QT_NO_CAST_FROM_ASCII 65 | QT_NO_CAST_TO_ASCII 66 | QT_NO_URL_CAST_FROM_STRING 67 | QT_NO_CAST_FROM_BYTEARRAY 68 | QT_NO_KEYWORDS 69 | QT_NO_NARROWING_CONVERSIONS_IN_CONNECT 70 | QT_NO_FOREACH 71 | QT_USE_QSTRINGBUILDER 72 | QT_DEPRECATED_WARNINGS 73 | QT_DISABLE_DEPRECATED_BEFORE=0x060500 # Remember to bump it when new Qt version releases. 74 | QTLOTTIE_BUILD_LIBRARY 75 | ) 76 | 77 | target_link_libraries(${PROJECT_NAME} PRIVATE 78 | Qt${QT_VERSION_MAJOR}::Gui 79 | ) 80 | 81 | if(TARGET Qt${QT_VERSION_MAJOR}::Widgets) 82 | target_link_libraries(${PROJECT_NAME} PRIVATE 83 | Qt${QT_VERSION_MAJOR}::Widgets 84 | ) 85 | endif() 86 | 87 | if(TARGET Qt${QT_VERSION_MAJOR}::Quick) 88 | target_link_libraries(${PROJECT_NAME} PRIVATE 89 | Qt${QT_VERSION_MAJOR}::Quick 90 | ) 91 | endif() 92 | 93 | include(GNUInstallDirs) 94 | include(CMakePackageConfigHelpers) 95 | 96 | target_include_directories(${PROJECT_NAME} PUBLIC 97 | "$" 98 | "$" 99 | ) 100 | 101 | write_basic_package_version_file( 102 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 103 | VERSION ${PROJECT_VERSION} 104 | COMPATIBILITY AnyNewerVersion 105 | ) 106 | 107 | configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}Config.cmake.in 108 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 109 | INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 110 | #NO_CHECK_REQUIRED_COMPONENTS_MACRO 111 | ) 112 | 113 | install(FILES 114 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" 115 | "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" 116 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 117 | ) 118 | 119 | install(TARGETS ${PROJECT_NAME} 120 | EXPORT ${PROJECT_NAME}Targets 121 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 122 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 123 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} 124 | INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} 125 | ) 126 | 127 | export(EXPORT ${PROJECT_NAME}Targets 128 | FILE "${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Targets.cmake" 129 | NAMESPACE ${PROJECT_NAME}:: 130 | ) 131 | 132 | install(FILES ${PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) 133 | 134 | install(EXPORT ${PROJECT_NAME}Targets 135 | FILE ${PROJECT_NAME}Targets.cmake 136 | NAMESPACE ${PROJECT_NAME}:: 137 | DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} 138 | ) 139 | -------------------------------------------------------------------------------- /src/qtlottiewidget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "qtlottiewidget.h" 26 | #include "qtlottiedrawengine.h" 27 | #include "qtlottiedrawenginefactory.h" 28 | #include 29 | #include 30 | 31 | QtLottieWidget::QtLottieWidget(QWidget *parent) : QWidget(parent) 32 | { 33 | m_drawEngine = QtLottieDrawEngineFactory::create(); 34 | if (!available()) { 35 | qWarning() << "No backends available."; 36 | dispose(); 37 | return; 38 | } 39 | // Use "Qt::PreciseTimer" to get the best appearance, however, it 40 | // will have a performance impact. 41 | m_timer.setTimerType(Qt::CoarseTimer); 42 | connect(&m_timer, &QTimer::timeout, this, [this](){ 43 | if (m_drawEngine->playing()) { 44 | m_drawEngine->render(size()); 45 | } 46 | }); 47 | connect(m_drawEngine, &QtLottieDrawEngine::needsRepaint, this, qOverload<>(&QtLottieWidget::update)); 48 | connect(m_drawEngine, &QtLottieDrawEngine::frameRateChanged, this, [this](qint64 arg){ 49 | if (m_timer.isActive()) { 50 | m_timer.stop(); 51 | } 52 | m_timer.setInterval(qRound(qreal(1000) / qreal(arg))); 53 | if (m_drawEngine->playing()) { 54 | m_timer.start(); 55 | } 56 | Q_EMIT frameRateChanged(arg); 57 | }); 58 | connect(m_drawEngine, &QtLottieDrawEngine::playingChanged, this, [this](bool arg){ 59 | if (arg) { 60 | if (!m_timer.isActive()) { 61 | if (m_timer.interval() <= 0) { 62 | m_timer.setInterval(qRound(qreal(1000) / qreal(m_drawEngine->frameRate()))); 63 | } 64 | m_timer.start(); 65 | } 66 | } else { 67 | if (m_timer.isActive()) { 68 | m_timer.stop(); 69 | } 70 | } 71 | }); 72 | connect(m_drawEngine, &QtLottieDrawEngine::durationChanged, this, &QtLottieWidget::durationChanged); 73 | connect(m_drawEngine, &QtLottieDrawEngine::sizeChanged, this, &QtLottieWidget::sourceSizeChanged); 74 | connect(m_drawEngine, &QtLottieDrawEngine::loopsChanged, this, &QtLottieWidget::loopsChanged); 75 | connect(m_drawEngine, &QtLottieDrawEngine::devicePixelRatioChanged, this, &QtLottieWidget::devicePixelRatioChanged); 76 | } 77 | 78 | QtLottieWidget::~QtLottieWidget() 79 | { 80 | dispose(); 81 | } 82 | 83 | void QtLottieWidget::dispose() 84 | { 85 | if (m_timer.isActive()) { 86 | m_timer.stop(); 87 | } 88 | if (m_drawEngine) { 89 | m_drawEngine->release(); 90 | m_drawEngine = nullptr; 91 | } 92 | } 93 | 94 | void QtLottieWidget::pause() 95 | { 96 | if (available()) { 97 | m_drawEngine->pause(); 98 | } 99 | } 100 | 101 | void QtLottieWidget::resume() 102 | { 103 | if (available()) { 104 | m_drawEngine->resume(); 105 | } 106 | } 107 | 108 | QSize QtLottieWidget::minimumSizeHint() const 109 | { 110 | // Our lottie backend will fail to paint if the size of the widget is too small. 111 | // This size will be ignored if you set the size policy or minimum size explicitly. 112 | return {50, 50}; 113 | } 114 | 115 | QString QtLottieWidget::backend() const 116 | { 117 | return available() ? m_drawEngine->name() : QStringLiteral("Unknown"); 118 | } 119 | 120 | QUrl QtLottieWidget::source() const 121 | { 122 | return m_source; 123 | } 124 | 125 | void QtLottieWidget::setSource(const QUrl &value) 126 | { 127 | if (!value.isValid()) { 128 | qWarning() << value << "is not a valid URL."; 129 | return; 130 | } 131 | if (m_source != value) { 132 | m_source = value; 133 | if (available()) { 134 | if (!m_drawEngine->setSource(value)) { 135 | qWarning() << "Failed to start playing."; 136 | } 137 | } 138 | Q_EMIT sourceChanged(m_source); 139 | } 140 | } 141 | 142 | qint64 QtLottieWidget::frameRate() const 143 | { 144 | // TODO: is the fallback value appropriate? 145 | return available() ? m_drawEngine->frameRate() : 30; 146 | } 147 | 148 | qint64 QtLottieWidget::duration() const 149 | { 150 | // TODO: is the fallback value appropriate? 151 | return available() ? m_drawEngine->duration() : 0; 152 | } 153 | 154 | QSize QtLottieWidget::sourceSize() const 155 | { 156 | // TODO: is the fallback value appropriate? 157 | return available() ? m_drawEngine->size() : QSize{50, 50}; 158 | } 159 | 160 | qint64 QtLottieWidget::loops() const 161 | { 162 | return available() ? m_drawEngine->loops() : 0; 163 | } 164 | 165 | void QtLottieWidget::setLoops(const qint64 value) 166 | { 167 | if (available()) { 168 | m_drawEngine->setLoops(value); 169 | } 170 | } 171 | 172 | bool QtLottieWidget::available() const 173 | { 174 | return (m_drawEngine && m_drawEngine->available()); 175 | } 176 | 177 | qreal QtLottieWidget::devicePixelRatio() const 178 | { 179 | return available() ? m_drawEngine->devicePixelRatio() : qreal(1); 180 | } 181 | 182 | void QtLottieWidget::setDevicePixelRatio(const qreal value) 183 | { 184 | if (!available()) { 185 | return; 186 | } 187 | m_drawEngine->setDevicePixelRatio(value); 188 | } 189 | 190 | void QtLottieWidget::paintEvent(QPaintEvent *event) 191 | { 192 | QWidget::paintEvent(event); 193 | QPainter painter(this); 194 | if (available()) { 195 | m_drawEngine->paint(&painter, size()); 196 | } 197 | } 198 | -------------------------------------------------------------------------------- /src/qtlottieitem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "qtlottieitem.h" 26 | #include "qtlottiedrawengine.h" 27 | #include "qtlottiedrawenginefactory.h" 28 | #include 29 | 30 | QtLottieItem::QtLottieItem(QQuickItem *parent) : QQuickPaintedItem(parent) 31 | { 32 | m_drawEngine = QtLottieDrawEngineFactory::create(); 33 | if (!available()) { 34 | qWarning() << "No backends available."; 35 | dispose(); 36 | return; 37 | } 38 | // Use "Qt::PreciseTimer" to get the best appearance, however, it 39 | // will have a performance impact. 40 | m_timer.setTimerType(Qt::CoarseTimer); 41 | connect(&m_timer, &QTimer::timeout, this, [this](){ 42 | if (m_drawEngine->playing()) { 43 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) 44 | const QSizeF s = size(); 45 | #else 46 | const QSizeF s = {width(), height()}; 47 | #endif 48 | m_drawEngine->render(s.toSize()); 49 | } 50 | }); 51 | connect(m_drawEngine, &QtLottieDrawEngine::needsRepaint, this, [this](){ 52 | update(); 53 | }); 54 | connect(m_drawEngine, &QtLottieDrawEngine::frameRateChanged, this, [this](qint64 arg){ 55 | if (m_timer.isActive()) { 56 | m_timer.stop(); 57 | } 58 | m_timer.setInterval(qRound(qreal(1000) / qreal(arg))); 59 | if (m_drawEngine->playing()) { 60 | m_timer.start(); 61 | } 62 | Q_EMIT frameRateChanged(arg); 63 | }); 64 | connect(m_drawEngine, &QtLottieDrawEngine::playingChanged, this, [this](bool arg){ 65 | if (arg) { 66 | if (!m_timer.isActive()) { 67 | if (m_timer.interval() <= 0) { 68 | m_timer.setInterval(qRound(qreal(1000) / qreal(m_drawEngine->frameRate()))); 69 | } 70 | m_timer.start(); 71 | } 72 | } else { 73 | if (m_timer.isActive()) { 74 | m_timer.stop(); 75 | } 76 | } 77 | }); 78 | connect(m_drawEngine, &QtLottieDrawEngine::durationChanged, this, &QtLottieItem::durationChanged); 79 | connect(m_drawEngine, &QtLottieDrawEngine::sizeChanged, this, &QtLottieItem::sourceSizeChanged); 80 | connect(m_drawEngine, &QtLottieDrawEngine::loopsChanged, this, &QtLottieItem::loopsChanged); 81 | connect(m_drawEngine, &QtLottieDrawEngine::devicePixelRatioChanged, this, &QtLottieItem::devicePixelRatioChanged); 82 | } 83 | 84 | QtLottieItem::~QtLottieItem() 85 | { 86 | dispose(); 87 | } 88 | 89 | void QtLottieItem::paint(QPainter *painter) 90 | { 91 | Q_ASSERT(painter); 92 | if (!painter) { 93 | return; 94 | } 95 | if (available()) { 96 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) 97 | const QSizeF s = size(); 98 | #else 99 | const QSizeF s = {width(), height()}; 100 | #endif 101 | m_drawEngine->paint(painter, s.toSize()); 102 | } 103 | } 104 | 105 | void QtLottieItem::dispose() 106 | { 107 | if (m_timer.isActive()) { 108 | m_timer.stop(); 109 | } 110 | if (m_drawEngine) { 111 | m_drawEngine->release(); 112 | m_drawEngine = nullptr; 113 | } 114 | } 115 | 116 | void QtLottieItem::pause() 117 | { 118 | if (available()) { 119 | m_drawEngine->pause(); 120 | } 121 | } 122 | 123 | void QtLottieItem::resume() 124 | { 125 | if (available()) { 126 | m_drawEngine->resume(); 127 | } 128 | } 129 | 130 | QString QtLottieItem::backend() const 131 | { 132 | return available() ? m_drawEngine->name() : QStringLiteral("Unknown"); 133 | } 134 | 135 | QUrl QtLottieItem::source() const 136 | { 137 | return m_source; 138 | } 139 | 140 | void QtLottieItem::setSource(const QUrl &value) 141 | { 142 | if (!value.isValid()) { 143 | qWarning() << value << "is not a valid URL."; 144 | return; 145 | } 146 | if (m_source != value) { 147 | m_source = value; 148 | if (available()) { 149 | if (!m_drawEngine->setSource(value)) { 150 | qWarning() << "Failed to start playing."; 151 | } 152 | } 153 | Q_EMIT sourceChanged(m_source); 154 | } 155 | } 156 | 157 | qint64 QtLottieItem::frameRate() const 158 | { 159 | // TODO: is the fallback value appropriate? 160 | return available() ? m_drawEngine->frameRate() : 30; 161 | } 162 | 163 | qint64 QtLottieItem::duration() const 164 | { 165 | // TODO: is the fallback value appropriate? 166 | return available() ? m_drawEngine->duration() : 0; 167 | } 168 | 169 | QSizeF QtLottieItem::sourceSize() const 170 | { 171 | // TODO: is the fallback value appropriate? 172 | return available() ? m_drawEngine->size() : QSizeF{qreal(50), qreal(50)}; 173 | } 174 | 175 | qint64 QtLottieItem::loops() const 176 | { 177 | return available() ? m_drawEngine->loops() : 0; 178 | } 179 | 180 | void QtLottieItem::setLoops(const qint64 value) 181 | { 182 | if (available()) { 183 | m_drawEngine->setLoops(value); 184 | } 185 | } 186 | 187 | bool QtLottieItem::available() const 188 | { 189 | return (m_drawEngine && m_drawEngine->available()); 190 | } 191 | 192 | qreal QtLottieItem::devicePixelRatio() const 193 | { 194 | return available() ? m_drawEngine->devicePixelRatio() : qreal(1); 195 | } 196 | 197 | void QtLottieItem::setDevicePixelRatio(const qreal value) 198 | { 199 | if (!available()) { 200 | return; 201 | } 202 | m_drawEngine->setDevicePixelRatio(value); 203 | } 204 | -------------------------------------------------------------------------------- /examples/lottiefiles/39506-check.json: -------------------------------------------------------------------------------- 1 | {"v":"5.3.4","fr":48,"ip":0,"op":120,"w":562,"h":562,"nm":"Checkbox","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"check","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[281,281,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.842,-30.16],[0,0],[0,0],[0,0]],"o":[[-6.465,28.5],[0,0],[0,0],[0,0]],"v":[[-146.035,-37.5],[-129.667,25.933],[-58.35,95.089],[129.667,-95.089]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.624,0.216,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":24,"s":[0],"e":[16]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":44,"s":[16],"e":[16]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.65],"y":[0]},"n":["0p833_0p833_0p65_0"],"t":74,"s":[16],"e":[0]},{"t":94}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.167]},"n":["0_1_0p167_0p167"],"t":22,"s":[0],"e":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"n":["0p667_1_0p333_0"],"t":44,"s":[100],"e":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.635],"y":[0]},"n":["0p833_0p833_0p635_0"],"t":72,"s":[100],"e":[0]},{"t":93}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":22,"op":94,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"circle","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[281,281,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,82.424],[82.424,0],[0,-82.424],[-82.424,0]],"o":[[0,-82.424],[-82.424,0],[0,82.424],[82.424,0]],"v":[[149.243,0],[0,-149.243],[-149.243,0],[0,149.243]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.624,0.216,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":1,"ml":10,"ml2":{"a":0,"k":10,"ix":8},"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.963]},"o":{"x":[0.657],"y":[0]},"n":["0p833_0p963_0p657_0"],"t":4,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[13.963]},"o":{"x":[0.167],"y":[12.963]},"n":["0p833_13p963_0p167_12p963"],"t":24,"s":[100],"e":[100]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.037]},"n":["0_1_0p167_0p037"],"t":94,"s":[100],"e":[0]},{"t":114}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.965]},"o":{"x":[0.687],"y":[0]},"n":["0p833_0p965_0p687_0"],"t":2,"s":[0],"e":[100]},{"i":{"x":[0.833],"y":[14.333]},"o":{"x":[0.167],"y":[13.187]},"n":["0p833_14p333_0p167_13p187"],"t":21,"s":[100],"e":[100]},{"i":{"x":[0],"y":[1]},"o":{"x":[0.167],"y":[0.033]},"n":["0_1_0p167_0p033"],"t":93,"s":[100],"e":[0]},{"t":111}],"ix":2},"o":{"a":0,"k":170,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":2,"op":113,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Слой 7","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[281,281,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.704,"y":0},"n":"0p667_1_0p704_0","t":0,"s":[{"i":[[38.5,0],[0,0],[0,38.5],[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0]],"o":[[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0],[38.5,0],[0,0],[0,38.5]],"v":[[180,250],[-180,250],[-250,180],[-250,-180],[-180,-250],[180,-250],[250,-180],[250,180]],"c":true}],"e":[{"i":[[34.496,0],[0,0],[0,34.496],[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0]],"o":[[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0],[34.496,0],[0,0],[0,34.496]],"v":[[161.28,224],[-161.28,224],[-224,161.28],[-224,-161.28],[-161.28,-224],[161.28,-224],[224,-161.28],[224,161.28]],"c":true}]},{"i":{"x":0.299,"y":1},"o":{"x":0.333,"y":0},"n":"0p299_1_0p333_0","t":11,"s":[{"i":[[34.496,0],[0,0],[0,34.496],[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0]],"o":[[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0],[34.496,0],[0,0],[0,34.496]],"v":[[161.28,224],[-161.28,224],[-224,161.28],[-224,-161.28],[-161.28,-224],[161.28,-224],[224,-161.28],[224,161.28]],"c":true}],"e":[{"i":[[38.5,0],[0,0],[0,38.5],[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0]],"o":[[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0],[38.5,0],[0,0],[0,38.5]],"v":[[180,250],[-180,250],[-250,180],[-250,-180],[-180,-250],[180,-250],[250,-180],[250,180]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"n":"0p667_1_0p333_0","t":44,"s":[{"i":[[38.5,0],[0,0],[0,38.5],[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0]],"o":[[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0],[38.5,0],[0,0],[0,38.5]],"v":[[180,250],[-180,250],[-250,180],[-250,-180],[-180,-250],[180,-250],[250,-180],[250,180]],"c":true}],"e":[{"i":[[38.5,0],[0,0],[0,38.5],[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0]],"o":[[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0],[38.5,0],[0,0],[0,38.5]],"v":[[180,250],[-180,250],[-250,180],[-250,-180],[-180,-250],[180,-250],[250,-180],[250,180]],"c":true}]},{"i":{"x":0.465,"y":1},"o":{"x":0.333,"y":0},"n":"0p465_1_0p333_0","t":72,"s":[{"i":[[38.5,0],[0,0],[0,38.5],[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0]],"o":[[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0],[38.5,0],[0,0],[0,38.5]],"v":[[180,250],[-180,250],[-250,180],[-250,-180],[-180,-250],[180,-250],[250,-180],[250,180]],"c":true}],"e":[{"i":[[34.496,0],[0,0],[0,34.496],[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0]],"o":[[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0],[34.496,0],[0,0],[0,34.496]],"v":[[161.28,224],[-161.28,224],[-224,161.28],[-224,-161.28],[-161.28,-224],[161.28,-224],[224,-161.28],[224,161.28]],"c":true}]},{"i":{"x":0.061,"y":1},"o":{"x":0.333,"y":0},"n":"0p061_1_0p333_0","t":105,"s":[{"i":[[34.496,0],[0,0],[0,34.496],[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0]],"o":[[0,0],[-34.496,0],[0,0],[0,-34.496],[0,0],[34.496,0],[0,0],[0,34.496]],"v":[[161.28,224],[-161.28,224],[-224,161.28],[-224,-161.28],[-161.28,-224],[161.28,-224],[224,-161.28],[224,161.28]],"c":true}],"e":[{"i":[[38.5,0],[0,0],[0,38.5],[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0]],"o":[[0,0],[-38.5,0],[0,0],[0,-38.5],[0,0],[38.5,0],[0,0],[0,38.5]],"v":[[180,250],[-180,250],[-250,180],[-250,-180],[-180,-250],[180,-250],[250,-180],[250,180]],"c":true}]},{"t":120}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.624,0.216,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":60,"ix":5},"lc":2,"lj":2,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /examples/lottiefiles/43846-butterfly-loader.json: -------------------------------------------------------------------------------- 1 | {"v":"5.7.4","fr":30.0000305175781,"ip":0,"op":121.000123087565,"w":600,"h":600,"nm":"Butterfly Loader","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"NULL CONTROL 1","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":120.000122070312,"s":[720]}],"ix":10},"p":{"a":0,"k":[300,300,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":121.000123087565,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 5","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2,"l":2},"a":{"a":0,"k":[-43.842,0.88,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-23.842,23.38],[-18.342,-19.62],[-0.342,-47.62],[23.892,-29.161],[22.158,28.88],[-13.041,17.982],[-44,6],[-23.446,20.2],[18.905,17.679],[29.158,-24.12],[-1.325,-46.786],[-19.343,-23.12],[-22.342,16.88],[21.18,21.368],[46,2],[28.583,24.467]],"o":[[23.181,-22.731],[23.499,25.136],[0.305,42.379],[-22.842,27.88],[-20.341,-26.512],[23.658,-32.62],[44,-6],[29.157,-25.12],[-18.843,-17.62],[-24.462,20.236],[1.195,42.202],[22.862,27.328],[30.984,-23.409],[-31.342,-31.62],[-46,-2],[-25.842,-22.12]],"v":[[-164,-120],[-82.5,-119.5],[-47,-0.5],[-77.5,117],[-168,116],[-170,42],[-49.5,-1],[73.5,-34],[78.5,-120],[-3,-120],[-46.518,-0.334],[-12,116],[70.5,128],[79.5,43],[-49.5,-1],[-161,-34]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":20,"ix":2},"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":120.000122070312,"s":[360]}],"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"st","c":{"a":0,"k":[0.819607843137,0.192156862745,0.243137254902,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121.000123087565,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":3,"nm":"NULL CONTROL ","parent":1,"sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[50,50,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":121.000123087565,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Shape Layer 4","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[130,-30,0],"ix":2,"l":2},"a":{"a":0,"k":[-259,-129,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[50,50],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.16862745098,0.317647058824,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-259,-129],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121.000123087565,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Shape Layer 2","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[130,130,0],"ix":2,"l":2},"a":{"a":0,"k":[-259,-129,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[54,54],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Shape Layer 4').content('Ellipse 1').content('Ellipse Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.16862745098,0.317647058824,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-259,-129],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121.000123087565,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 3","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-30,-30,0],"ix":2,"l":2},"a":{"a":0,"k":[-259,-129,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[54,54],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Shape Layer 2').content('Ellipse 1').content('Ellipse Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.16862745098,0.317647058824,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-259,-129],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121.000123087565,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 1","parent":3,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-30,130,0],"ix":2,"l":2},"a":{"a":0,"k":[-259,-129,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[54,54],"ix":2,"x":"var $bm_rt;\n$bm_rt = thisComp.layer('Shape Layer 3').content('Ellipse 1').content('Ellipse Path 1').size;"},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.133333333333,0.16862745098,0.317647058824,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-259,-129],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":121.000123087565,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /examples/lottiefiles/53175-ball-spinner.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.21","a":"","k":"","d":"","tc":""},"fr":29.9700012207031,"ip":0,"op":270.000010997325,"w":124,"h":124,"nm":"ball-thinking","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":269.000010956595,"s":[1440]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[62,39,0],"to":[-3.833,7.667,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":120,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":150,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":180,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":210,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":240,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[3.833,7.667,0]},{"t":270.000010997325,"s":[62,39,0]}],"ix":2,"x":"var $bm_rt;\nfunction easeandwizz_inoutExpo(t, b, c, d) {\n var CORRECTION = 0.000976563;\n var v;\n if ((t /= d / 2) < 1) {\n v = $bm_sub(Math.pow(2, $bm_mul(10, $bm_sub(t, 1))), CORRECTION);\n } else {\n v = $bm_sum($bm_sum($bm_neg(Math.pow(2, $bm_mul(-10, $bm_sub(t, 1)))), 2), CORRECTION);\n }\n return $bm_sum(b, $bm_mul($bm_div(v, 2), c));\n}\nfunction easeAndWizz() {\n var t, d, sX, eX, sY, eY, sZ, eZ, val1, val2, val2, val3;\n var n = 0;\n if (numKeys > 0) {\n n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n }\n try {\n var key1 = key(n);\n var key2 = key($bm_sum(n, 1));\n } catch (e) {\n return null;\n }\n var dim = 1;\n try {\n key(1)[1].length;\n dim = 2;\n key(1)[2].length;\n dim = 3;\n } catch (e) {\n }\n t = $bm_sub(time, key1.time);\n d = $bm_sub(key2.time, key1.time);\n sX = key1[0];\n eX = $bm_sub(key2[0], key1[0]);\n if (dim >= 2) {\n sY = key1[1];\n eY = $bm_sub(key2[1], key1[1]);\n if (dim >= 3) {\n sZ = key1[2];\n eZ = $bm_sub(key2[2], key1[2]);\n }\n }\n if (time < key1.time || time > key2.time) {\n return value;\n } else {\n val1 = easeandwizz_inoutExpo(t, sX, eX, d);\n switch (dim) {\n case 1:\n return val1;\n break;\n case 2:\n val2 = easeandwizz_inoutExpo(t, sY, eY, d);\n return [\n val1,\n val2\n ];\n break;\n case 3:\n val2 = easeandwizz_inoutExpo(t, sY, eY, d);\n val3 = easeandwizz_inoutExpo(t, sZ, eZ, d);\n return [\n val1,\n val2,\n val3\n ];\n break;\n default:\n return null;\n }\n }\n}\n$bm_rt = easeAndWizz() || value;"},"a":{"a":0,"k":[-11.939,0.561,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[64,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":1,"g":{"p":3,"k":{"a":0,"k":[0,0,0,1,0.504,0.5,0,1,1,1,0,1],"ix":9}},"s":{"a":0,"k":[0.103,-31.829],"ix":5},"e":{"a":0,"k":[0.311,31.472],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-11.939,0.561],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1798.00007323404,"st":0,"bm":1},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 4","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":269.000010956595,"s":[1440]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[85,85,0],"to":[-3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":120,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":150,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":180,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":210,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":240,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-7.667,0,0]},{"t":270.000010997325,"s":[85,85,0]}],"ix":2,"x":"var $bm_rt;\nfunction easeandwizz_inoutExpo(t, b, c, d) {\n var CORRECTION = 0.000976563;\n var v;\n if ((t /= d / 2) < 1) {\n v = $bm_sub(Math.pow(2, $bm_mul(10, $bm_sub(t, 1))), CORRECTION);\n } else {\n v = $bm_sum($bm_sum($bm_neg(Math.pow(2, $bm_mul(-10, $bm_sub(t, 1)))), 2), CORRECTION);\n }\n return $bm_sum(b, $bm_mul($bm_div(v, 2), c));\n}\nfunction easeAndWizz() {\n var t, d, sX, eX, sY, eY, sZ, eZ, val1, val2, val2, val3;\n var n = 0;\n if (numKeys > 0) {\n n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n }\n try {\n var key1 = key(n);\n var key2 = key($bm_sum(n, 1));\n } catch (e) {\n return null;\n }\n var dim = 1;\n try {\n key(1)[1].length;\n dim = 2;\n key(1)[2].length;\n dim = 3;\n } catch (e) {\n }\n t = $bm_sub(time, key1.time);\n d = $bm_sub(key2.time, key1.time);\n sX = key1[0];\n eX = $bm_sub(key2[0], key1[0]);\n if (dim >= 2) {\n sY = key1[1];\n eY = $bm_sub(key2[1], key1[1]);\n if (dim >= 3) {\n sZ = key1[2];\n eZ = $bm_sub(key2[2], key1[2]);\n }\n }\n if (time < key1.time || time > key2.time) {\n return value;\n } else {\n val1 = easeandwizz_inoutExpo(t, sX, eX, d);\n switch (dim) {\n case 1:\n return val1;\n break;\n case 2:\n val2 = easeandwizz_inoutExpo(t, sY, eY, d);\n return [\n val1,\n val2\n ];\n break;\n case 3:\n val2 = easeandwizz_inoutExpo(t, sY, eY, d);\n val3 = easeandwizz_inoutExpo(t, sZ, eZ, d);\n return [\n val1,\n val2,\n val3\n ];\n break;\n default:\n return null;\n }\n }\n}\n$bm_rt = easeAndWizz() || value;"},"a":{"a":0,"k":[-11.939,0.561,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[64,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":1,"g":{"p":3,"k":{"a":0,"k":[0,0,1,0,0.504,0,1,0.5,1,0,1,1],"ix":9}},"s":{"a":0,"k":[0.103,-31.829],"ix":5},"e":{"a":0,"k":[0.311,31.472],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-11.939,0.561],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1798.00007323404,"st":0,"bm":1},{"ddd":0,"ind":3,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":269.000010956595,"s":[1440]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[39,85,0],"to":[7.667,0,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":120,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":150,"s":[62,39,0],"to":[-7.667,0,0],"ti":[-3.833,-7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":180,"s":[39,85,0],"to":[3.833,7.667,0],"ti":[-3.833,7.667,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":210,"s":[85,85,0],"to":[3.833,-7.667,0],"ti":[7.667,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":240,"s":[62,39,0],"to":[-7.667,0,0],"ti":[3.833,-7.667,0]},{"t":270.000010997325,"s":[39,85,0]}],"ix":2,"x":"var $bm_rt;\nfunction easeandwizz_inoutExpo(t, b, c, d) {\n var CORRECTION = 0.000976563;\n var v;\n if ((t /= d / 2) < 1) {\n v = $bm_sub(Math.pow(2, $bm_mul(10, $bm_sub(t, 1))), CORRECTION);\n } else {\n v = $bm_sum($bm_sum($bm_neg(Math.pow(2, $bm_mul(-10, $bm_sub(t, 1)))), 2), CORRECTION);\n }\n return $bm_sum(b, $bm_mul($bm_div(v, 2), c));\n}\nfunction easeAndWizz() {\n var t, d, sX, eX, sY, eY, sZ, eZ, val1, val2, val2, val3;\n var n = 0;\n if (numKeys > 0) {\n n = nearestKey(time).index;\n if (key(n).time > time) {\n n--;\n }\n }\n try {\n var key1 = key(n);\n var key2 = key($bm_sum(n, 1));\n } catch (e) {\n return null;\n }\n var dim = 1;\n try {\n key(1)[1].length;\n dim = 2;\n key(1)[2].length;\n dim = 3;\n } catch (e) {\n }\n t = $bm_sub(time, key1.time);\n d = $bm_sub(key2.time, key1.time);\n sX = key1[0];\n eX = $bm_sub(key2[0], key1[0]);\n if (dim >= 2) {\n sY = key1[1];\n eY = $bm_sub(key2[1], key1[1]);\n if (dim >= 3) {\n sZ = key1[2];\n eZ = $bm_sub(key2[2], key1[2]);\n }\n }\n if (time < key1.time || time > key2.time) {\n return value;\n } else {\n val1 = easeandwizz_inoutExpo(t, sX, eX, d);\n switch (dim) {\n case 1:\n return val1;\n break;\n case 2:\n val2 = easeandwizz_inoutExpo(t, sY, eY, d);\n return [\n val1,\n val2\n ];\n break;\n case 3:\n val2 = easeandwizz_inoutExpo(t, sY, eY, d);\n val3 = easeandwizz_inoutExpo(t, sZ, eZ, d);\n return [\n val1,\n val2,\n val3\n ];\n break;\n default:\n return null;\n }\n }\n}\n$bm_rt = easeAndWizz() || value;"},"a":{"a":0,"k":[-11.939,0.561,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[64,64],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":1,"g":{"p":3,"k":{"a":0,"k":[0,1,0,0,0.504,1,0.5,0,1,1,1,0],"ix":9}},"s":{"a":0,"k":[0.103,-31.829],"ix":5},"e":{"a":0,"k":[0.311,31.472],"ix":6},"t":1,"nm":"Gradient Fill 1","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-11.939,0.561],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1798.00007323404,"st":0,"bm":1}],"markers":[]} -------------------------------------------------------------------------------- /src/qtlottiedrawengine_rlottie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "qtlottiedrawengine_rlottie.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | static constexpr const char kFileName[] = "QTLOTTIE_RLOTTIE_FILENAME"; 36 | 37 | [[nodiscard]] static inline QString getRLottieLibraryName() 38 | { 39 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) 40 | return qEnvironmentVariable(kFileName, QStringLiteral("rlottie")); 41 | #else 42 | const QByteArray ba = qgetenv(kFileName); 43 | return ba.isEmpty() ? QStringLiteral("rlottie") : QString::fromUtf8(ba); 44 | #endif 45 | } 46 | 47 | using lottie_init_ptr = void(*)(); 48 | using lottie_shutdown_ptr = void(*)(); 49 | using lottie_animation_destroy_ptr = void(*)(Lottie_Animation *animation); 50 | using lottie_animation_from_data_ptr = Lottie_Animation *(*)(const char *data, const char *key, const char *resource_path); 51 | using lottie_animation_get_framerate_ptr = double(*)(const Lottie_Animation *animation); 52 | using lottie_animation_get_totalframe_ptr = size_t(*)(const Lottie_Animation *animation); 53 | using lottie_animation_render_ptr = void(*)(Lottie_Animation *animation, size_t frame_num, uint32_t *buffer, size_t width, size_t height, size_t bytes_per_line); 54 | using lottie_animation_get_size_ptr = void(*)(const Lottie_Animation *animation, size_t *width, size_t *height); 55 | using lottie_animation_get_duration_ptr = double(*)(const Lottie_Animation *animation); 56 | 57 | class rlottie_data 58 | { 59 | Q_DISABLE_COPY_MOVE(rlottie_data) 60 | 61 | public: 62 | mutable QMutex mutex; 63 | 64 | lottie_init_ptr lottie_init_pfn = nullptr; 65 | lottie_shutdown_ptr lottie_shutdown_pfn = nullptr; 66 | lottie_animation_destroy_ptr lottie_animation_destroy_pfn = nullptr; 67 | lottie_animation_from_data_ptr lottie_animation_from_data_pfn = nullptr; 68 | lottie_animation_get_framerate_ptr lottie_animation_get_framerate_pfn = nullptr; 69 | lottie_animation_get_totalframe_ptr lottie_animation_get_totalframe_pfn = nullptr; 70 | lottie_animation_render_ptr lottie_animation_render_pfn = nullptr; 71 | lottie_animation_get_size_ptr lottie_animation_get_size_pfn = nullptr; 72 | lottie_animation_get_duration_ptr lottie_animation_get_duration_pfn = nullptr; 73 | 74 | explicit rlottie_data() 75 | { 76 | const bool result = load(); 77 | Q_UNUSED(result); 78 | } 79 | 80 | ~rlottie_data() 81 | { 82 | const bool result = unload(); 83 | Q_UNUSED(result); 84 | } 85 | 86 | [[nodiscard]] bool load(const QString &libName = {}) 87 | { 88 | if (isLoaded()) { 89 | qDebug() << "rlottie library has already been loaded."; 90 | return true; 91 | } 92 | 93 | const QMutexLocker locker(&mutex); 94 | 95 | library.setFileName(libName.isEmpty() ? getRLottieLibraryName() : libName); 96 | if (!library.load()) { 97 | qWarning() << "Failed to load rlottie library:" << library.errorString(); 98 | return false; 99 | } 100 | qDebug() << "rlottie library loaded successfully from" << library.fileName(); 101 | 102 | #define RESOLVE(API) \ 103 | API##_pfn = reinterpret_cast(library.resolve(#API)); \ 104 | if (!API##_pfn) { \ 105 | qWarning() << "Failed to resolve " #API; \ 106 | return false; \ 107 | } 108 | 109 | RESOLVE(lottie_init) 110 | RESOLVE(lottie_shutdown) 111 | RESOLVE(lottie_animation_destroy) 112 | RESOLVE(lottie_animation_from_data) 113 | RESOLVE(lottie_animation_get_framerate) 114 | RESOLVE(lottie_animation_get_totalframe) 115 | RESOLVE(lottie_animation_render) 116 | RESOLVE(lottie_animation_get_size) 117 | RESOLVE(lottie_animation_get_duration) 118 | 119 | #undef RESOLVE 120 | 121 | return true; 122 | } 123 | 124 | [[nodiscard]] bool unload() 125 | { 126 | if (!isLoaded()) { 127 | qDebug() << "rlottie library has already been unloaded."; 128 | return true; 129 | } 130 | 131 | const QMutexLocker locker(&mutex); 132 | 133 | lottie_init_pfn = nullptr; 134 | lottie_shutdown_pfn = nullptr; 135 | lottie_animation_destroy_pfn = nullptr; 136 | lottie_animation_from_data_pfn = nullptr; 137 | lottie_animation_get_framerate_pfn = nullptr; 138 | lottie_animation_get_totalframe_pfn = nullptr; 139 | lottie_animation_render_pfn = nullptr; 140 | lottie_animation_get_size_pfn = nullptr; 141 | lottie_animation_get_duration_pfn = nullptr; 142 | 143 | if (!library.unload()) { 144 | qWarning() << "Failed to unload rlottie library:" << library.errorString(); 145 | return false; 146 | } 147 | 148 | return true; 149 | } 150 | 151 | [[nodiscard]] bool isLoaded() const 152 | { 153 | const QMutexLocker locker(&mutex); 154 | 155 | return lottie_init_pfn && lottie_shutdown_pfn && lottie_animation_destroy_pfn 156 | && lottie_animation_from_data_pfn && lottie_animation_get_framerate_pfn 157 | && lottie_animation_get_totalframe_pfn && lottie_animation_render_pfn 158 | && lottie_animation_get_size_pfn && lottie_animation_get_duration_pfn; 159 | } 160 | 161 | private: 162 | QLibrary library; 163 | }; 164 | 165 | Q_GLOBAL_STATIC(rlottie_data, rlottie) 166 | 167 | QtLottieRLottieEngine::QtLottieRLottieEngine(QObject *parent) : QtLottieDrawEngine(parent) 168 | { 169 | if (rlottie()->isLoaded()) { 170 | if (const auto screen = QGuiApplication::primaryScreen()) { 171 | m_devicePixelRatio = screen->devicePixelRatio(); 172 | } else { 173 | m_devicePixelRatio = 1.0; 174 | } 175 | const QMutexLocker locker(&rlottie()->mutex); 176 | rlottie()->lottie_init_pfn(); 177 | } else { 178 | qWarning() << "The rlottie backend is not available due to can't load rlottie library."; 179 | } 180 | } 181 | 182 | QtLottieRLottieEngine::~QtLottieRLottieEngine() 183 | { 184 | if (!rlottie()->isLoaded()) { 185 | return; 186 | } 187 | const QMutexLocker locker(&rlottie()->mutex); 188 | if (m_animation) { 189 | rlottie()->lottie_animation_destroy_pfn(m_animation); 190 | } 191 | rlottie()->lottie_shutdown_pfn(); 192 | } 193 | 194 | bool QtLottieRLottieEngine::setSource(const QUrl &value) 195 | { 196 | if (!rlottie()->isLoaded()) { 197 | qWarning() << Q_FUNC_INFO << "some necessary rlottie functions are not available."; 198 | return false; 199 | } 200 | Q_ASSERT(value.isValid()); 201 | if (!value.isValid()) { 202 | qWarning() << value << "is not a valid URL."; 203 | return false; 204 | } 205 | if (m_source == value) { 206 | // debug output? 207 | return false; // or true? 208 | } 209 | QString jsonFilePath = {}; 210 | if (value.scheme() == QStringLiteral("qrc")) { 211 | jsonFilePath = value.toString(); 212 | // QFile can't recognize url. 213 | jsonFilePath.replace(QStringLiteral("qrc:"), QStringLiteral(":"), Qt::CaseInsensitive); 214 | jsonFilePath.replace(QStringLiteral(":///"), QStringLiteral(":/")); 215 | } else { 216 | jsonFilePath = value.isLocalFile() ? value.toLocalFile() : value.url(); 217 | } 218 | Q_ASSERT(QFile::exists(jsonFilePath)); 219 | if (!QFile::exists(jsonFilePath)) { 220 | qWarning() << jsonFilePath << "doesn't exist."; 221 | return false; 222 | } 223 | QFile file(jsonFilePath); 224 | if (!file.open(QFile::ReadOnly | QFile::Text)) { 225 | qWarning() << "Failed to open the JSON file:" << jsonFilePath; 226 | return false; 227 | } 228 | const QByteArray jsonBuffer = file.readAll(); 229 | file.close(); 230 | if (jsonBuffer.isEmpty()) { 231 | qWarning() << "File is empty:" << jsonFilePath; 232 | return false; 233 | } 234 | // TODO: support embeded resources. 235 | const QString resDirPath = QCoreApplication::applicationDirPath(); 236 | rlottie()->mutex.lock(); 237 | m_animation = rlottie()->lottie_animation_from_data_pfn(jsonBuffer.constData(), jsonBuffer.constData(), resDirPath.toUtf8().constData()); 238 | rlottie()->mutex.unlock(); 239 | if (!m_animation) { 240 | qWarning() << "Failed to create lottie animation."; 241 | return false; 242 | } 243 | m_source = value; 244 | rlottie()->mutex.lock(); 245 | rlottie()->lottie_animation_get_size_pfn(m_animation, reinterpret_cast(&m_width), reinterpret_cast(&m_height)); 246 | m_frameRate = qRound64(rlottie()->lottie_animation_get_framerate_pfn(m_animation)); 247 | m_duration = qRound64(rlottie()->lottie_animation_get_duration_pfn(m_animation)); 248 | m_totalFrame = rlottie()->lottie_animation_get_totalframe_pfn(m_animation); 249 | rlottie()->mutex.unlock(); 250 | m_frameBuffer.reset(new char[m_width * m_height * 32 / 8]); 251 | // Clear previous status. 252 | m_currentFrame = 0; 253 | m_loopTimes = 0; 254 | m_shouldStop = false; 255 | Q_EMIT sourceChanged(m_source); 256 | Q_EMIT sizeChanged(size()); 257 | Q_EMIT frameRateChanged(m_frameRate); 258 | Q_EMIT durationChanged(m_duration); 259 | Q_EMIT playingChanged(true); 260 | return true; 261 | } 262 | 263 | qint64 QtLottieRLottieEngine::frameRate() const 264 | { 265 | return m_frameRate; 266 | } 267 | 268 | qint64 QtLottieRLottieEngine::duration() const 269 | { 270 | return m_duration; 271 | } 272 | 273 | QSize QtLottieRLottieEngine::size() const 274 | { 275 | return {int(m_width), int(m_height)}; 276 | } 277 | 278 | qint64 QtLottieRLottieEngine::loops() const 279 | { 280 | return m_loops; 281 | } 282 | 283 | void QtLottieRLottieEngine::setLoops(const qint64 value) 284 | { 285 | if (m_loops != value) { 286 | m_loops = value; 287 | Q_EMIT loopsChanged(m_loops); 288 | // Also clear previous status. 289 | m_loopTimes = 0; 290 | m_shouldStop = false; 291 | Q_EMIT playingChanged(true); 292 | } 293 | } 294 | 295 | bool QtLottieRLottieEngine::available() const 296 | { 297 | return rlottie()->isLoaded(); 298 | } 299 | 300 | bool QtLottieRLottieEngine::playing() const 301 | { 302 | return (m_animation && !m_shouldStop); 303 | } 304 | 305 | qreal QtLottieRLottieEngine::devicePixelRatio() const 306 | { 307 | return m_devicePixelRatio; 308 | } 309 | 310 | void QtLottieRLottieEngine::setDevicePixelRatio(const qreal value) 311 | { 312 | if (qFuzzyCompare(m_devicePixelRatio, value)) { 313 | return; 314 | } 315 | m_devicePixelRatio = value; 316 | Q_EMIT devicePixelRatioChanged(m_devicePixelRatio); 317 | } 318 | 319 | void QtLottieRLottieEngine::pause() 320 | { 321 | if (m_animation && !m_shouldStop) { 322 | m_shouldStop = true; 323 | Q_EMIT playingChanged(false); 324 | } 325 | } 326 | 327 | void QtLottieRLottieEngine::resume() 328 | { 329 | if (m_animation && m_shouldStop) { 330 | m_shouldStop = false; 331 | Q_EMIT playingChanged(true); 332 | } 333 | } 334 | 335 | void QtLottieRLottieEngine::paint(QPainter *painter, const QSize &s) 336 | { 337 | Q_ASSERT(painter); 338 | if (!painter) { 339 | return; 340 | } 341 | Q_ASSERT(s.isValid()); 342 | if (!s.isValid()) { 343 | qWarning() << s << "is not a valid size."; 344 | return; 345 | } 346 | if (!m_animation) { 347 | // lottie animation is not created, mostly due to setSource() not called. 348 | // Or the rlottie library is not loaded. Safe to ignore. 349 | return; 350 | } 351 | if (m_shouldStop) { 352 | return; 353 | } 354 | if (!m_hasFirstUpdate) { 355 | return; 356 | } 357 | QImage image(m_width, m_height, QImage::Format_ARGB32); 358 | for (int i = 0; i != image.height(); ++i) { 359 | char *p = m_frameBuffer.data() + i * image.bytesPerLine(); 360 | std::memcpy(image.scanLine(i), p, image.bytesPerLine()); 361 | } 362 | // TODO: let the user be able to set the scale mode. 363 | // "Qt::SmoothTransformation" is a must otherwise the scaled image will become fuzzy. 364 | painter->drawImage(QPoint{0, 0}, (s == size()) ? image : image.scaled(s, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); 365 | } 366 | 367 | void QtLottieRLottieEngine::render(const QSize &s) 368 | { 369 | Q_UNUSED(s); 370 | if (!m_animation) { 371 | // lottie animation is not created, mostly due to setSource() not called. 372 | // Or the rlottie library is not loaded. Safe to ignore. 373 | return; 374 | } 375 | if (!rlottie()->isLoaded()) { 376 | qWarning() << Q_FUNC_INFO << "some necessary rlottie functions are not available."; 377 | return; 378 | } 379 | if (m_shouldStop) { 380 | return; 381 | } 382 | rlottie()->mutex.lock(); 383 | rlottie()->lottie_animation_render_pfn(m_animation, m_currentFrame, reinterpret_cast(m_frameBuffer.data()), m_width, m_height, m_width * 32 / 8); 384 | rlottie()->mutex.unlock(); 385 | if (m_currentFrame >= m_totalFrame) { 386 | m_currentFrame = 0; 387 | // negative number means infinite loops. 388 | if (m_loops > 0) { 389 | ++m_loopTimes; 390 | if (m_loopTimes >= m_loops) { 391 | m_loopTimes = 0; 392 | m_shouldStop = true; 393 | Q_EMIT playingChanged(false); 394 | return; 395 | } 396 | } 397 | } else { 398 | ++m_currentFrame; 399 | } 400 | m_hasFirstUpdate = true; 401 | Q_EMIT needsRepaint(); 402 | } 403 | 404 | void QtLottieRLottieEngine::release() 405 | { 406 | // TODO: ref count 407 | delete this; 408 | } 409 | 410 | QString QtLottieRLottieEngine::name() const 411 | { 412 | return QStringLiteral("rlottie"); 413 | } 414 | 415 | QUrl QtLottieRLottieEngine::source() const 416 | { 417 | return m_source; 418 | } 419 | -------------------------------------------------------------------------------- /examples/lottiefiles/40292-clickable-rainbow.json: -------------------------------------------------------------------------------- 1 | {"v":"5.7.4","fr":29.9700012207031,"ip":0,"op":50.0000020365418,"w":1000,"h":1000,"nm":"leftright rainbow","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"violet Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.195],"y":[1.929]},"t":0,"s":[0]},{"t":50.0000020365418,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,594.076,0],"ix":2,"l":2},"a":{"a":0,"k":[225,175,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-55.229,0],[0,-55.229]],"o":[[0,-55.229],[55.228,0],[0,0]],"v":[[-100,50],[0,-50],[100,50]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.510000011968,0.250999989229,0.651000019148,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[225,175],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[1],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.934],"y":[-0.054]},"t":25,"s":[95]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[0]},{"t":101.000004113814,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.918],"y":[0]},"t":-25,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":0,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.918],"y":[0]},"t":76,"s":[5]},{"t":101.000004113814,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"blue Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.195],"y":[1.929]},"t":0,"s":[0]},{"t":50.0000020365418,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,569.076,0],"ix":2,"l":2},"a":{"a":0,"k":[275,200,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-82.843,0],[0,-82.843]],"o":[[0,-82.843],[82.842,0],[0,0]],"v":[[-150,75],[0,-75],[150,75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.156999999402,0.588000009574,0.709999952129,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[275,200],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.715],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.715],"y":[0]},"t":25,"s":[95]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[0]},{"t":101.000004113814,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.754],"y":[0.011]},"t":-25,"s":[5]},{"i":{"x":[0.594],"y":[1]},"o":{"x":[0.544],"y":[1.487]},"t":0,"s":[100]},{"i":{"x":[0.521],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.754],"y":[0.011]},"t":76,"s":[5]},{"t":101.000004113814,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"green Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.195],"y":[1.929]},"t":0,"s":[0]},{"t":50.0000020365418,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,544.076,0],"ix":2,"l":2},"a":{"a":0,"k":[325,225,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-110.457,0],[0,-110.457]],"o":[[0,-110.457],[110.457,0],[0,0]],"v":[[-200,100],[0,-100],[200,100]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.275,0.769000004787,0.40800000359,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[325,225],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.524],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.524],"y":[0]},"t":25,"s":[95]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[0]},{"t":101.000004113814,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.569],"y":[0]},"t":-25,"s":[5]},{"i":{"x":[0.536],"y":[1]},"o":{"x":[0.45],"y":[0]},"t":0,"s":[100]},{"i":{"x":[0.366],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.569],"y":[0]},"t":76,"s":[5]},{"t":101.000004113814,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"yellow Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.195],"y":[1.929]},"t":0,"s":[0]},{"t":50.0000020365418,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,519.076,0],"ix":2,"l":2},"a":{"a":0,"k":[375,250,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-138.071,0],[0,-138.071]],"o":[[0,-138.071],[138.071,0],[0,0]],"v":[[-250,125],[0,-125],[250,125]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.961000031116,0.816000007181,0.097999999102,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[375,250],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.21],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.325],"y":[-0.002]},"t":25,"s":[95]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[0]},{"t":101.000004113814,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.459],"y":[0.02]},"t":-25,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.386],"y":[3.25]},"t":0,"s":[100]},{"i":{"x":[0.202],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.459],"y":[0.02]},"t":76,"s":[5]},{"t":101.000004113814,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"red Outlines","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.195],"y":[1.929]},"t":0,"s":[0]},{"t":50.0000020365418,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,494.076,0],"ix":2,"l":2},"a":{"a":0,"k":[425,275,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-165.686,0],[0,-165.686]],"o":[[0,-165.686],[165.685,0],[0,0]],"v":[[-300,150],[0,-150],[300,150]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.987999949736,0.368999974868,0.349000010771,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[425,275],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.012],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.176],"y":[0.018]},"t":25,"s":[95]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":50,"s":[0]},{"t":101.000004113814,"s":[0]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.318],"y":[0]},"t":-25,"s":[5]},{"i":{"x":[0.304],"y":[0.169]},"o":{"x":[0.317],"y":[0]},"t":0,"s":[100]},{"i":{"x":[0.095],"y":[1.006]},"o":{"x":[0.365],"y":[0.007]},"t":50,"s":[100]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":75,"s":[5]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.318],"y":[0]},"t":76,"s":[5]},{"t":101.000004113814,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"violet Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,594.076,0],"ix":2,"l":2},"a":{"a":0,"k":[225,175,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-55.229,0],[0,-55.229]],"o":[[0,-55.229],[55.228,0],[0,0]],"v":[[-100,50],[0,-50],[100,50]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.284313738346,0.284313738346,0.284313738346,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[225,175],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"blue Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,569.076,0],"ix":2,"l":2},"a":{"a":0,"k":[275,200,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-82.843,0],[0,-82.843]],"o":[[0,-82.843],[82.842,0],[0,0]],"v":[[-150,75],[0,-75],[150,75]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.35686275363,0.354763567448,0.354763567448,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[275,200],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"green Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,544.076,0],"ix":2,"l":2},"a":{"a":0,"k":[325,225,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-110.457,0],[0,-110.457]],"o":[[0,-110.457],[110.457,0],[0,0]],"v":[[-200,100],[0,-100],[200,100]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.427450984716,0.427450984716,0.427450984716,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[325,225],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"yellow Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,519.076,0],"ix":2,"l":2},"a":{"a":0,"k":[375,250,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-138.071,0],[0,-138.071]],"o":[[0,-138.071],[138.071,0],[0,0]],"v":[[-250,125],[0,-125],[250,125]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.503921568394,0.503921568394,0.503921568394,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[375,250],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"red Outlines 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[485.165,494.076,0],"ix":2,"l":2},"a":{"a":0,"k":[425,275,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-165.686,0],[0,-165.686]],"o":[[0,-165.686],[165.685,0],[0,0]],"v":[[-300,150],[0,-150],[300,150]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.549019634724,0.549019634724,0.549019634724,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":50,"ix":5},"lc":2,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[425,275],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":50.0000020365418,"st":-25.0000010182709,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /src/qtlottiedrawengine_skottie.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (C) 2021 by wangwenx190 (Yuhang Zhao) 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | * SOFTWARE. 23 | */ 24 | 25 | #include "qtlottiedrawengine_skottie.h" 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | static constexpr const char kFileName[] = "QTLOTTIE_SKOTTIE_FILENAME"; 35 | 36 | [[nodiscard]] static inline QString getSkottieLibraryName() 37 | { 38 | #if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) 39 | return qEnvironmentVariable(kFileName, QStringLiteral("skottiewrapper")); 40 | #else 41 | const QByteArray ba = qgetenv(kFileName); 42 | return ba.isEmpty() ? QStringLiteral("skottiewrapper") : QString::fromUtf8(ba); 43 | #endif 44 | } 45 | 46 | using skottie_animation_from_file_ptr = Skottie_Animation*(*)(const char *path, const char *resource); 47 | using skottie_animation_from_data_ptr = Skottie_Animation*(*)(void *data, size_t data_size, const char *resource); 48 | using skottie_animation_get_size_ptr = void(*)(const Skottie_Animation *animation, size_t *width, size_t *height); 49 | using skottie_animation_get_duration_ptr = double(*)(const Skottie_Animation *animation); 50 | using skottie_animation_get_totalframe_ptr = size_t(*)(const Skottie_Animation *animation); 51 | using skottie_animation_get_framerate_ptr = double(*)(const Skottie_Animation *animation); 52 | using skottie_new_pixmap_ptr = Skottie_Pixmap*(*)(); 53 | using skottie_new_pixmap_wh_ptr = Skottie_Pixmap*(*)(size_t width, size_t height, void *buffer); 54 | using skottie_get_pixmap_buffer_ptr = const void*(*)(Skottie_Pixmap *pixmap); 55 | using skottie_delete_pixmap_ptr = void(*)(Skottie_Pixmap *pixmap); 56 | using skottie_animation_render_ptr = void(*)(Skottie_Animation *animation, size_t frame_num, Skottie_Pixmap *pixmap); 57 | using skottie_animation_render_scale_ptr = void(*)(Skottie_Animation *animation, size_t frame_num, Skottie_Pixmap *pixmap); 58 | using skottie_animation_destroy_ptr = void(*)(Skottie_Animation *animation); 59 | 60 | class skottie_data 61 | { 62 | Q_DISABLE_COPY_MOVE(skottie_data) 63 | 64 | public: 65 | mutable QMutex mutex; 66 | 67 | skottie_animation_from_file_ptr skottie_animation_from_file_pfn = nullptr; 68 | skottie_animation_from_data_ptr skottie_animation_from_data_pfn = nullptr; 69 | skottie_animation_get_size_ptr skottie_animation_get_size_pfn = nullptr; 70 | skottie_animation_get_duration_ptr skottie_animation_get_duration_pfn = nullptr; 71 | skottie_animation_get_totalframe_ptr skottie_animation_get_totalframe_pfn = nullptr; 72 | skottie_animation_get_framerate_ptr skottie_animation_get_framerate_pfn = nullptr; 73 | skottie_new_pixmap_ptr skottie_new_pixmap_pfn = nullptr; 74 | skottie_new_pixmap_wh_ptr skottie_new_pixmap_wh_pfn = nullptr; 75 | skottie_get_pixmap_buffer_ptr skottie_get_pixmap_buffer_pfn = nullptr; 76 | skottie_delete_pixmap_ptr skottie_delete_pixmap_pfn = nullptr; 77 | skottie_animation_render_ptr skottie_animation_render_pfn = nullptr; 78 | skottie_animation_render_scale_ptr skottie_animation_render_scale_pfn = nullptr; 79 | skottie_animation_destroy_ptr skottie_animation_destroy_pfn = nullptr; 80 | 81 | explicit skottie_data() 82 | { 83 | const bool result = load(); 84 | Q_UNUSED(result); 85 | } 86 | 87 | ~skottie_data() 88 | { 89 | const bool result = unload(); 90 | Q_UNUSED(result); 91 | } 92 | 93 | [[nodiscard]] bool load(const QString &libName = {}) 94 | { 95 | if (isLoaded()) { 96 | qDebug() << "The skottie library has already been loaded."; 97 | return true; 98 | } 99 | 100 | const QMutexLocker locker(&mutex); 101 | 102 | library.setFileName(libName.isEmpty() ? getSkottieLibraryName() : libName); 103 | if (!library.load()) { 104 | qWarning() << "Failed to load skottie library:" << library.errorString(); 105 | return false; 106 | } 107 | qDebug() << "skottie library loaded successfully from" << library.fileName(); 108 | 109 | #define RESOLVE(API) \ 110 | API##_pfn = reinterpret_cast(library.resolve(#API)); \ 111 | if (!API##_pfn) { \ 112 | qWarning() << "Failed to resolve " #API; \ 113 | return false; \ 114 | } 115 | 116 | RESOLVE(skottie_animation_from_file) 117 | RESOLVE(skottie_animation_from_data) 118 | RESOLVE(skottie_animation_get_size) 119 | RESOLVE(skottie_animation_get_duration) 120 | RESOLVE(skottie_animation_get_totalframe) 121 | RESOLVE(skottie_animation_get_framerate) 122 | RESOLVE(skottie_new_pixmap) 123 | RESOLVE(skottie_new_pixmap_wh) 124 | RESOLVE(skottie_get_pixmap_buffer) 125 | RESOLVE(skottie_delete_pixmap) 126 | RESOLVE(skottie_animation_render) 127 | RESOLVE(skottie_animation_render_scale) 128 | RESOLVE(skottie_animation_destroy) 129 | 130 | #undef RESOLVE 131 | 132 | return true; 133 | } 134 | 135 | [[nodiscard]] bool unload() 136 | { 137 | if (!isLoaded()) { 138 | qDebug() << "The skottie library has already been unloaded."; 139 | return true; 140 | } 141 | 142 | const QMutexLocker locker(&mutex); 143 | 144 | skottie_animation_from_file_pfn = nullptr; 145 | skottie_animation_from_data_pfn = nullptr; 146 | skottie_animation_get_size_pfn = nullptr; 147 | skottie_animation_get_duration_pfn = nullptr; 148 | skottie_animation_get_totalframe_pfn = nullptr; 149 | skottie_animation_get_framerate_pfn = nullptr; 150 | skottie_new_pixmap_pfn = nullptr; 151 | skottie_new_pixmap_wh_pfn = nullptr; 152 | skottie_get_pixmap_buffer_pfn = nullptr; 153 | skottie_delete_pixmap_pfn = nullptr; 154 | skottie_animation_render_pfn = nullptr; 155 | skottie_animation_render_scale_pfn = nullptr; 156 | skottie_animation_destroy_pfn = nullptr; 157 | 158 | if (!library.unload()) { 159 | qWarning() << "Failed to unload skottie library:" << library.errorString(); 160 | return false; 161 | } 162 | 163 | return true; 164 | } 165 | 166 | [[nodiscard]] bool isLoaded() const 167 | { 168 | const QMutexLocker locker(&mutex); 169 | 170 | return skottie_animation_from_file_pfn 171 | && skottie_animation_from_data_pfn && skottie_animation_get_size_pfn 172 | && skottie_animation_get_duration_pfn && skottie_animation_get_totalframe_pfn 173 | && skottie_animation_get_framerate_pfn && skottie_new_pixmap_pfn 174 | && skottie_new_pixmap_wh_pfn && skottie_get_pixmap_buffer_pfn 175 | && skottie_delete_pixmap_pfn && skottie_animation_render_pfn 176 | && skottie_animation_render_scale_pfn && skottie_animation_destroy_pfn; 177 | } 178 | 179 | private: 180 | QLibrary library; 181 | }; 182 | 183 | Q_GLOBAL_STATIC(skottie_data, skottie) 184 | 185 | QtLottieSkottieEngine::QtLottieSkottieEngine(QObject *parent) : QtLottieDrawEngine(parent) 186 | { 187 | if (skottie()->isLoaded()) { 188 | if (const auto screen = QGuiApplication::primaryScreen()) { 189 | m_devicePixelRatio = screen->devicePixelRatio(); 190 | } else { 191 | m_devicePixelRatio = 1.0; 192 | } 193 | } else { 194 | qWarning() << "The skottie backend is not available due to can't load skottie library."; 195 | } 196 | } 197 | 198 | QtLottieSkottieEngine::~QtLottieSkottieEngine() 199 | { 200 | if (!skottie()->isLoaded()) { 201 | return; 202 | } 203 | if (m_animation) { 204 | skottie()->skottie_animation_destroy_pfn(m_animation); 205 | } 206 | } 207 | 208 | void QtLottieSkottieEngine::paint(QPainter *painter, const QSize &s) 209 | { 210 | Q_ASSERT(painter); 211 | if (!painter) { 212 | return; 213 | } 214 | Q_ASSERT(s.isValid()); 215 | if (!s.isValid()) { 216 | qWarning() << s << "is not a valid size."; 217 | return; 218 | } 219 | if (!m_animation) { 220 | // lottie animation is not created, mostly due to setSource() not called. 221 | // Or the skottie library is not loaded. Safe to ignore. 222 | return; 223 | } 224 | if (!skottie()->isLoaded()) { 225 | qWarning() << Q_FUNC_INFO << "some necessary skottie functions are not available."; 226 | return; 227 | } 228 | if (m_shouldStop) { 229 | return; 230 | } 231 | if (!m_hasFirstUpdate) { 232 | return; 233 | } 234 | const int width = s.width(); 235 | const int height = s.height(); 236 | QScopedArrayPointer buffer(new char[width * height * 4]); 237 | Skottie_Pixmap *pixmap = nullptr; 238 | skottie()->mutex.lock(); 239 | if (s == size()) { 240 | pixmap = skottie()->skottie_new_pixmap_pfn(); 241 | skottie()->skottie_animation_render_pfn(m_animation, m_currentFrame, pixmap); 242 | } else { 243 | pixmap = skottie()->skottie_new_pixmap_wh_pfn(width, height, buffer.data()); 244 | skottie()->skottie_animation_render_scale_pfn(m_animation, m_currentFrame, pixmap); 245 | } 246 | const void *addr = skottie()->skottie_get_pixmap_buffer_pfn(pixmap); 247 | skottie()->mutex.unlock(); 248 | QImage image(width, height, QImage::Format_ARGB32); 249 | for (int i = 0; i != height; ++i) { 250 | const char *p = static_cast(addr) + i * image.bytesPerLine(); 251 | std::memcpy(image.scanLine(i), p, image.bytesPerLine()); 252 | } 253 | skottie()->mutex.lock(); 254 | skottie()->skottie_delete_pixmap_pfn(pixmap); 255 | skottie()->mutex.unlock(); 256 | painter->drawImage(QPoint{0, 0}, image); 257 | } 258 | 259 | void QtLottieSkottieEngine::render(const QSize &s) 260 | { 261 | Q_UNUSED(s); 262 | if (!m_animation) { 263 | // lottie animation is not created, mostly due to setSource() not called. 264 | // Or the skottie library is not loaded. Safe to ignore. 265 | return; 266 | } 267 | if (m_shouldStop) { 268 | return; 269 | } 270 | if (m_currentFrame >= m_totalFrame) { 271 | m_currentFrame = 0; 272 | // negative number means infinite loops. 273 | if (m_loops > 0) { 274 | ++m_loopTimes; 275 | if (m_loopTimes >= m_loops) { 276 | m_loopTimes = 0; 277 | m_shouldStop = true; 278 | Q_EMIT playingChanged(false); 279 | return; 280 | } 281 | } 282 | } else { 283 | ++m_currentFrame; 284 | } 285 | m_hasFirstUpdate = true; 286 | Q_EMIT needsRepaint(); 287 | } 288 | 289 | void QtLottieSkottieEngine::release() 290 | { 291 | // TODO: ref count 292 | delete this; 293 | } 294 | 295 | QString QtLottieSkottieEngine::name() const 296 | { 297 | return QStringLiteral("skottie"); 298 | } 299 | 300 | QUrl QtLottieSkottieEngine::source() const 301 | { 302 | return m_source; 303 | } 304 | 305 | bool QtLottieSkottieEngine::setSource(const QUrl &value) 306 | { 307 | if (!skottie()->isLoaded()) { 308 | qWarning() << Q_FUNC_INFO << "some necessary skottie functions are not available."; 309 | return false; 310 | } 311 | Q_ASSERT(value.isValid()); 312 | if (!value.isValid()) { 313 | qWarning() << value << "is not a valid URL."; 314 | return false; 315 | } 316 | if (m_source == value) { 317 | // debug output? 318 | return false; // or true? 319 | } 320 | QString jsonFilePath = {}; 321 | if (value.scheme() == QStringLiteral("qrc")) { 322 | jsonFilePath = value.toString(); 323 | // QFile can't recognize url. 324 | jsonFilePath.replace(QStringLiteral("qrc:"), QStringLiteral(":"), Qt::CaseInsensitive); 325 | jsonFilePath.replace(QStringLiteral(":///"), QStringLiteral(":/")); 326 | } else { 327 | jsonFilePath = value.isLocalFile() ? value.toLocalFile() : value.url(); 328 | } 329 | Q_ASSERT(QFile::exists(jsonFilePath)); 330 | if (!QFile::exists(jsonFilePath)) { 331 | qWarning() << jsonFilePath << "doesn't exist."; 332 | return false; 333 | } 334 | QFile file(jsonFilePath); 335 | if (!file.open(QFile::ReadOnly | QFile::Text)) { 336 | qWarning() << "Failed to open the JSON file:" << jsonFilePath; 337 | return false; 338 | } 339 | const QByteArray jsonBuffer = file.readAll(); 340 | file.close(); 341 | if (jsonBuffer.isEmpty()) { 342 | qWarning() << "File is empty:" << jsonFilePath; 343 | return false; 344 | } 345 | // TODO: support embeded resources. 346 | const QString resDirPath = QCoreApplication::applicationDirPath(); 347 | skottie()->mutex.lock(); 348 | m_animation = skottie()->skottie_animation_from_data_pfn(const_cast(jsonBuffer.data()), jsonBuffer.length(), resDirPath.toUtf8().constData()); 349 | skottie()->mutex.unlock(); 350 | if (!m_animation) { 351 | qWarning() << "Failed to create lottie animation."; 352 | return false; 353 | } 354 | m_source = value; 355 | skottie()->mutex.lock(); 356 | skottie()->skottie_animation_get_size_pfn(m_animation, reinterpret_cast(&m_width), reinterpret_cast(&m_height)); 357 | m_frameRate = qRound64(skottie()->skottie_animation_get_framerate_pfn(m_animation)); 358 | m_duration = qRound64(skottie()->skottie_animation_get_duration_pfn(m_animation)); 359 | m_totalFrame = skottie()->skottie_animation_get_totalframe_pfn(m_animation); 360 | skottie()->mutex.unlock(); 361 | // Clear previous status. 362 | m_currentFrame = 0; 363 | m_loopTimes = 0; 364 | m_shouldStop = false; 365 | Q_EMIT sourceChanged(m_source); 366 | Q_EMIT sizeChanged(size()); 367 | Q_EMIT frameRateChanged(m_frameRate); 368 | Q_EMIT durationChanged(m_duration); 369 | Q_EMIT playingChanged(true); 370 | return true; 371 | } 372 | 373 | qint64 QtLottieSkottieEngine::frameRate() const 374 | { 375 | return m_frameRate; 376 | } 377 | 378 | qint64 QtLottieSkottieEngine::duration() const 379 | { 380 | return m_duration; 381 | } 382 | 383 | QSize QtLottieSkottieEngine::size() const 384 | { 385 | return {int(m_width), int(m_height)}; 386 | } 387 | 388 | qint64 QtLottieSkottieEngine::loops() const 389 | { 390 | return m_loops; 391 | } 392 | 393 | void QtLottieSkottieEngine::setLoops(const qint64 value) 394 | { 395 | if (m_loops != value) { 396 | m_loops = value; 397 | Q_EMIT loopsChanged(m_loops); 398 | // Also clear previous status. 399 | m_loopTimes = 0; 400 | m_shouldStop = false; 401 | Q_EMIT playingChanged(true); 402 | } 403 | } 404 | 405 | bool QtLottieSkottieEngine::available() const 406 | { 407 | return skottie()->isLoaded(); 408 | } 409 | 410 | bool QtLottieSkottieEngine::playing() const 411 | { 412 | return (m_animation && !m_shouldStop); 413 | } 414 | 415 | qreal QtLottieSkottieEngine::devicePixelRatio() const 416 | { 417 | return m_devicePixelRatio; 418 | } 419 | 420 | void QtLottieSkottieEngine::setDevicePixelRatio(const qreal value) 421 | { 422 | if (qFuzzyCompare(m_devicePixelRatio, value)) { 423 | return; 424 | } 425 | m_devicePixelRatio = value; 426 | Q_EMIT devicePixelRatioChanged(m_devicePixelRatio); 427 | } 428 | 429 | void QtLottieSkottieEngine::pause() 430 | { 431 | if (m_animation && !m_shouldStop) { 432 | m_shouldStop = true; 433 | Q_EMIT playingChanged(false); 434 | } 435 | } 436 | 437 | void QtLottieSkottieEngine::resume() 438 | { 439 | if (m_animation && m_shouldStop) { 440 | m_shouldStop = false; 441 | Q_EMIT playingChanged(true); 442 | } 443 | } 444 | -------------------------------------------------------------------------------- /examples/lottiefiles/50486-rocket.json: -------------------------------------------------------------------------------- 1 | {"v":"5.7.4","fr":60,"ip":0,"op":180,"w":150,"h":150,"nm":"전체","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"rocket Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.7,"y":0.709},"o":{"x":0.7,"y":0.679},"t":15,"s":[75,206,0],"to":[0,-22.5,0],"ti":[0,22.5,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.3,"y":0.3},"t":45,"s":[75,71,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":135,"s":[75,71,0],"to":[0,-21,0],"ti":[0,21,0]},{"t":165,"s":[75,-55,0]}],"ix":2,"l":2},"a":{"a":0,"k":[49.5,56,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.12,-71.94],[8.23,0],[0,0],[0,0]],"o":[[-0.229,7.85],[0,0],[0,0],[8.771,0]],"v":[[16.941,42.5],[8.941,55.5],[-17.059,55.5],[-17.059,-55.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":5,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[66.278,55.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.568,0.688],[0,0],[-1.246,-1.17],[0,0]],"o":[[0,0],[0.68,1.568],[0,0],[-1.17,-1.251]],"v":[[6.14,-10.295],[-10.29,6.145],[-7.37,10.295],[10.29,-7.355]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[48.53,60.545],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":4,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.899,0.011],[0,-6.903],[-6.904,0],[0,6.903]],"o":[[-6.904,0],[0,6.903],[6.904,0],[-0.011,-6.899]],"v":[[0,-12.5],[-12.5,0],[0,12.5],[12.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[8.003,-0.011],[0,8.008],[-8.008,0],[0,-8.008]],"o":[[-8.008,0],[0,-8.008],[8.008,0],[-0.011,8.004]],"v":[[0,14.5],[-14.5,0],[0,-14.5],[14.5,0]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.72,61.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":6,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-6.904,0],[0,-6.903],[6.904,0],[0,6.903]],"o":[[6.904,0],[0,6.903],[-6.904,0],[0,-6.903]],"v":[[0,-12.5],[12.5,0],[0,12.5],[-12.5,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.532999973671,0.552999997606,0.592000026329,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.72,61.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":4,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,-9.665],[9.665,0],[0,9.665],[-9.66,0.005]],"o":[[9.665,0],[0,9.665],[-9.665,0],[-0.006,-9.66],[0,0]],"v":[[0.003,-17.5],[17.503,0],[0.003,17.5],[-17.497,0],[-0.017,-17.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.122000002394,0.368999974868,0.933000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.717,61.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":4,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.656,0],[0,-1.657],[1.657,0],[0,1.657]],"o":[[1.657,0],[0,1.657],[-1.656,0],[0,-1.657]],"v":[[0,-3],[3,0],[0,3],[-3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[73.22,102.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":4,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.657,0],[0,-1.657],[1.657,0],[0,1.657]],"o":[[1.657,0],[0,1.657],[-1.657,0],[0,-1.657]],"v":[[0,-3],[3,0],[0,3],[-3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.22,102.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":4,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.657,0],[0,-1.657],[1.657,0],[0,1.657]],"o":[[1.657,0],[0,1.657],[-1.657,0],[0,-1.657]],"v":[[0,-3],[3,0],[0,3],[-3,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.22,102.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":4,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-34,-1.5],[34,-1.5],[34,1.5],[-34,1.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.728999956916,0.952999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.32,94.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":4,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.22,0],[7.44,-14.37],[-11.127,10.739],[-0.258,0.269]],"o":[[-4.23,0],[10.739,11.127],[0.267,-0.259],[-7.46,-14.3]],"v":[[-0.04,-15.941],[-20.19,4.499],[19.402,5.202],[20.19,4.41]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.490000017952,0.728999956916,0.952999997606,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.26,16.191],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":4,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[8.23,0],[0,0],[0.23,7.85],[0,0]],"o":[[0,0],[-0.229,7.85],[0,0],[-8.18,0],[0,0],[0,0]],"v":[[33.91,-7.5],[33.91,-5.5],[25.91,7.5],[-25.96,7.5],[-33.91,-5.5],[-33.91,-7.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.847000002394,0.885999971278,0.941000007181,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.35,103.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":4,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.12,-71.94],[8.23,0],[0,0],[0.23,7.85],[-8.71,0]],"o":[[-0.229,7.85],[0,0],[-8.18,0],[-2.11,-71.94],[8.71,0]],"v":[[33.885,42.5],[25.885,55.5],[-25.945,55.5],[-33.895,42.5],[-0.115,-55.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[49.335,55.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":4,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-9.785,4.2],[-9.785,19.8],[9.785,9],[9.785,-19.8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.122000002394,0.368999974868,0.933000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[10.035,89.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":2,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-9.79,9],[9.79,19.8],[9.79,4.199],[-9.79,-19.8]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.122000002394,0.368999974868,0.933000033509,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[88.41,89.75],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"bm":0,"ix":14,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"spinning_star","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[29,75.5,0],"ix":2,"l":2},"a":{"a":0,"k":[9,9,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":18,"h":18,"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"spinning_star","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":61,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[120.5,34,0],"ix":2,"l":2},"a":{"a":0,"k":[9,9,0],"ix":1,"l":2},"s":{"a":0,"k":[55.556,55.556,100],"ix":6,"l":2}},"ao":0,"w":18,"h":18,"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"spinning_star","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[123.5,96.5,0],"ix":2,"l":2},"a":{"a":0,"k":[9,9,0],"ix":1,"l":2},"s":{"a":0,"k":[79,79,100],"ix":6,"l":2}},"ao":0,"w":18,"h":18,"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"jet_exhaust","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[75,225,0],"to":[0,-25,0],"ti":[0,25,0]},{"t":45,"s":[75,75,0]}],"ix":2,"l":2},"a":{"a":0,"k":[75,75,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"w":150,"h":150,"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[150,150],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"fl","c":{"a":0,"k":[0.596078431373,0.823529411765,0.98431372549,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":300,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"star Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[360]}],"ix":10},"p":{"a":0,"k":[9,9,0],"ix":2,"l":2},"a":{"a":0,"k":[9,9,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0]],"v":[[8.37,-3.03],[4.09,1.4],[6.26,7.23],[0.72,4.46],[-4.09,8.3],[-3.23,2.16],[-8.37,-1.31],[-2.3,-2.33],[-0.67,-8.3],[2.22,-2.79]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.894000004787,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[8.62,8.55],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":181,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,136.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[40.635,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[74.998,75.007],[-75.002,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[66.188,75.007],[-66.192,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[74.998,75.007],[-75.002,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":45,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[66.188,75.007],[-66.192,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[74.998,75.007],[-75.002,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[66.188,75.007],[-66.192,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[74.998,75.007],[-75.002,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[66.188,75.007],[-66.192,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[74.998,75.007],[-75.002,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":135,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[51.509,-74.866],[66.188,75.007],[-66.192,74.993],[-53.855,-74.73]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":165,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[50.542,-589.216],[50.205,120.493],[-55.747,120.48],[-54.823,-589.08]],"c":true}]},{"t":175,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-1.142,-589.24],[-1.479,120.469],[-4.063,120.41],[-3.139,-589.15]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.988235353956,0.835294177485,0.423529441684,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[52.377,28.58],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,136.5,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[76.001,100,100],"ix":6,"l":2}},"ao":0,"ef":[{"ty":5,"nm":"Transform","np":14,"mn":"ADBE Geometry2","ix":1,"en":1,"ef":[{"ty":3,"nm":"Anchor Point","mn":"ADBE Geometry2-0001","ix":1,"v":{"a":0,"k":[75,75],"ix":1}},{"ty":3,"nm":"Position","mn":"ADBE Geometry2-0002","ix":2,"v":{"a":0,"k":[75,75],"ix":2}},{"ty":7,"nm":"Uniform Scale","mn":"ADBE Geometry2-0011","ix":3,"v":{"a":0,"k":1,"ix":3}},{"ty":0,"nm":"Scale","mn":"ADBE Geometry2-0003","ix":4,"v":{"a":0,"k":100,"ix":4}},{"ty":0,"nm":" ","mn":"ADBE Geometry2-0004","ix":5,"v":{"a":0,"k":100,"ix":5}},{"ty":0,"nm":"Skew","mn":"ADBE Geometry2-0005","ix":6,"v":{"a":0,"k":0,"ix":6}},{"ty":0,"nm":"Skew Axis","mn":"ADBE Geometry2-0006","ix":7,"v":{"a":0,"k":0,"ix":7}},{"ty":0,"nm":"Rotation","mn":"ADBE Geometry2-0007","ix":8,"v":{"a":0,"k":0,"ix":8}},{"ty":0,"nm":"Opacity","mn":"ADBE Geometry2-0008","ix":9,"v":{"a":0,"k":100,"ix":9}},{"ty":7,"nm":"Use Composition’s Shutter Angle","mn":"ADBE Geometry2-0009","ix":10,"v":{"a":0,"k":1,"ix":10}},{"ty":0,"nm":"Shutter Angle","mn":"ADBE Geometry2-0010","ix":11,"v":{"a":0,"k":0,"ix":11}},{"ty":7,"nm":"Sampling","mn":"ADBE Geometry2-0012","ix":12,"v":{"a":0,"k":1,"ix":12}}]}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[75,75],[-75,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":15,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[70.326,75],[-70.326,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":30,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[75,75],[-75,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":45,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[70.326,75],[-70.326,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":60,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[75,75],[-75,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":75,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[70.326,75],[-70.326,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":90,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[75,75],[-75,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":105,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[70.326,75],[-70.326,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":120,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[75,75],[-75,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":135,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[49.448,-75],[70.326,75],[-70.326,75],[-52.564,-75]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":165,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[48.92,-588.018],[49.268,94.195],[-53.055,94.195],[-53.092,-588.018]],"c":true}]},{"t":175,"s":[{"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[-0.938,-587.337],[-0.59,94.876],[-1.951,94.876],[-1.988,-587.337]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.996078491211,0.603921568627,0.219607858097,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[52.781,28.654],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":180,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Comp 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[75,75,0],"ix":2,"l":2},"a":{"a":0,"k":[75,75,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"a","pt":{"a":0,"k":{"i":[[41.421,0],[0,-41.421],[-41.421,0],[0,41.421]],"o":[[-41.421,0],[0,41.421],[41.421,0],[0,-41.421]],"v":[[75,0],[0,75],[75,150],[150,75]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"w":150,"h":150,"ip":0,"op":300,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /examples/lottiefiles/50807-pacman-loading.json: -------------------------------------------------------------------------------- 1 | {"v":"5.7.6","fr":30,"ip":7,"op":91,"w":512,"h":512,"nm":"Pacman Loading","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Head1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[120]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[150]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[180]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[210]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[240]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[270]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[300]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[330]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[360]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[390]},{"t":91,"s":[420]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[256,255.938,0],"to":[0,-0.019,0],"ti":[0,0.039,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":7,"s":[255.75,255.598,0],"to":[0,-0.022,0],"ti":[-0.011,0.014,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":14,"s":[255.768,255.296,0],"to":[0.015,-0.019,0],"ti":[-0.027,-0.017,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":21,"s":[255.709,255.299,0],"to":[0.022,0.014,0],"ti":[-0.039,-0.023,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":28,"s":[255.806,255.108,0],"to":[0.089,0.052,0],"ti":[0,0.027,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":42,"s":[256,254.938,0],"to":[0,-0.083,0],"ti":[0,-0.021,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":49,"s":[256.375,255.438,0],"to":[0,0.021,0],"ti":[0.021,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63,"s":[256.25,255.812,0],"to":[-0.021,0,0],"ti":[0,-0.021,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[256.25,256.062,0],"to":[0,0.021,0],"ti":[0,0.039,0]},{"t":91,"s":[255.75,255.598,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":0,"k":[78.74,78.74,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.278431385756,0.278431385756,0.278431385756,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"t":7,"s":[90]}],"ix":6,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":50,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Pfade trimmen 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Head2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[30]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[60]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[120]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[150]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[180]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[210]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[240]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[270]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[300]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[330]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[360]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":84,"s":[390]},{"t":91,"s":[420]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[256,255.188,0],"to":[0,0.019,0],"ti":[0,-0.039,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":7,"s":[256.25,255.027,0],"to":[0,0.032,0],"ti":[0.022,-0.061,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":14,"s":[256.463,255.171,0],"to":[-0.017,0.045,0],"ti":[0.044,-0.051,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":21,"s":[256.492,255.318,0],"to":[-0.039,0.046,0],"ti":[0.06,-0.044,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":28,"s":[256.338,255.828,0],"to":[-0.155,0.112,0],"ti":[0,-0.027,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":42,"s":[256,256.188,0],"to":[0,0.083,0],"ti":[0,0.021,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":49,"s":[255.625,255.688,0],"to":[0,-0.021,0],"ti":[-0.021,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":63,"s":[255.75,255.312,0],"to":[0.021,0,0],"ti":[0,0.021,0]},{"t":70,"s":[255.75,255.062,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":0,"k":[78.74,78.74,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.278431385756,0.278431385756,0.278431385756,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-90]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[0]},{"t":7,"s":[-90]}],"ix":6,"x":"var $bm_rt;\n$bm_rt = loopOut('cycle');"},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":50,"ix":1},"e":{"a":0,"k":100,"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":2,"nm":"Pfade trimmen 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Circle 0","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":4,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":76,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":77,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":87,"s":[0]},{"t":88,"s":[100]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[0,0,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":7,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":87,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":88,"s":[0,0,100]},{"t":91,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":"Circle 1","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":10,"s":[0]},{"t":11,"s":[100]}],"ix":11},"r":{"a":0,"k":30,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":11,"s":[0,0,100]},{"t":14,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"Circle 2","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":6,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":7,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":17,"s":[0]},{"t":18,"s":[100]}],"ix":11},"r":{"a":0,"k":60,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":17,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":18,"s":[0,0,100]},{"t":21,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":"Circle 3","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":13,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":14,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":24,"s":[0]},{"t":25,"s":[100]}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":24,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":25,"s":[0,0,100]},{"t":28,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Circle 4","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":20,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":21,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":31,"s":[0]},{"t":32,"s":[100]}],"ix":11},"r":{"a":0,"k":120,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":31,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":32,"s":[0,0,100]},{"t":35,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Circle 5","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":27,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":28,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":38,"s":[0]},{"t":39,"s":[100]}],"ix":11},"r":{"a":0,"k":150,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":38,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":39,"s":[0,0,100]},{"t":42,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"Circle 6","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":34,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":35,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":45,"s":[0]},{"t":46,"s":[100]}],"ix":11},"r":{"a":0,"k":180,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":45,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":46,"s":[0,0,100]},{"t":49,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"Circle 7","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":41,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":42,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":52,"s":[0]},{"t":53,"s":[100]}],"ix":11},"r":{"a":0,"k":210,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":52,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":53,"s":[0,0,100]},{"t":56,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"Circle 8","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":48,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":49,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":59,"s":[0]},{"t":60,"s":[100]}],"ix":11},"r":{"a":0,"k":240,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":59,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":60,"s":[0,0,100]},{"t":63,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"Circle 9","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":55,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":56,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":66,"s":[0]},{"t":67,"s":[100]}],"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":66,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":67,"s":[0,0,100]},{"t":70,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":"Circle 10","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":62,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":63,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":73,"s":[0]},{"t":74,"s":[100]}],"ix":11},"r":{"a":0,"k":300,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":73,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":74,"s":[0,0,100]},{"t":77,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"Circle 11","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":69,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":70,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":80,"s":[0]},{"t":81,"s":[100]}],"ix":11},"r":{"a":0,"k":330,"ix":10},"p":{"a":0,"k":[256,255.938,0],"ix":2,"l":2},"a":{"a":0,"k":[-13.97,124.381,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":80,"s":[78.74,78.74,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":81,"s":[0,0,100]},{"t":84,"s":[78.74,78.74,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[72,72],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Elliptischer Pfad 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[0.654901960784,0.654901960784,0.654901960784,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fläche 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-15,-153],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transformieren"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":120,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /examples/lottiefiles/41446-teh-tarik.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.7","meta":{"g":"LottieFiles AE 0.1.21","a":"","k":"","d":"","tc":""},"fr":24,"ip":0,"op":101,"w":1600,"h":1200,"nm":"Pre-comp 3","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"Pre-comp 2","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,960,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":101,"op":202,"st":101,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"mug loop","refId":"comp_1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,960,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":0,"op":101,"st":0,"bm":0}]},{"id":"comp_1","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,960,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[784,1192,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":42,"op":53,"st":42,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[848,1312,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":37,"op":48,"st":37,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1032,1219,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":34,"op":45,"st":34,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[808,1192,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":31,"op":42,"st":31,"bm":0},{"ddd":0,"ind":6,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[960,1128,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":26,"op":37,"st":26,"bm":0},{"ddd":0,"ind":7,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[848,1108,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":21,"op":32,"st":21,"bm":0},{"ddd":0,"ind":8,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1024,1024,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":19,"op":30,"st":19,"bm":0},{"ddd":0,"ind":9,"ty":0,"nm":"Shape Layer 3 Comp 1","refId":"comp_2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[916,996,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":16,"op":27,"st":16,"bm":0},{"ddd":0,"ind":10,"ty":3,"nm":"Null 12","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.408],"y":[1]},"o":{"x":[0.553],"y":[0]},"t":0,"s":[-90]},{"i":{"x":[0.552],"y":[1]},"o":{"x":[0.446],"y":[0]},"t":21,"s":[90]},{"i":{"x":[0.483],"y":[1]},"o":{"x":[0.589],"y":[0]},"t":50,"s":[90]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.465],"y":[0]},"t":70,"s":[-90]},{"t":100,"s":[-90]}],"ix":10},"p":{"a":0,"k":[960,960,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":101,"st":1,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"cup 3","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-50.007,-226.994,0],"ix":2},"a":{"a":0,"k":[-50,-227,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.334,0.334],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[301,0]},{"i":{"x":[0.575,0.575],"y":[1,0.529]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[301,203]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.221]},"t":50,"s":[301,108.054]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":70,"s":[301,0]},{"t":100,"s":[301,0]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.546,"y":1},"o":{"x":0.652,"y":0},"t":0,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"i":{"x":0.575,"y":0.529},"o":{"x":0.185,"y":0},"t":20,"s":[-50,-147],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.341,"y":0.351},"t":50,"s":[-50,-162.717],"to":[0,0],"ti":[0,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.652,"y":0.652},"t":70,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"t":100,"s":[-50,-174]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":0,"k":30,"ix":2},"o":{"a":0,"k":104,"ix":3},"m":1,"ix":2,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":13,"ty":0,"nm":"pour","parent":16,"refId":"comp_3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":4,"ix":10},"p":{"a":0,"k":[-34.621,-547.286,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":14,"op":54,"st":0,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":"cup 2","parent":16,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-50.007,-226.994,0],"ix":2},"a":{"a":0,"k":[-50,-227,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.334,0.334],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[301,0]},{"i":{"x":[0.575,0.575],"y":[1,0.529]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[301,203]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.221]},"t":50,"s":[301,108.054]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":70,"s":[301,0]},{"t":100,"s":[301,0]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274988511,0.776471007104,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.546,"y":1},"o":{"x":0.652,"y":0},"t":0,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"i":{"x":0.575,"y":0.529},"o":{"x":0.185,"y":0},"t":20,"s":[-50,-147],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.341,"y":0.351},"t":50,"s":[-50,-162.717],"to":[0,0],"ti":[0,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.652,"y":0.652},"t":70,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"t":100,"s":[-50,-174]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":"liquid","parent":16,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.097],"y":[0.345]},"o":{"x":[0.225],"y":[0]},"t":0,"s":[0]},{"i":{"x":[0.571],"y":[1]},"o":{"x":[0.247],"y":[0.121]},"t":10,"s":[-27.066]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":20,"s":[-67]},{"t":48,"s":[-129]}],"ix":10},"p":{"a":0,"k":[102.612,-157.363,0],"ix":2},"a":{"a":0,"k":[102.619,-157.369,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.334,0.334],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[301,0]},{"i":{"x":[0.575,0.575],"y":[1,0.529]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[301,203]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.221]},"t":50,"s":[301,108.054]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":70,"s":[301,0]},{"t":100,"s":[301,0]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274988511,0.776471007104,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.658823529412,0.258823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.546,"y":1},"o":{"x":0.652,"y":0},"t":0,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"i":{"x":0.575,"y":0.529},"o":{"x":0.185,"y":0},"t":20,"s":[-50,-147],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.341,"y":0.351},"t":50,"s":[-50,-162.717],"to":[0,0],"ti":[0,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.652,"y":0.652},"t":70,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"t":100,"s":[-50,-174]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":"cup","parent":10,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.394],"y":[1]},"o":{"x":[0.546],"y":[0]},"t":0,"s":[86]},{"i":{"x":[0.485],"y":[1]},"o":{"x":[0.475],"y":[0]},"t":20,"s":[0]},{"i":{"x":[0.394],"y":[1]},"o":{"x":[0.546],"y":[0]},"t":50,"s":[46]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.475],"y":[0]},"t":70,"s":[105]},{"t":100,"s":[86]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.061,"y":1},"o":{"x":0.209,"y":0.358},"t":0,"s":[-320.578,7,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.475,"y":1},"o":{"x":0.485,"y":0},"t":17,"s":[-133,7,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.061,"y":1},"o":{"x":0.561,"y":0},"t":45,"s":[-424,7,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":1},"o":{"x":0.485,"y":0},"t":67,"s":[-61,7,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.811,"y":0.394},"o":{"x":0.519,"y":0},"t":95,"s":[-350,7,0],"to":[0,0,0],"ti":[0,0,0]},{"t":100,"s":[-320.578,7,0]}],"ix":2},"a":{"a":0,"k":[-50,-227,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.334,0.334],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[301,0]},{"i":{"x":[0.575,0.575],"y":[1,0.529]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[301,203]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.221]},"t":50,"s":[301,108.054]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":70,"s":[301,0]},{"t":100,"s":[301,0]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.682352941176,0,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.546,"y":1},"o":{"x":0.652,"y":0},"t":0,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"i":{"x":0.575,"y":0.529},"o":{"x":0.185,"y":0},"t":20,"s":[-50,-147],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.341,"y":0.351},"t":50,"s":[-50,-162.717],"to":[0,0],"ti":[0,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.652,"y":0.652},"t":70,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"t":100,"s":[-50,-174]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":1,"k":[{"i":{"x":[0.546,0.515],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[316,348]},{"i":{"x":[0.575,0.575],"y":[1,0.529]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[316,297]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.351]},"t":50,"s":[316,326.687]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":70,"s":[316,348]},{"t":100,"s":[316,348]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":20,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274988511,0.776471007104,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[-50,-6],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.334,0.334],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[301,0]},{"i":{"x":[0.575,0.575],"y":[1,0.529]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[301,203]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.221]},"t":50,"s":[301,108.054]},{"i":{"x":[0.667,0.667],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":70,"s":[301,0]},{"t":100,"s":[301,0]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":16,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.546,"y":1},"o":{"x":0.652,"y":0},"t":0,"s":[-50,160],"to":[0,0],"ti":[0,0]},{"i":{"x":0.575,"y":0.529},"o":{"x":0.185,"y":0},"t":20,"s":[-50,118],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.341,"y":0.351},"t":50,"s":[-50,142.448],"to":[0,0],"ti":[0,0]},{"i":{"x":0.667,"y":0.667},"o":{"x":0.652,"y":0.652},"t":70,"s":[-50,160],"to":[0,0],"ti":[0,0]},{"t":100,"s":[-50,160]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 2","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":0,"s":[{"i":[[0,0],[2.906,-156.434],[0,0]],"o":[[0,0],[-2.901,156.178],[0,0]],"v":[[-30.88,-142.037],[-274.955,-34.802],[-45.864,129.579]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":20,"s":[{"i":[[0,0],[2.906,-156.434],[0,0]],"o":[[0,0],[-2.902,156.178],[0,0]],"v":[[-33.391,-106.125],[155.065,-71.805],[-45.864,129.579]],"c":false}]},{"i":{"x":0.667,"y":1},"o":{"x":0.333,"y":0},"t":50,"s":[{"i":[[0,0],[2.906,-156.434],[0,0]],"o":[[0,0],[-2.902,156.178],[0,0]],"v":[[-33.391,-106.125],[155.065,-71.805],[-45.864,129.579]],"c":false}]},{"t":70,"s":[{"i":[[0,0],[2.906,-156.434],[0,0]],"o":[[0,0],[-2.901,156.178],[0,0]],"v":[[-30.88,-142.037],[-274.955,-34.802],[-45.864,129.579]],"c":false}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.776470648074,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":36,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[296.149,161.201],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":124,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.776470648074,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.733332974303,0.470587995941,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[-45.462,-142.762],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":20,"s":[-45.462,-32.762],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":70,"s":[-45.462,-90.762],"to":[0,0],"ti":[0,0]},{"t":100,"s":[-45.462,-142.762]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 2","np":3,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0}]},{"id":"comp_2","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Shape Layer 3","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":0,"s":[964,962,0],"to":[0,0,0],"ti":[0,0,0]},{"t":6,"s":[964,924,0]}],"ix":2},"a":{"a":0,"k":[-226,318,0],"ix":1},"s":{"a":0,"k":[50,50,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-248,319.333],[-292,319.333]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-230,316],"ix":2},"a":{"a":0,"k":[-230,316],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-248,319.333],[-292,319.333]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-230,316],"ix":2},"a":{"a":0,"k":[-230,316],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":90,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 3","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-248,319.333],[-292,319.333]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-230,316],"ix":2},"a":{"a":0,"k":[-230,316],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":180,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 4","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0]],"o":[[0,0],[0,0]],"v":[[-248,319.333],[-292,319.333]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-230,316],"ix":2},"a":{"a":0,"k":[-230,316],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":270,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":6,"s":[0]},{"t":8,"s":[100]}],"ix":1},"e":{"a":1,"k":[{"i":{"x":[0],"y":[1]},"o":{"x":[0.333],"y":[0]},"t":6,"s":[0]},{"t":11,"s":[100]}],"ix":2},"o":{"a":0,"k":0,"ix":3},"m":1,"ix":5,"nm":"Trim Paths 1","mn":"ADBE Vector Filter - Trim","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[1,1],"y":[1,1]},"o":{"x":[1,1],"y":[0,0]},"t":3,"s":[68,68]},{"t":6,"s":[98,98]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":20,"ix":5},"lc":2,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-226,318],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":1,"k":[{"t":3,"s":[100],"h":1},{"t":6,"s":[0],"h":1}],"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":11,"st":0,"bm":0}]},{"id":"comp_3","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"cuplip 3","td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-4,"ix":10},"p":{"a":0,"k":[967,1280.578,0],"ix":2},"a":{"a":0,"k":[-50,-227,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0},"t":13,"s":[{"i":[[0,0],[0,0],[0,0],[-55.288,13.228],[0,0]],"o":[[0,0],[0,0],[0,0],[89.674,-21.454],[0,0]],"v":[[604.678,-749.815],[-198.802,-183.039],[79.084,-103.403],[176.149,-155.361],[309.827,-178.842]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0},"t":20,"s":[{"i":[[0,0],[0,0],[0,0],[-56.673,20.424],[0,0]],"o":[[0,0],[0,0],[0,0],[86.744,-31.261],[0,0]],"v":[[604.678,-749.815],[-198.802,-183.039],[75.671,-89.679],[173.549,-149.595],[309.827,-178.842]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":27,"s":[{"i":[[0,0],[0,0],[0,0],[-111.043,28.9],[0,0]],"o":[[0,0],[0,0],[0,0],[111.043,-28.9],[0,0]],"v":[[599.046,-753.492],[-198.802,-183.039],[82.8,-105.576],[223.111,-171.972],[586.872,-222.833]],"c":true}]},{"i":{"x":0.833,"y":0.879},"o":{"x":0.167,"y":0.167},"t":35,"s":[{"i":[[0,0],[0,0],[0,0],[-171.273,103.787],[0,0]],"o":[[0,0],[0,0],[0,0],[121.968,-73.909],[0,0]],"v":[[589.754,-759.557],[-198.802,-183.039],[94.563,-131.805],[308.765,-291.641],[720.298,-508.532]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.121},"t":42,"s":[{"i":[[0,0],[0,0],[0,0],[-125.903,120.312],[0,0]],"o":[[0,0],[0,0],[0,0],[240.625,-229.941],[0,0]],"v":[[502.448,-855.045],[-198.802,-183.039],[104.856,-154.755],[339.915,-433.695],[708.226,-762.585]],"c":true}]},{"i":{"x":0.833,"y":0.771},"o":{"x":0.167,"y":0},"t":50.626,"s":[{"i":[[0,0],[0,0],[0,0],[-115.823,140.602],[0,0]],"o":[[0,0],[0,0],[0,0],[111.641,-135.526],[0,0]],"v":[[543.256,-789.907],[-198.802,-183.039],[104.856,-154.755],[263.297,-374.552],[573.882,-712.365]],"c":true}]},{"i":{"x":0.833,"y":1},"o":{"x":0.167,"y":0.229},"t":52.081,"s":[{"i":[[0,0],[0,0],[0,0],[-115.823,140.602],[0,0]],"o":[[0,0],[0,0],[0,0],[111.641,-135.526],[0,0]],"v":[[452.96,-735.67],[-198.802,-183.039],[104.856,-154.755],[263.297,-374.552],[483.586,-658.127]],"c":true}]},{"t":63,"s":[{"i":[[0,0],[0,0],[0,0],[-115.823,140.602],[0,0]],"o":[[0,0],[0,0],[0,0],[111.641,-135.526],[0,0]],"v":[[543.256,-789.907],[-198.802,-183.039],[104.856,-154.755],[263.297,-374.552],[573.882,-712.365]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274988511,0.776471007104,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.733333333333,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.334,0.334],"y":[1,1]},"o":{"x":[0.652,0.636],"y":[0,0]},"t":0,"s":[301,39.892]},{"i":{"x":[0.575,0.575],"y":[1,0.52]},"o":{"x":[0.185,0.185],"y":[0,0]},"t":20,"s":[301,203]},{"i":{"x":[0.833,0.833],"y":[1,1]},"o":{"x":[0.341,0.341],"y":[0,0.217]},"t":50.626,"s":[301,108.054]},{"t":63,"s":[301,39.892]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274988511,0.776471007104,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.733333333333,0.470588235294,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.546,"y":1},"o":{"x":0.652,"y":0},"t":0,"s":[-50,-174],"to":[0,0],"ti":[0,0]},{"i":{"x":0.575,"y":0.52},"o":{"x":0.185,"y":0},"t":20,"s":[-50,-147],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":1},"o":{"x":0.341,"y":0.217},"t":50.626,"s":[-50,-162.717],"to":[0,0],"ti":[0,0]},{"t":63,"s":[-50,-174]}],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Shape Layer 2","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.816],"y":[1.055]},"o":{"x":[0.55],"y":[0]},"t":10,"s":[-94]},{"i":{"x":[0.443],"y":[1.239]},"o":{"x":[0.315],"y":[0.073]},"t":19,"s":[-110.783]},{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.19],"y":[0.114]},"t":26,"s":[-93.995]},{"i":{"x":[0.69],"y":[1.722]},"o":{"x":[0.298],"y":[0]},"t":40,"s":[-118]},{"i":{"x":[0.793],"y":[1]},"o":{"x":[0.43],"y":[0.135]},"t":49.346,"s":[-122.993]},{"i":{"x":[0.833],"y":[1]},"o":{"x":[0.167],"y":[0]},"t":53.537,"s":[-106.327]},{"t":54.9931640625,"s":[-99.327]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":0.229,"y":0},"t":10,"s":[961.707,1441.219,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":0.681},"o":{"x":0.333,"y":0},"t":40,"s":[1009.323,1270.602,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.667,"y":0.913},"o":{"x":0.333,"y":0.089},"t":49.346,"s":[1081.173,1250.193,0],"to":[0,0,0],"ti":[-10.644,-14.925,0]},{"i":{"x":0.667,"y":0.969},"o":{"x":0.167,"y":0},"t":53.537,"s":[1199.04,1239.742,0],"to":[10.644,14.925,0],"ti":[9,-16.667,0]},{"t":54.9931640625,"s":[1145.04,1339.742,0]}],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":10,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.655],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[168,832],[0,80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":19,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.656],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[-13.064,849.409],[0,80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":29,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.655],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[129.445,858.258],[0,80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":44.275,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.655],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144.001],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[180.426,960.831],[-48.829,18.164]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":50,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.937],[107.112,115.14],[211.78,341.174]],"o":[[0,0],[185.862,-24.782],[93.962,207.939],[-476.754,-512.487],[-160.105,-257.927]],"v":[[-384,-144],[-416,64],[-106.262,927.48],[462.764,908.328],[-30.168,76.577]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":52,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[175.665,17.669],[194.537,227.757]],"o":[[0,0],[185.862,-24.781],[93.962,207.937],[-500.265,-405.726],[-186.209,-218.008]],"v":[[-384,-144],[-416,64],[-106.262,927.482],[738.439,911.395],[-44.112,-17.085]],"c":true}]},{"t":53.537109375,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[116.688,151.014],[421.836,493.997]],"o":[[0,0],[185.862,-24.782],[93.963,207.938],[-137.931,-178.506],[-181.608,-212.675]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[573.798,951.861],[35.697,51.917]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.658823529412,0.258823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 2","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":10,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.655],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[168,832],[0,80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":19,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.656],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[-13.064,849.409],[0,80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":29,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.655],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[129.445,858.258],[0,80]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":44.275,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[-3.87,69.655],[94.101,117.708]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[8,-144.001],[-189.564,-237.119]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[180.426,960.831],[-48.829,18.164]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":50,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[113,109.367],[118.955,291.854]],"o":[[0,0],[185.862,-24.782],[93.962,207.938],[-526.243,-509.324],[-114.58,-281.125]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[484.194,972.228],[-30.168,76.577]],"c":true}]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":52,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[175.665,17.669],[148.783,188.942]],"o":[[0,0],[185.862,-24.782],[93.962,207.937],[-500.265,-405.726],[-177.376,-225.254]],"v":[[-401.241,-133.863],[-433.241,74.137],[-123.503,937.619],[721.198,921.532],[-68.57,-20.802]],"c":true}]},{"t":53.537109375,"s":[{"i":[[0,0],[-360,48],[-100.289,-221.938],[116.688,151.014],[421.836,493.997]],"o":[[0,0],[185.862,-24.782],[93.963,207.938],[-137.931,-178.506],[-181.608,-212.675]],"v":[[-384,-144],[-416,64],[-106.262,927.481],[573.798,951.861],[35.697,51.917]],"c":true}]}],"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.658823529412,0.258823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,-54],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":1,"k":[{"i":{"x":[0.833,0.833],"y":[0.833,0.833]},"o":{"x":[0.167,0.167],"y":[0.167,0.167]},"t":42.533,"s":[73.79,447.711]},{"t":53.537109375,"s":[274.79,447.711]}],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[1,0.732180008234,0.470587995941,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":42,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,0.658823529412,0.258823529412,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":1,"k":[{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":44.275,"s":[-99.522,23.668],"to":[0,0],"ti":[0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.167,"y":0.167},"t":50,"s":[93.296,517.169],"to":[0,0],"ti":[0,0]},{"t":53.537109375,"s":[307.919,887.317]}],"ix":2},"a":{"a":0,"k":[26,0],"ix":1},"s":{"a":0,"k":[64.694,64.694],"ix":3},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":44.275,"s":[-29.124]},{"t":46.8115234375,"s":[-13.124]}],"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":101,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 13","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[800,600,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[40,40,100],"ix":6}},"ao":0,"ip":0,"op":216,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":0,"nm":"mug","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":0,"op":7,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":0,"nm":"mug","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":0,"op":59,"st":-51,"bm":0},{"ddd":0,"ind":4,"ty":0,"nm":"mug","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[-100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":0,"op":101,"st":0,"bm":0},{"ddd":0,"ind":5,"ty":0,"nm":"mug","parent":1,"refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2},"a":{"a":0,"k":[960,960,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"w":1920,"h":1920,"ip":59,"op":101,"st":-51,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"Shape Layer 1","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[800,600,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"rc","d":1,"s":{"a":0,"k":[1920,1920],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"r":{"a":0,"k":0,"ix":4},"nm":"Rectangle Path 1","mn":"ADBE Vector Shape - Rect","hd":false},{"ty":"st","c":{"a":0,"k":[0.686274509804,0.776470648074,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":0,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.68235318053,0,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Rectangle 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":216,"st":0,"bm":0}],"markers":[]} --------------------------------------------------------------------------------