ESP32 S3 IDF arduino-platformio编译使用lvgl下的rlottie player

1.源文件准备 

(1)获取源代码      

由于很多人不满足gif文件在lvgl播放下占用大量的flash内存,今天我们来讲解一下怎么为esp32的两种框架esp-idf ,arduino-platformio实现rlottie 动画的播放。

        首先我参考b站up@西瓜杨桃的视频讲解,他提供了主要的思路和步骤,我也是通过复现他的过程中发现了很多问题和逐步解决这些问题的。

        首先我们来到github找到三星的这个rlottie库,分支中选择c++11和工具链选择esp-idf4.4.6 powershell才能够成功编译,编译完生成的静态库适用于5.2以下的版本,更高的版本还没有测试过的。使用这样的选择能解决因为posix标准系统带来的文件问题,不过我也不清楚是否比起c++14版本是否会有性能下降等情况。https://github.com/Samsung/rlottie

我们下载下来这个zip,随后会使用这个文件。

(2)查找esp工具链

使用everthing软件查找toolchain-esp32s3.cmake,一定要是4.4.6版本

你需要安装一个esp-idf 4.4.6的powershell具体怎么安装请自行网上查找,然后找到他,打开准备用于编译。一定要是4.4.6版本

最好使用你的编译环境下的工具链,不过本质上一样的

2.编译

(1)CMake

创建一个文件夹,构建如下的结构树,将解压出来的源代码改名为rlottie放入这个文件夹

修改CMakeLists.txt为一下内容

cmake_minimum_required(VERSION 3.14)

Set(LOTTIE_MODULE OFF)
Set(LOTTIE_THREAD OFF)
Set(BUILD_SHARED_LIBS OFF)
set(LOTTIE_EXAMPLE OFF)
add_definitions(-DESP_PLATFORM)
add_subdirectory(rlottie)

(2)为源文件打上esp的补丁

From 18083a559734d297838e4cf34a856a4770062319 Mon Sep 17 00:00:00 2001

From: tvanfossen <vanfosst@gmail.com>

Date: Tue, 23 Aug 2022 10:06:53 -0400

Subject: [PATCH] changes to compile with esp-idf

---

 CMakeLists.txt              | 11 ++++++-----

 src/vector/vimageloader.cpp | 23 +++++++++++++----------

 2 files changed, 19 insertions(+), 15 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt

index 38a9862..ee6d2cd 100644

--- a/CMakeLists.txt

+++ b/CMakeLists.txt

@@ -95,10 +95,11 @@ if (NOT APPLE AND NOT WIN32)

                           )

 endif()

-if (LOTTIE_MODULE)

-    # for dlopen, dlsym and dlclose dependency

-    target_link_libraries(rlottie PRIVATE ${CMAKE_DL_LIBS})

-endif()

+# No Sym links in ESP-IDF

+# if (LOTTIE_MODULE)

+#     # for dlopen, dlsym and dlclose dependency

+#     target_link_libraries(rlottie PRIVATE ${CMAKE_DL_LIBS})

+# endif()

 if (NOT LOTTIE_ASAN)

     if(APPLE)

@@ -137,7 +138,7 @@ endif (NOT LIB_INSTALL_DIR)

 #declare source and include files

 add_subdirectory(inc)

 add_subdirectory(src)

-add_subdirectory(example)

+# add_subdirectory(example) // We dont need example dir in ESP-IDF

 if (LOTTIE_TEST)

     enable_testing()

diff --git a/src/vector/vimageloader.cpp b/src/vector/vimageloader.cpp

index c2446be..3df4c6a 100644

--- a/src/vector/vimageloader.cpp

+++ b/src/vector/vimageloader.cpp

@@ -6,7 +6,7 @@

 #ifdef _WIN32

 # include <windows.h>

 #else

-# include <dlfcn.h>

