Lottie 是Airbnb开源的一个面向 iOS、Android、React Native 的动画库,能分析 Adobe After Effects 导出的动画,并且能让原生 App 像使用静态素材一样使用这些动画,完美实现动画效果。

现在使用各平台的 native 代码实现一套复杂的动画是一件很困难并且耗时的事,我们需要为不同尺寸的屏幕加载不同的素材资源,还需要写大量难维护的代码,而Lottie可以做到同一个动画文件在不同平台上实现相同的效果,极大减少开发时间,实现不同的动画,只需要设置不同的动画文件即可,极大减少开发和维护成本。

为什么使用Lottie?

跨平台只有制作一套json动画文件便可以跨平台在 Android ios ReactNeative上使用,lottie库负责解析json文件并播放动画

可以支持网络下载json文件,本地播放,实时更新动画资源。

运行时效率上仅仅用Canvas去draw而已,流畅度非常棒,所以哪怕在Listview里去大量显示,内存占用和绘图效率都远远高于帧动画。

实现效果可以按设计出的100%还原到产品中。

开发周期大大减少。
定制DIY名片并不是件简单的事情,官方本身是禁止这种行为的,被和谐了很多次:
特殊unicode字符法——已和谐
域名伪装法——已和谐
Http法——已和谐
半屏显示法——已和谐
经过TX几次的和谐之后终于算是稳定了,最终方案为伪装图片zip
大致原理就是制作lottie动画在通过JSON上传就可以实现了

开始教程

准备工具:
1.Xposed框架(很多安卓手机已经不支持这个了,建议在虚拟机下运行)
2.Adobe After Effects CC(2019)+bodymovin(5.6.10)(必须CC版本,CS不支持)
3.自定义DIY名片工具,下载地址:https://lanzous.com/ianhi6j
4.SVIP

怎样使用bodymovin?

拷贝bodymovin文件夹到如下位置:

Win : C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\

Mac : ~/Library/Application Support/Adobe/CEP/extensions

大概就这些关键工具,全部就绪好后开始。
1.安装QQ、Xposed框架、DIY工具等,在Xposed框架中激活DIY名片模块.
2.image_view是静态图片,lottie_view是lottie动画,自行根据需要替换,静态图片很简单,直接上传到图床上,粘贴图片直链就行,视频就比较麻烦,很考验对视频的后期处理能力,这里我建议的导出参数有10帧,281500分辨率(也有297700的),图片序列控制在200张以内(150张以下最佳),一张图保持在20KB-50KB,压缩后的zip应小于5MB,,帧数太高或者分辨率太高可能会导致闪屏或者加载慢,下面来讲视频的处理过程
avatar
3.先把原视频导出成PNG序列,然后在AE中合成PNG,勾选单个合成,序列图层,渲染队列。不用勾,静止持续时间0:00:00:03
avatar
4.窗口->扩展->bodymovin,选择目标路径,开始渲染,生成data.json,data.json的代码就不说了,里面全是动画参数,看也看不懂。
avatar
5.打包image文件夹和data.json成zip格式,在用copy /b xx.jpg+xx.zip xx.jpg 合并命令伪装图片
上传至云盘,获得直链,复制到type为lottie_view下的content对象里。
avatar
6.在DIY名片插件中粘贴生成JSON代码,重启QQ,登录QQ,任选一张名片再次刷新,自定义名片就生成了。
avatar
DIY名片工具所需JSON代码如下:

