滲透理解Animation時間插值Interpolator類,interpolator

來源:互聯網
上載者:User

滲透理解Animation時間插值Interpolator類,interpolator

========================================================
作者:qiujuer
部落格:blog.csdn.net/qiujuer
網站:www.qiujuer.net
開源庫:Genius-Android
轉載請註明出處:http://blog.csdn.net/qiujuer/article/details/42430269
========================================================

  • 一個好的動畫一定是用心做出來的,何為用心?其中一點我認為定義適當的 Interpolator 就是一種用心的表現;這點在 google material design 中尤為明顯。
  • 一個好的動畫一定要符合實際,一句老的話就是:石頭下落一定要受重力才優雅,不然一顆石頭像羽毛一樣在風中還飄啊飄的那就不行了。

介紹Interpolator 是個什麼東西?

說到 Interpolator 啊,這個要從3年前說起,話說當年Google、諾基亞、Qiujuer 三分天下.... 哈哈,開個玩笑~

Interpolator 這個時間插值類,其主要使用在動畫中,其作用主要是控制目標變數的變化值進行對應的變化。

你可以這麼理解,現在小明去買醬油,規定時間是1個小時到達,裡程是1公裡;現在小明心裡唯恐無法達到,所以先跑起來了,但因為體力消耗所以逐漸的慢下來了;然後成功到達。這樣的一個過程中把小明逐漸慢下來的這個過程抽象出來也就是 Interpolator  的工作;當然 Interpolator 也可以控制小明先慢慢熱身然後越跑越快最後達到。

這些都是 Interpolator 能完成的工作,同樣 Interpolator 還能控制一個彈球掉在地上彈起來逐漸降低的過程,這些都是可以控制的。

Interpolator 的原理?

public interface Interpolator extends TimeInterpolator {}
可以看見這個類其是是一個空的類,那麼其操作在哪裡?

/** * A time interpolator defines the rate of change of an animation. This allows animations * to have non-linear motion, such as acceleration and deceleration. */public interface TimeInterpolator {    /**     * Maps a value representing the elapsed fraction of an animation to a value that represents     * the interpolated fraction. This interpolated value is then multiplied by the change in     * value of an animation to derive the animated value at the current elapsed animation time.     *     * @param input A value between 0 and 1.0 indicating our current point     *        in the animation where 0 represents the start and 1.0 represents     *        the end     * @return The interpolation value. This value can be more than 1.0 for     *         interpolators which overshoot their targets, or less than 0 for     *         interpolators that undershoot their targets.     */    float getInterpolation(float input);}
其操作在所繼承的介面中,在所繼承的介面中有一個方法 float getInterpolation(float input);

在這個方法中,傳入的值是一個0.0~1.0的值,返回值可以小於0.0也可以大於1.0。

你可以這麼理解:在Animation中時間是正常的走的,你設定了200ms,現在走到了100ms了,那麼按照線性來說現在應該是走了一半的路程也就是0.5;現在就把這0.5傳遞給Interpolator 讓 Interpolator 告訴我走到一半時間的時候此時小明在哪裡;這也就是 Interpolator 的原理。

常用類

哎呀我的天天啊,訪問不了Google就是麻煩,只能從源碼了:


Android 官方提供的就是這麼十種,是9種還是10種啊,沒有數錯吧。分別是:

源碼

這裡說幾個簡單的源碼

LinearInterpolator

@HasNativeInterpolatorpublic class LinearInterpolator implements Interpolator, NativeInterpolatorFactory {    public LinearInterpolator() {    }        public LinearInterpolator(Context context, AttributeSet attrs) {    }        public float getInterpolation(float input) {        return input;    }    /** @hide */    @Override    public long createNativeInterpolator() {        return NativeInterpolatorFactoryHelper.createLinearInterpolator();    }}
最簡單的一個由於是線性,所以直接返回。

DecelerateInterpolator

public class DecelerateInterpolator implements Interpolator, NativeInterpolatorFactory {    public DecelerateInterpolator() {    }    /**     * Constructor     *     * @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces     *        an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the     *        ease-out effect (i.e., it starts even faster and ends evens slower)     */    public DecelerateInterpolator(float factor) {        mFactor = factor;    }    public DecelerateInterpolator(Context context, AttributeSet attrs) {        this(context.getResources(), context.getTheme(), attrs);    }    /** @hide */    public DecelerateInterpolator(Resources res, Theme theme, AttributeSet attrs) {        TypedArray a;        if (theme != null) {            a = theme.obtainStyledAttributes(attrs, R.styleable.DecelerateInterpolator, 0, 0);        } else {            a = res.obtainAttributes(attrs, R.styleable.DecelerateInterpolator);        }        mFactor = a.getFloat(R.styleable.DecelerateInterpolator_factor, 1.0f);        a.recycle();    }    public float getInterpolation(float input) {        float result;        if (mFactor == 1.0f) {            result = (float)(1.0f - (1.0f - input) * (1.0f - input));        } else {            result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));        }        return result;    }    private float mFactor = 1.0f;    /** @hide */    @Override    public long createNativeInterpolator() {        return NativeInterpolatorFactoryHelper.createDecelerateInterpolator(mFactor);    }}
從其中可以看出,其並不是一個簡單的類,其是是可以通過 XML 進行設定的類,通過 XML 可以設定其中的 mFactor 變數,其值預設是1.0;值越大其變化越快;得到的結果就是,開始的時候更加的快,其結果就是更加的慢,好比一個人開始跑的很快,但是換來的就是後面的路程將會花更多時間慢慢走。