+// # include <dlfcn.h> //Does not work on ESP-IDF

 #endif  // _WIN32

 using lottie_image_load_f = unsigned char *(*)(const char *filename, int *x,

@@ -61,22 +61,25 @@ struct VImageLoader::Impl {

     void *dl_handle{nullptr};

     void  init()

     {

-        imageLoad = reinterpret_cast<lottie_image_load_f>(

-                    dlsym(dl_handle, "lottie_image_load"));

-        imageFree = reinterpret_cast<lottie_image_free_f>(

-                    dlsym(dl_handle, "lottie_image_free"));

-        imageFromData = reinterpret_cast<lottie_image_load_data_f>(

-                    dlsym(dl_handle, "lottie_image_load_from_data"));

+        // No sym links in ESP-iDF

+        // imageLoad = reinterpret_cast<lottie_image_load_f>(

+        //             dlsym(dl_handle, "lottie_image_load"));

+        // imageFree = reinterpret_cast<lottie_image_free_f>(

+        //             dlsym(dl_handle, "lottie_image_free"));

+        // imageFromData = reinterpret_cast<lottie_image_load_data_f>(

+        //             dlsym(dl_handle, "lottie_image_load_from_data"));

     }

     void moduleFree()

     {

-        if (dl_handle) dlclose(dl_handle);

+        // if (dl_handle) dlclose(dl_handle); // No sym links in ESP-iDF

     }

     bool moduleLoad()

     {

-        dl_handle = dlopen(LOTTIE_IMAGE_MODULE_PLUGIN, RTLD_LAZY);

-        return (dl_handle == nullptr);

+        // No sym links in ESP idf

+        // dl_handle = dlopen(LOTTIE_IMAGE_MODULE_PLUGIN, RTLD_LAZY);

+        // return (dl_handle == nullptr);

+        return true

     }

 # endif  // _WIN32

 #else  // LOTTIE_IMAGE_MODULE_SUPPORT

--

2.34.1

 指导一下如何找到这些文件,首先是rlottie下的cmakelists.txt,直接复制我已经修改好的cmakelists内容进去

cmake_minimum_required( VERSION 3.3 )

#declare project
project( rlottie VERSION 0.0.1 LANGUAGES C CXX ASM)

if (NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE MinSizeRel)
endif()

if (NOT DEFINED BUILD_SHARED_LIBS)
    # Keep the previous behavior of the build system, consistent with Meson.
    set(BUILD_SHARED_LIBS ON)
endif()

#declare target
add_library( rlottie )
set_target_properties( rlottie PROPERTIES DEFINE_SYMBOL LOT_BUILD )

#declare version of the target
set(player_version_major 0)
set(player_version_minor 0)
set(player_version_patch 1)
set(player_version ${player_version_major}.${player_version_minor}.${player_version_patch} )
set_target_properties(rlottie PROPERTIES
                        VERSION    ${player_version}
                        SOVERSION  ${player_version_major}
                      )

#declare alias so that library can be used inside the build tree, e.g. when testing
add_library(rlottie::rlottie ALIAS rlottie)

option(LOTTIE_MODULE "Enable LOTTIE MODULE SUPPORT" OFF)
option(LOTTIE_THREAD "Enable LOTTIE THREAD SUPPORT" OFF)
option(LOTTIE_CACHE "Enable LOTTIE CACHE SUPPORT" ON)
option(LOTTIE_TEST "Build LOTTIE AUTOTESTS" OFF)
option(LOTTIE_CCACHE "Enable LOTTIE ccache SUPPORT" OFF)
option(LOTTIE_ASAN "Compile with asan" OFF)

set(LOTTIE_MODULE_PATH "${CMAKE_SHARED_LIBRARY_PREFIX}rlottie-image-loader${CMAKE_SHARED_LIBRARY_SUFFIX}"
    CACHE STRING "Absolute or relative path to dynamic loader plugin.")

configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in config.h)

target_include_directories(rlottie
    PRIVATE
        "${CMAKE_CURRENT_BINARY_DIR}"
    )

#declare target compilation options
target_compile_options(rlottie
                    PUBLIC
                    PRIVATE
                        -std=c++11
                        -fno-exceptions
                        -fno-unwind-tables
                        -fno-asynchronous-unwind-tables
                        -fno-rtti
                        -Wall
                        -Werror
                        -Wextra
                        -Wnon-virtual-dtor
                        -Woverloaded-virtual
                        -Wno-unused-parameter
                        -fvisibility=hidden
                    )

#declare dependancy
set( CMAKE_THREAD_PREFER_PTHREAD TRUE )
find_package( Threads )

target_link_libraries(rlottie
                    PUBLIC
                        "${CMAKE_THREAD_LIBS_INIT}"
                     )

if (NOT APPLE AND NOT WIN32)
    target_link_libraries(rlottie
                        PRIVATE
                            "-Wl,--version-script=${CMAKE_SOURCE_DIR}/rlottie.expmap"
                          )
endif()

# No Sym links in ESP-IDF
# if (LOTTIE_MODULE)
#     # for dlopen, dlsym and dlclose dependency
#     target_link_libraries(rlottie PRIVATE ${CMAKE_DL_LIBS})
# endif()

if (NOT LOTTIE_ASAN)
    if(APPLE)
        target_link_libraries(rlottie
                            PUBLIC
                                 "-Wl, -undefined error"
                              )
    else()
        target_link_libraries(rlottie
                            PUBLIC
                                 "-Wl,--no-undefined"
                              )
    endif()
endif()

if (LOTTIE_CCACHE)
    find_program(CCACHE_FOUND ccache)
    if (CCACHE_FOUND)
        message(STATUS "Found ccache")
        set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
        set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
    else()
        message(STATUS "Could NOT find ccache (this is NOT an error)")
    endif()
endif()

if (LOTTIE_ASAN)
    target_compile_options(rlottie PUBLIC -fsanitize=address)
    target_link_options(rlottie PUBLIC  -fsanitize=address)
endif()

if (NOT LIB_INSTALL_DIR)
    set (LIB_INSTALL_DIR "/usr/lib")
endif (NOT LIB_INSTALL_DIR)

#declare source and include files
add_subdirectory(inc)
add_subdirectory(src)
# add_subdirectory(example)

# if (LOTTIE_TEST)
#     enable_testing()
#     add_subdirectory(test)
# endif()

SET(PREFIX ${CMAKE_INSTALL_PREFIX})
SET(EXEC_DIR ${PREFIX})
SET(LIBDIR ${LIB_INSTALL_DIR})
SET(INCDIR ${PREFIX}/include)

CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc)
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)


