这交互炸了(三):闪屏页是像云同样消失的

《交互炸了》或许是一系列高端特效教程, 文中会介绍一些比较炫酷的特效,以及实现的思路。特效实现自己也许不会有太大的难度。难点在于实现的思路。一旦思路被打开,特效将很简单实现。java

效果项目地址: https://github.com/githubwing/WowSplashgit

本期是第三期,第二期作的比较草率,好像并不太符合“交互炸了”这一主题,因此之后我会保证质量,而不是为了跟进数量凑数。此次给你们分享的效果是一个闪屏页的效果,效果以下:github

有没有眼前一亮?如今许多炫酷的闪屏页或者引导页喜欢用视频来作,可是我偏不,缘由有两个:canvas

1.视频会增长App体积,为了这一个闪屏页,多增长用户下载流量,这是很恶心的一件事情。

2.第二段云扩散融合效果,视频实现起来比较棘手。

动效制做思路发散

前面一篇跟你们分享了一写关于动画的小技巧。动画这种东西跟魔术同样,只要用户看的开心,怎么实现无所谓,因此作一些障眼法来取悦用户是没有问题的。这里的障眼法大概有以下几点:缓存

1.View放大不是真正的放大。markdown

2.View平移以后,可能悬浮在顶部的已经换成了一个如出一辙的双胞胎View。ide

3.比较特殊的如上面的效果,扩散并非View本身被扩散。工具

因此在作动效的时候,应该从一个魔术师的角度去考虑,而不能从用户的角度来考虑,作到思惟的发散。这里能够去看看一些魔术揭秘教程~作到看起来很炫酷,原理很简单,基本上动效的思路就有啦。post

WowSplash实现思路

咱们先把特效分为两段,一段为描边动画。另外一段为云雾扩散动画。首先来研究第一段。动画

第一阶段

第一段其实很简单,大部分小伙伴一眼就能够看出来,这就是SVG结合Path实现的动画。恩,对~你说的没错,网上有不少关于这种动画的实现,这里直接把须要的东西给到你们~

首先,你须要一张SVG图片,怎么得到呢,美工会配合我吗? 想多了,彻底不须要美工大大帮忙~咱们能够本身动手来。

首先须要用到一个神器: Vector Magic 他能够帮咱们把普通图片转换为SVG图片。这里我就找来了一张铁塔的简笔画~ 转换以后,就能够获得SVG文件了~

其次,须要用到一个工具类,用于把SVG转换成Path.这里我直接拿了GAStudio哥的一个工具类:SvgPathParser 接下来,咱们把拿到的SVG保存在String.xml文件中待用~

接下来使用PathMeasure 来进行SVG转换后Path的绘制,具体的细节,请看源码~这里不过多阐述。

float stop = mLength * mAnimatorValue;
 mTowerPathMeasure.getSegment(0, stop, mTowerDst, true);
 canvas.drawPath(mTowerDst, mPaint);

铁塔完毕后,有点单调~ 咱们来给他绘制一些云彩~ 每一个云彩都是一个Path,因此画云彩只是绘制一些Path.

private void drawCould(Canvas canvas) {
    for (int i = 0; i < mCouldPaths.length; i++) {
      setupCouldPath(mCouldPaths[i], i);
      canvas.drawPath(mCouldPaths[i], mPaint);
    }
  }

最后,加上动画~ 让他不生硬。最后暴漏一个方法,在进入Activity的时候执行,第一个阶段就完成啦~

public void startAnimate() {

    restore();
    //start tower animate
    getTowerValueAnimator().start();

    //start could animate
    for (int i = 0; i < mCouldPaths.length; i++) {
      final ValueAnimator couldAnimator = getCouldValueAnimator(i);
      postDelayed(new Runnable() {
        @Override public void run() {
          couldAnimator.start();
        }
      }, mDuration / 2);
    }

    getTitleAnimate().start();
  }

第二阶段

第二阶段看起来比较炫,其实也是比较简单的,扩散很差搞,能够换一个思路嘛。因此这里我就想到使用Xfermode,没错,你看到发散的云,其实又是另外一张图片:

哈哈哈哈,这张图片一贴出来,你是否是想笑。原来看起来很炫的效果,真实这么搞笑。

好的,有了思路就很好继续了。我只须要让两个图片使用Xfermode搞基一番,而且在过程当中让这个View逐渐透明,遮罩图片逐渐放大便可。

固然,有了思路变成很简单,其实仍是有些坑的,说说遇到的坑。

关于Xfermode小伙伴们用到过的可能了解,他有坑,很是大的坑。。常常发现与Demo图出不来同样的效果。因此我专门总结了一篇博客以下:PorterDuffXferMode不正确的真正缘由,感兴趣的能够看下。这里再来重复下Xfermode坑如何避免。

最终大总结,若是想让PorterDuffXferMode按照预期Demo(或者效果图)的效果图像实现,必须知足如下条件:

一、关闭硬件加速。(实际为开启硬离屏缓存)

二、两个bitmap大小尽可能同样。

三、背景色为透明色。

四、若是两个bitmap位置不彻底同样,可能也是预期效果,只不过你看到的效果和你本身脑补的预期效果不一致。

因此,为了不这些坑,我把View分为了两个,第一阶段是一个View,第二阶段是一个View。当第一段View执行完以后,把该View截屏,转换为bitmap交给第二个View。同时第一个View设置gone来避免过分绘制,第二个View绘制的其实是两个bitmap,而且开启硬离屏缓存来实现Xfermode的正确效果。

//解决硬件加速的bug
setLayerType(View.LAYER_TYPE_HARDWARE, null);
//将第一个View的bitmap交给第二个View
mWowView.startAnimate(wowSplashView.getDrawingCache());

最后,在使用动画让第二个View从0扩大到数倍,同时改变透明度就达到咱们想要的效果了。

好啦,本期《交互炸了》到此就结束了,最后附上项目地址,若是你以为不错,欢迎star,关注我能够得到最新动态哦。

https://github.com/githubwing/WowSplash

相关文章
相关标签/搜索