在方法

    public float getInterpolation(float input) {        float result;        if (mFactor == 1.0f) {            result = (float)(1.0f - (1.0f - input) * (1.0f - input));        } else {            result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));        }        return result;    }
其描述的是一個初中學的拋物方程(話說是初中吧),y = x^2 我擦不知道怎麼弄上去,就這樣吧;意思懂就OK。

由於篇幅就說這麼兩個;下面說說其他東西。

動畫表


這個圖片相信前段時間看的不少吧?前段時間 material design 剛剛出來的時候好多人說這個啊,但是好像都是說圖,但是沒有說說其如何?吧。

實現

這裡送上福利,其是最開始我發現的是 C++ 的版本:

float Elastic::easeIn (float t,float b , float c, float d) { if (t==0) return b;  if ((t/=d)==1) return b+c;   float p=d*.3f; float a=c;  float s=p/4; float postFix =a*pow(2,10*(t-=1)); // this is a fix, again, with post-increment operators return -(postFix * sin((t*d-s)*(2*PI)/p )) + b;} float Elastic::easeOut(float t,float b , float c, float d) { if (t==0) return b;  if ((t/=d)==1) return b+c;   float p=d*.3f; float a=c;  float s=p/4; return (a*pow(2,-10*t) * sin( (t*d-s)*(2*PI)/p ) + c + b); } float Elastic::easeInOut(float t,float b , float c, float d) { if (t==0) return b;  if ((t/=d/2)==2) return b+c;  float p=d*(.3f*1.5f); float a=c;  float s=p/4;  if (t < 1) { float postFix =a*pow(2,10*(t-=1)); // postIncrement is evil return -.5f*(postFix* sin( (t*d-s)*(2*PI)/p )) + b; }  float postFix =  a*pow(2,-10*(t-=1)); // postIncrement is evil return postFix * sin( (t*d-s)*(2*PI)/p )*.5f + c + b;}
參數的意思:

  • t – 動畫中當前的時間
  • b – 開始值
  • c – 結束值
  • d – 動畫的總時間
看看 Java 的 第一行前三個的:

public class Sine {public static float  easeIn(float t,float b , float c, float d) {return -c * (float)Math.cos(t/d * (Math.PI/2)) + c + b;}public static float  easeOut(float t,float b , float c, float d) {return c * (float)Math.sin(t/d * (Math.PI/2)) + b;}public static float  easeInOut(float t,float b , float c, float d) {return -c/2 * ((float)Math.cos(Math.PI*t/d) - 1) + b;}}
雖然 Java 的也有了,但是話說這個怎麼用啊,跟上面的Interpolator如何聯絡起來啊?

一個簡單的方法:首先把 d 總時間設定為固定值 1.0 ,把 b 開始值設定為 0.0 把結束值設定為1.0,然後把 t 當作上面 Interpolator 中的 float getInterpolation(float input);傳入值,此時不就能用上了?對不?

舉個Case

/** * Created by Qiujuer on 2015/1/5. */public class InSineInterpolator implements Interpolator{    public static float  easeIn(float t,float b , float c, float d) {        return -c * (float)Math.cos(t/d * (Math.PI/2)) + c + b;    }    @Override    public float getInterpolation(float input) {        return easeIn(input, 0, 1, 1);    }}
使用

        //AnimatorSet        mAnimatorSet = new AnimatorSet();        mAnimatorSet.playTogether(aPaintX, aPaintY, aRadius, aBackground);        mAnimatorSet.setInterpolator(new InSineInterpolator());        mAnimatorSet.start();
可以看出使用與上面 Android 內建的完全一樣,當然這個只是一個 Case ,具體使用中你可以隨意封裝,前提是別改動了主要部分。


好了,完成了,擦又是三個小時過去了,我的 LOL 又沒法打了。

最後送上福利,全部的實作類別:



Animation Interpolator.zip

願大家都能做出自己滿意的動畫!


——學之開源,用於開源;初學者的心態,與君共勉!

========================================================
作者:qiujuer
部落格:blog.csdn.net/qiujuer
網站:www.qiujuer.net
開源庫:Genius-Android
轉載請註明出處:http://blog.csdn.net/qiujuer/article/details/42430269
========================================================

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.