{
    "styleId": 22,
    "bgId": 3807,
    "cardId": 3807,
    "renderInfo": {
        "bg": [{
            "type": "image_view",
            "scale_type": "center_crop",
            "content": ""
        }, {
            "type": "mask_view",
            "content": "#00000000"
        }, {
            "loop": "1",
            "type": "lottie_view",
            "content": "https:\/\/imgcache.qq.com@r.photo.store.qq.com/psc?\/1e3eee36-58c1-427c-adbd-b483a71f8360/bqQfVz5yrrGYSXMvKr.cqZngYd1GpR.7w3J2dVjWPyu.SOqMTBsXAQzgfy7J.eAS7FgDxsd9RUQd5Uvtu4kD0e6.5HHWCfzWwdydGIpgwKg!\/b&bo=OASABzgEgAcDCSw!&rf=viewer_4\/r"
        }],
        "v": 909125644,
        "header": {
            "width": "fill",
            "type": "layout",
            "order": 0,
            "height": "fill",
            "child": [{
                "loop": "1",
                "width": "fill",
                "type": "lottie_view",
                "content": "",
                "height": "fill"
            }, {
                "loop": "1",
                "type": "lottie_view",
                "content": ""
            }, {
                "border": "1",
                "x": "520w",
                "y": "-7100h",
                "id": "1002",
                "type": "pf_avatar",
                "positionLimit": {
                    "top": "88px",
                    "bottom": "88px"
                }
            }, {
                "rotate": 0,
                "x": "3000w",
                "width": "6000w",
                "y": "-7250h",
                "id": "2001",
                "type": "image_view",
                "scale_type": "center_crop",
                "content": "https:\/\/imgcache.qq.com@images-cdn.shimo.im\/756kVABIRQaCae3d.png?club.vip.qq.com&",
                "positionLimit": {
                    "bottom": "75px"
                },
                "height": "3500w",
                "stickerId": 2063
            }, {
                "loop": "1",
                "width": "10000w",
                "x": "0w",
                "y": "200h",
                "type": "lottie_view",
                "content": "",
                "height": "10000w"
            }, {
                "loop": "1",
                "type": "lottie_view",
                "content": ""
            }, {
                "loop": "1",
                "width": "5000w",
                "x": "-14200w",
                "y": "-10200w",
                "type": "lottie_view",
                "content": "",
                "height": "5000w"
            }, {
                "width": "4000w",
                "x": "33766w",
                "y": "28099h",
                "id": "1",
                "type": "image_view",
                "scale_type": "center_crop",
                "content": "",
                "stickerId": 2068,
                "height": "4000w"
            }, {
                "rotate": 2,
                "x": "2630w",
                "width": "730w",
                "y": "-8200h",
                "id": "1004",
                "type": "image_view",
                "scale_type": "center_crop",
                "content": "https:\/\/imgcache.qq.com@images-cdn.shimo.im\/LuMyc0w4wpVT0rcl.png?club.vip.qq.com&",
                "height": "730w",
                "stickerId": 2065
            }, {
                "bg": "",
                "f": 0,
                "width": "800w",
                "x": "283300w",
                "y": "920000h",
                "id": "1003",
                "type": "pf_name",
                "ft": 1,
                "positionLimit": {
                    "top": "88px",
                    "left": "32px",
                    "bottom": "120px",
                    "right": "32px"
                },
                "height": ""
            }, {
                "lpd": 120000,
                "bg": "",
                "rpd": 12,
                "x": "-36000w",
                "y": "0h",
                "style": 1,
                "id": "1001",
                "type": "pf_like",
                "positionLimit": {
                    "top": "88px",
                    "bottom": "88px"
                },
                "height": "100050w"
            }]
        },
        "body": {
            "arr": "https:\/\/imgcache.qq.com@s1.ax1x.com\/2020\/07\/18\/U2YL3F.png??imgcache.qq.com&",
            "c": "#00000000",
            "cpd": 8,
            "f": "GROUP99799305",
            "line": "#00000000",
            "t_bg": "https:\/\/imgcache.qq.com\/xydata\/card\/item\/3807\/r\/dcc6ef2de2bd4853c3293678d54ff-t_bg.png?1304009050?imgcache.qq.com&",
            "module": [{
                "arr": "https:\/\/imgcache.qq.com\/\/xydata\/\/card\/\/customProfileSticker\/\/2011\/\/content.png",
                "p": "https:\/\/imgcache.qq.com@uploader.uploader.shimo.im\/f\/fb5XkFnj9i5n1FIF.png?imgcache.qq.com&",
                "qq": "https:\/\/imgcache.qq.com@uploader.uploader.shimo.im\/f\/fb5XkFnj9i5n1FIF.png?imgcache.qq.com&",
                "metal": "https:\/\/imgcache.qq.com@uploader.uploader.shimo.im\/f\/fb5XkFnj9i5n1FIF.png?imgcache.qq.com&",
                "sign": "https:\/\/imgcache.qq.com@uploader.uploader.shimo.im\/f\/fb5XkFnj9i5n1FIF.png?imgcache.qq.com&",
                "lv": "https:\/\/imgcache.qq.com@uploader.uploader.shimo.im\/f\/fb5XkFnj9i5n1FIF.png?imgcache.qq.com&",
                "type": "info"
            }, {
                "ph": "https:\/\/imgcache.qq.com\/xydata\/card\/item\/3807\/r\/dcc6ef2de2bd4853c3293678d54ff-t_bg.png?imgcache.qq.com&",
                "type": "state"
            }, {
                "ph": "https:\/\/imgcache.qq.com\/xydata\/card\/item\/3807\/r\/dcc6ef2de2bd4853c3293678d54ff-t_bg.png?imgcache.qq.com&",
                "type": "qz"
            }, {
                "type": "photo"
            }, {
                "type": "tag"
            }, {
                "type": "exp"
            }],
            "cbg": "https:\/\/imgcache.qq.com\/xydata\/card\/item\/3807\/r\/dcc6ef2de2bd4853c3293678d54ff-cbg.png?imgcache.qq.com&",
            "sbg": "https:\/\/imgcache.qq.com@uploader.shimo.im\/f\/risYqmv8XTQIPJda.png?imgcache.qq.com&",
            "id": 22,
            "ts": 0
        }
    },
    "callback": "__MQQ_CALLBACK_AUTO_7"
}