#install header
install(FILES
        inc/rlottie.h
        inc/rlottie_capi.h
        inc/rlottiecommon.h
        DESTINATION include)

#install lib
install( TARGETS rlottie EXPORT rlottie-targets
         LIBRARY     DESTINATION    ${LIB_INSTALL_DIR}
         ARCHIVE     DESTINATION    ${LIB_INSTALL_DIR}
         INCLUDES    DESTINATION    include
       )

#install config file.

install( EXPORT rlottie-targets
         FILE          rlottieTargets.cmake
         NAMESPACE     rlottie::
         DESTINATION   ${LIB_INSTALL_DIR}/cmake/rlottie
       )


#Create a ConfigVersion.cmake file
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfigVersion.cmake
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY AnyNewerVersion
)

configure_package_config_file(${CMAKE_CURRENT_LIST_DIR}/cmake/rlottieConfig.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfig.cmake
    INSTALL_DESTINATION ${LIB_INSTALL_DIR}/cmake/rlottie
)

#Install the config, configversion and custom find modules
install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfig.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/rlottieConfigVersion.cmake
    DESTINATION ${LIB_INSTALL_DIR}/cmake/rlottie
)


export(EXPORT rlottie-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/rlottieTargets.cmake NAMESPACE rlottie::)

#Register package in user's package registry
export(PACKAGE rlottie)

rlottie/src/vector/vimageloader.cpp这个文件中将这些代码屏蔽掉

找到\rlottie\src\binding\c\lottieanimation_capi.cpp这个文件为其添加strdup方法的定义如下图所示

#ifdef ESP_PLATFORM
extern "C" {
#include <string>
char* strdup(const char* str);
}
#endif

最后将rlottie/example文件夹直接删掉,否则会无法通过编译,这样我们就打好了补丁。

(3)获取静态库

保存文件,然后打开esp-idf powershell,进入到示例目录下

cd "D:\lv_lib_lottie\rlottie_lib\build"

将我们在开头找到的工具链地址复制进下面的命令里去。一定要是4.4.6版本

cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE="你查找到的toolchain-esp32s3.cmake地址"

然后就会开始编译

成功编译是这样的,然后使用以下命令使用ninja生成静态库

ninja

这样就成功获取了静态库librlottie.a文件在D:\lv_lib_lottie\rlottie_lib\build\rlottie目录下

3.将静态库链接到项目中

(1)platformio实现

编写platformio.ini,添加以下代码

lib_extra_dirs=

    "D:/lv_lib_lottie/rlottie_lib/build/rlottie"  #此处为存放静态库librlottie.a文件处

