Flipagram 涂鸦特效逆向分析

背景

Flipagram是美国一款非常火爆的短视频应用,一度登顶美国appstore榜首。前段时间又被今日头条重金收购,被当做今日头条发展海外短视频、提升国际影响力的发力点。本着好奇的心情体验了一下这款APP,印象最深的是视频编辑能力比较强,特别是动态涂鸦效果感觉非常惊艳,打算好好研究一下,优化改进一下手Q现有的涂鸦效果。

Flipagram特效

仿涂鸦特效

初步推测:系统自带的粒子效果+手势,在手指移动的过程中创建不同效果的粒子发射机,粒子发射机发射不同效果的粒子。

IOS粒子效果

系统自带的粒子效果实现主要的类是:CAEmitterBehaviorCAEmitterLayerCAEmitterCell他们的作用分别是,定义粒子发射机的行为、设置发射机的特征、设置粒子的具体特效。

使用比较简单:

    //Create the root layer
    rootLayer = [CALayer layer];

    //Set the root layer's attributes
    rootLayer.bounds = CGRectMake(0, 0, 640, 480);
    CGColorRef color = CGColorCreateGenericRGB(0.0, 0.0, 0.0, 1);
    rootLayer.backgroundColor = color;
    CGColorRelease(color);

    //Load the spark image for the particle
    NSImage *image = [NSImage imageNamed:@"tspark"];
    CGImageRef img = [image CGImageForProposedRect:nil context:nil hints:nil];

    mortor = [CAEmitterLayer layer];
    mortor.emitterPosition = CGPointMake(320, 0);
    mortor.renderMode = kCAEmitterLayerAdditive;

    //Invisible particle representing the rocket before the explosion
    CAEmitterCell *rocket = [CAEmitterCell emitterCell];
    rocket.emissionLongitude = M_PI / 2;
    rocket.emissionLatitude = 0;
    rocket.lifetime = 1.6;
    rocket.birthRate = 1;
    rocket.velocity = 400;
    rocket.velocityRange = 100;
    rocket.yAcceleration = -250;
    rocket.emissionRange = M_PI / 4;
    color = CGColorCreateGenericRGB(0.5, 0.5, 0.5, 0.5);
    rocket.color = color;
    CGColorRelease(color);
    rocket.redRange = 0.5;
    rocket.greenRange = 0.5;
    rocket.blueRange = 0.5;

    //Name the cell so that it can be animated later using keypath
    rocket.name = @"rocket";

    //Flare particles emitted from the rocket as it flys
    CAEmitterCell *flare = [CAEmitterCell emitterCell];
    flare.contents = (__bridge id)img;
    flare.emissionLongitude = (4 * M_PI) / 2;
    flare.scale = 0.4;
    flare.velocity = 100;
    flare.birthRate = 45;
    flare.lifetime = 1.5;
    flare.yAcceleration = -350;
    flare.emissionRange = M_PI / 7;
    flare.alphaSpeed = -0.7;
    flare.scaleSpeed = -0.1;
    flare.scaleRange = 0.1;
    flare.beginTime = 0.01;
    flare.duration = 0.7;

    //The particles that make up the explosion
    CAEmitterCell *firework = [CAEmitterCell emitterCell];
    firework.contents = (__bridge id)img;
    firework.birthRate = 9999;
    firework.scale = 0.6;
    firework.velocity = 130;
    firework.lifetime = 2;
    firework.alphaSpeed = -0.2;
    firework.yAcceleration = -80;
    firework.beginTime = 1.5;
    firework.duration = 0.1;
    firework.emissionRange = 2 * M_PI;
    firework.scaleSpeed = -0.1;
    firework.spin = 2;

    //Name the cell so that it can be animated later using keypath
    firework.name = @"firework";

    //preSpark is an invisible particle used to later emit the spark
    CAEmitterCell *preSpark = [CAEmitterCell emitterCell];
    preSpark.birthRate = 80;
    preSpark.velocity = firework.velocity * 0.70;
    preSpark.lifetime = 1.7;
    preSpark.yAcceleration = firework.yAcceleration * 0.85;
    preSpark.beginTime = firework.beginTime - 0.2;
    preSpark.emissionRange = firework.emissionRange;
    preSpark.greenSpeed = 100;
    preSpark.blueSpeed = 100;
    preSpark.redSpeed = 100;

    //Name the cell so that it can be animated later using keypath
    preSpark.name = @"preSpark";

    //The 'sparkle' at the end of a firework
    CAEmitterCell *spark = [CAEmitterCell emitterCell];
    spark.contents = (__bridge id)img;
    spark.lifetime = 0.05;
    spark.yAcceleration = -250;
    spark.beginTime = 0.8;
    spark.scale = 0.4;
    spark.birthRate = 10;

    preSpark.emitterCells = @[spark];
    rocket.emitterCells = @[flare, firework, preSpark];
    mortor.emitterCells = @[rocket];
    [rootLayer addSublayer:mortor];

    //Set the view's layer to the base layer
    theView.layer = rootLayer;
    [theView setWantsLayer:YES];

    //Force the view to update
    [theView setNeedsDisplay:YES];