最终效果:

avatar

2021年某日起动态名片一旦换掉就无法换回来,
1001为点赞,1002为头像,1003为昵称
bg_id决定背景ID,
card_md5决定框的类型,不能为空,MD5不存在则隐藏
已知MD5:
杂志:189eaa75f991a24c5e67bd89cc4f5d1f
唯美:c9f374febf69d976de4840be07059063
潮流派:dcc6ef2de2bd4853c3b10293678d54ff
甜甜爱情:42939e51cd18a09aad371a67caf93062
animation_md5只是一个校验,动画还是由bg_id决定
bg_id为0时base64_bg_pic不为空
body_info里的color为#00000000时完全透明
2022年1月 静态名片和谐

最后一次代码如下

{
    "style_id": 22,
    "bg_id": 0,
    "card_id": 3807,
    "card_md5": "d37f1c233aa888b125fbc4f8a6308790",
    "render_info": {
        "bg_info": {
            "base64_bg_pic": "",
            "mask_view": "#00000000",
            "lottie_id": "",
            "animation_md5": "",
            "animation_loop": "1"
        },
        "head_info": {
            "head_items": {
                "1001": {
                    "position_info": {
                        "x_axis": "-36000w",
                        "y_axis": "0h",
                        "height": "100050w",
                        "position_limit": {
                            "top": "88px",
                            "bottom": "88px"
                        }
                    },
                    "int_kv": {
                        "style": 1,
                        "lpd": 120000,
                        "rpd": 12
                    },
                    "str_kv": {
                        "id": "1001",
                        "type": "pf_like"
                    }
                },
                "1002": {
                    "position_info": {
                        "x_axis": "520w",
                        "y_axis": "-7100h",
                        "position_limit": {
                            "top": "88px",
                            "bottom": "88px"
                        }
                    },
                    "int_kv": {
                        "border": 1
                    },
                    "str_kv": {
                        "id": "1002",
                        "type": "pf_avatar"
                    }
                },
                "1003": {
                    "position_info": {
                        "x_axis": "283300w",
                        "y_axis": "920000h",
                        "width": "800w",
                        "height": "",
                        "gravity": "center_horizontal",
                        "position_limit": {
                            "top": "88px",
                            "bottom": "120px",
                            "left": "32px",
                            "right": "32px"
                        }
                    },
                    "int_kv": {
                        "f": 0,
                        "ft": 1
                    },
                    "str_kv": {
                        "id": "1003",
                        "type": "pf_name"
                    }
                }
            }
        },
        "body_info": {
            "color": "#00000000",
            "cpd": 8,
            "line_color": "#00000000",
            "ts": 0
        }
    }
}