build_flags =

    -L"D://lv_lib_lottie/rlottie_lib/build2/rlottie"

    -lrlottie

    -I"D:/FirmwareS3/lib/lvgl/src/extra/libs/rlottie" #你项目中lvgl的文件地址\lib\lvgl\src\extra\libs\rlottie

 D:\lv_lib_lottie\rlottie_lib\rlottie\inc目录下找到rlottie_capi.h和rlottiecommon.h这两个文件复制到

你的项目地址\lvgl\src\extra\libs\rlottie下

打开lv_rlottie.c确保rlottie_capi.h是这样添加头文件的

/**
 * @file lv_rlottie.c
 *
 */
#include "esp_heap_caps.h"
/*********************
 *      INCLUDES
 *********************/
#include "lv_rlottie.h"
#if LV_USE_RLOTTIE

#include "rlottie_capi.h"

/*********************
*      DEFINES
*********************/
#define MY_CLASS &lv_rlottie_class

rlottie_capi.h中开头这样添加头文件

/* 
 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef _RLOTTIE_CAPI_H_
#define _RLOTTIE_CAPI_H_

#include <stddef.h>
#include <stdint.h>
#include "rlottiecommon.h"

这样就完成了静态库的链接了。

(2)idf实现

参考使用 ESP-IDF 生成第三方的 .a 静态库并使用的流程_idf 创建并生成.a-CSDN博客为idf添加rlottie.a 的实现

首先在components下新建rlottie文件夹,结构树如下

components/
└── rlottie/
    ├── include/
    │   ├── rlottie_capi.h
    │   └── rlottiecommon.h
    ├── CMakeLists.txt
    └── librlottie.a

cmakelists.txt如下编写

idf_component_register(INCLUDE_DIRS "./include")

target_link_libraries(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/librlottie.a")

这样你就可以在文件内调用 rlottie_capi.h和rlottiecommon.h中的api了

无论是在哪中框架下都不要忘记在lv_conf.h中开启lottie player

/*Rlottie library*/
#define LV_USE_RLOTTIE 1

4.ESP32 S3的特定优化 

为lottie动画分配缓冲代码如下 ,我们可以很明显看出一个80*80像素的lottie动画就需要25kb的内部ram,这是我们无法接受的尤其是你的lvgl已经分配一块不小的缓存。

size_t allocaled_buf_size = (create_width * create_height * LV_ARGB32 / 8);

所以我们修改这个代码让其在psram中分配缓冲区

#include "esp_heap_caps.h" //文件顶部进行头文件包含

static void lv_rlottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)
{
    LV_UNUSED(class_p);
    lv_rlottie_t * rlottie = (lv_rlottie_t *) obj;

    if(rlottie_desc_create) {
        rlottie->animation = lottie_animation_from_data(rlottie_desc_create, rlottie_desc_create, "");
    }
    else if(path_create) {
        rlottie->animation = lottie_animation_from_file(path_create);
    }
    if(rlottie->animation == NULL) {
        LV_LOG_WARN("The aniamtion can't be opened");
        return;
    }

    rlottie->total_frames = lottie_animation_get_totalframe(rlottie->animation);
    rlottie->framerate = (size_t)lottie_animation_get_framerate(rlottie->animation);
    rlottie->current_frame = 0;

    rlottie->scanline_width = create_width * LV_ARGB32 / 8;

    size_t allocaled_buf_size = (create_width * create_height * LV_ARGB32 / 8);
    rlottie->allocated_buf = heap_caps_malloc(allocaled_buf_size + 1, MALLOC_CAP_SPIRAM);
    if(rlottie->allocated_buf == NULL) {
        LV_LOG_WARN("Memory allocation failed");
        return;
    }
    if(rlottie->allocated_buf != NULL) {
        rlottie->allocated_buffer_size = allocaled_buf_size;
        memset(rlottie->allocated_buf, 0, allocaled_buf_size);
    }

    rlottie->imgdsc.header.always_zero = 0;
    rlottie->imgdsc.header.cf = LV_IMG_CF_TRUE_COLOR_ALPHA;
    rlottie->imgdsc.header.h = create_height;
    rlottie->imgdsc.header.w = create_width;
    rlottie->imgdsc.data = (void *)rlottie->allocated_buf;
    rlottie->imgdsc.data_size = allocaled_buf_size;

    lv_img_set_src(obj, &rlottie->imgdsc);

    rlottie->play_ctrl = LV_RLOTTIE_CTRL_FORWARD | LV_RLOTTIE_CTRL_PLAY | LV_RLOTTIE_CTRL_LOOP;
    rlottie->dest_frame = rlottie->total_frames; /* invalid destination frame so it's possible to pause on frame 0 */

    rlottie->task = lv_timer_create(next_frame_task_cb, 1000 / rlottie->framerate, obj);

    lv_obj_update_layout(obj);
}