具体效果:

Flipagram特效参数分析

粒子效果的参数非常多,要实现和Flipagram一样的效果,设置参数是一件非常繁琐的事情,借用粒子效果的工具分析了一种类似效果的具体参数,主要包含4个方面的参数:发射机、粒子、色彩、纹理 16个发射机参数(截取部分显示):

10个粒子参数(截取部分显示):

12个色彩参数(截取部分显示):

纹理设置:

小结:通过类似粒子效果的参数分析,发现系统接口的参数比较少,根本实现不了这种稍微复杂一点的效果。

逆向分析

UI层级分析

通过分析Flipagram的涂鸦页面的UI层级,发现和涂鸦渲染层的类是FGDrawControlsView

相关类

通过反汇编分析了和渲染层FGDrawControlsView相关的主要类:FGDrawEnginePathFactoryFGDrawEnginePathFGDrawEngine

FGDrawEnginePathFactory是一个负责创建具体特效路径的工厂类,比如:烟花效果的路径、不同画刷的路径、表情效果的路径、沙子效果的路径等等。 FGDrawEnginePath设置粒子发射机的特性和粒子特效参数,比如:颜色、画刷参数、弧度等,同时维护了一条路径的矢量点阵信息。 FGDrawEngine内部利用了OpenGL把发射机参数、粒子效果参数、色彩参数、纹理参数的具体效果渲染出来。

小结

IOS自带的粒子效果使用比较简单,但是效果也比较单一,很难实现酷炫的效果。Flipagram的涂鸦特效实现是在手指移动的过程中创建不同效果的粒子发射机,粒子发射机发射不同效果的粒子。其中FGDrawEnginePath主要负责管理路径和特效信息,FGDrawEngine负责渲染具体的效果。

后续工作

继续分析FGDrawEngine的内部接口,利用OpenGL实现一个粒子特效引擎,最终实现Flipagram的涂鸦特效。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏学海无涯

iOS开发之扫描二维码

自iOS7以后,iOS扫描二维码不需要借助于第三方框架了,苹果在AVFoundation中原生支持了扫描二维码的API,主要涉及到5个类,这5个类在自定义相机或...

2734
来自专栏wOw的Android小站

[iOS] 列表滑动展开隐藏头部HeaderView

首先看一下BiliBili客户端的视频浏览界面。默认界面Header完全展开,并且Header显示AV号(别乱想,就是视频编号了)以及播放按钮。滑动之后Head...

812
来自专栏Jerry的SAP技术分享

Kubernetes里的ConfigMap的用途

顾名思义,ConfigMap用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。

351
来自专栏岑志军的专栏

iOS广告启动页

1445
来自专栏FreeBuf

FIT 2016集锦 | 解锁iOS手势密码的正确姿势

刚刚过去的FreeBuf互联网安全创新大会(FIT)中,平安科技银河实验室安全研究员姜若芾带来的“解锁iOS手势密码”的议题尤为吸睛。 什么是手势密码? 手势密...

2098
来自专栏向治洪

android自定义view实现公章效果

上次去一个公司面试,面试官问了一个题,怎么用android的自定义view实现一个公章的效果,据说这是华为之前的面试题,我想了下,要是公章的效果,最外层是一个圆...

2105
来自专栏鬼谷君

12-部署EFK插件

1842
来自专栏DannyHoo的专栏

iOS开发中利用UICollectionView创建文字轮播控件

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010105969/article/details/...

592
来自专栏xx_Cc的学习总结专栏

六天完成一个简单iOS App - 第二天

2695
来自专栏编程之旅

iOS开发——制作圆形头像

在iOS7之后,我们能发现许多应用都开始使用圆形来作为用户头像的形状,代表App就是腾讯QQ了,QQ的头像就是圆形的。

442

扫码关注云+社区