将原先的 static void lv_rlottie_constructor(const lv_obj_class_t * class_p, lv_obj_t * obj)替换为我修改过的代码这样你就可以轻松创建一个150*150的lottie动画

示例如下

#include <lvgl>

const char lodingani[] = "{\"nm\":\"Main Scene\",\"ddd\":0,\"h\":500,\"w\":500,\"meta\":{\"g\":\"@lottiefiles/creator 1.15.0\"},\"layers\":[{\"ty\":4,\"nm\":\"Ellipse 1\",\"sr\":1,\"st\":0,\"op\":120,\"ip\":0,\"hd\":false,\"ddd\":0,\"bm\":0,\"hasMask\":false,\"ao\":0,\"ks\":{\"a\":{\"a\":0,\"k\":[0,0]},\"s\":{\"a\":0,\"k\":[80,80]},\"sk\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[246,247]},\"r\":{\"a\":1,\"k\":[{\"o\":{\"x\":0,\"y\":0},\"i\":{\"x\":1,\"y\":1},\"s\":[160],\"t\":0},{\"s\":[-200],\"t\":119}]},\"sa\":{\"a\":0,\"k\":0},\"o\":{\"a\":0,\"k\":100}},\"ef\":[],\"shapes\":[{\"ty\":\"sh\",\"bm\":0,\"hd\":false,\"nm\":\"Ellipse Path 1\",\"d\":1,\"ks\":{\"a\":0,\"k\":{\"c\":true,\"i\":[[-73.9546,0],[0,-73.9546],[73.9546,0],[0,73.9546]],\"o\":[[73.9546,0],[0,73.9546],[-73.9546,0],[0,-73.9546]],\"v\":[[0,-134],[134,0],[0,134],[-134,0]]}}},{\"ty\":\"tm\",\"bm\":0,\"hd\":false,\"nm\":\"Trim Path\",\"e\":{\"a\":1,\"k\":[{\"o\":{\"x\":0.65,\"y\":0},\"i\":{\"x\":0.36,\"y\":1},\"s\":[100],\"t\":4},{\"s\":[0],\"t\":120}]},\"o\":{\"a\":0,\"k\":0},\"s\":{\"a\":1,\"k\":[{\"o\":{\"x\":0.55,\"y\":0.06},\"i\":{\"x\":0.36,\"y\":1},\"s\":[100],\"t\":0},{\"s\":[0],\"t\":116}]},\"m\":1},{\"ty\":\"st\",\"bm\":0,\"hd\":false,\"nm\":\"Stroke\",\"lc\":2,\"lj\":2,\"ml\":1,\"o\":{\"a\":0,\"k\":100},\"w\":{\"a\":0,\"k\":28},\"c\":{\"a\":0,\"k\":[0,0.8667,0.702,1]}}],\"ind\":1},{\"ty\":4,\"nm\":\"Ellipse 1\",\"sr\":1,\"st\":0,\"op\":120,\"ip\":0,\"hd\":false,\"ddd\":0,\"bm\":0,\"hasMask\":false,\"ao\":0,\"ks\":{\"a\":{\"a\":0,\"k\":[0,0]},\"s\":{\"a\":0,\"k\":[80,80]},\"sk\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[246,247]},\"r\":{\"a\":1,\"k\":[{\"o\":{\"x\":0,\"y\":0},\"i\":{\"x\":1,\"y\":1},\"s\":[60],\"t\":0},{\"s\":[-300],\"t\":119}]},\"sa\":{\"a\":0,\"k\":0},\"o\":{\"a\":0,\"k\":100}},\"ef\":[],\"shapes\":[{\"ty\":\"sh\",\"bm\":0,\"hd\":false,\"nm\":\"Ellipse Path 1\",\"d\":1,\"ks\":{\"a\":0,\"k\":{\"c\":true,\"i\":[[-73.9546,0],[0,-73.9546],[73.9546,0],[0,73.9546]],\"o\":[[73.9546,0],[0,73.9546],[-73.9546,0],[0,-73.9546]],\"v\":[[0,-134],[134,0],[0,134],[-134,0]]}}},{\"ty\":\"tm\",\"bm\":0,\"hd\":false,\"nm\":\"Trim Path\",\"e\":{\"a\":1,\"k\":[{\"o\":{\"x\":0.65,\"y\":0},\"i\":{\"x\":0.36,\"y\":1},\"s\":[100],\"t\":26},{\"s\":[0],\"t\":120}]},\"o\":{\"a\":0,\"k\":0},\"s\":{\"a\":1,\"k\":[{\"o\":{\"x\":0.55,\"y\":0.06},\"i\":{\"x\":0.36,\"y\":1},\"s\":[100],\"t\":0},{\"s\":[0],\"t\":96}]},\"m\":1},{\"ty\":\"st\",\"bm\":0,\"hd\":false,\"nm\":\"Stroke\",\"lc\":2,\"lj\":2,\"ml\":1,\"o\":{\"a\":0,\"k\":100},\"w\":{\"a\":0,\"k\":28},\"c\":{\"a\":0,\"k\":[0,0.8667,0.702,1]}}],\"ind\":2},{\"ty\":4,\"nm\":\"Ellipse 1\",\"sr\":1,\"st\":0,\"op\":122,\"ip\":0,\"hd\":false,\"ddd\":0,\"bm\":0,\"hasMask\":false,\"ao\":0,\"ks\":{\"a\":{\"a\":0,\"k\":[0,0]},\"s\":{\"a\":0,\"k\":[100,100]},\"sk\":{\"a\":0,\"k\":0},\"p\":{\"a\":0,\"k\":[246,247]},\"r\":{\"a\":1,\"k\":[{\"o\":{\"x\":0,\"y\":0},\"i\":{\"x\":1,\"y\":1},\"s\":[0],\"t\":0},{\"s\":[-359],\"t\":120}]},\"sa\":{\"a\":0,\"k\":0},\"o\":{\"a\":0,\"k\":100}},\"ef\":[],\"shapes\":[{\"ty\":\"sh\",\"bm\":0,\"hd\":false,\"nm\":\"Ellipse Path 1\",\"d\":1,\"ks\":{\"a\":0,\"k\":{\"c\":true,\"i\":[[-73.9546,0],[0,-73.9546],[73.9546,0],[0,73.9546]],\"o\":[[73.9546,0],[0,73.9546],[-73.9546,0],[0,-73.9546]],\"v\":[[0,-134],[134,0],[0,134],[-134,0]]}}},{\"ty\":\"tm\",\"bm\":0,\"hd\":false,\"nm\":\"Trim Path\",\"e\":{\"a\":1,\"k\":[{\"o\":{\"x\":0.65,\"y\":0},\"i\":{\"x\":0.36,\"y\":1},\"s\":[100],\"t\":26},{\"s\":[0],\"t\":120}]},\"o\":{\"a\":0,\"k\":0},\"s\":{\"a\":1,\"k\":[{\"o\":{\"x\":0.55,\"y\":0.06},\"i\":{\"x\":0.36,\"y\":1},\"s\":[100],\"t\":0},{\"s\":[0],\"t\":96}]},\"m\":1},{\"ty\":\"st\",\"bm\":0,\"hd\":false,\"nm\":\"Stroke\",\"lc\":2,\"lj\":2,\"ml\":1,\"o\":{\"a\":0,\"k\":100},\"w\":{\"a\":0,\"k\":10},\"c\":{\"a\":0,\"k\":[0.8992,0.9808,0.9658,1]}}],\"ind\":3}],\"v\":\"5.7.0\",\"fr\":60,\"op\":120,\"ip\":0,\"assets\":[]}";

void ui_ainimation_screen_init(void){
lottie_screen = lv_obj_create(NULL);
lv_obj_clear_flag(lottie_screen, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_bg_color(lottie_screen, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(lottie_screen, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_disp_load_scr(lottie_screen);


// 初始化 Lottie 动画
lottie_obj = lv_rlottie_create_from_raw(lottie_screen, 150, 150, lodingani);
lv_obj_center(lottie_obj); 
}

void setup() 
{

    ui_ainimation_screen_init();

}

void loop()
{
    lv_timer_handler(); // 处理LVGL任务
}

tips:我设置了1024 * 30大小的堆栈用于lottie动画播放,lottie动画的json文件大于15kb就很难渲染成功,不知道为什么,可能是算力不够,我的刷新率太高

  • 21
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值