package com.hanks.htextview.animatetext;
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.OvershootInterpolator;

import com.hanks.htextview.util.CharacterUtils;
import com.hanks.htextview.util.HLog;
/**
 * 蒸发效果
 * Created by hanks on 15-12-14.
 */
public class FallText extends HText {

    float charTime   = 400; // 每个字符动画时间 500ms
    int   mostCount  = 20; // 最多10个字符同时动画
    float upDistance = 0;
    float progress;

    @Override protected void initVariables() {

    }

    @Override protected void animateStart(CharSequence text) {
        int n = mText.length();
        n = n <= 0 ? 1 : n;

        // 计算动画总时间
        long duration = (long) (charTime + charTime / mostCount * (n - 1));

        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, duration).setDuration(duration);
        valueAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {

            @Override public void onAnimationUpdate(ValueAnimator animation) {
                progress = (float) animation.getAnimatedValue();
                mHTextView.invalidate();
            }
        });
        valueAnimator.start();
    }

    @Override protected void animatePrepare(CharSequence text) {
        Rect bounds = new Rect();
        mPaint.getTextBounds(mText.toString(), 0, mText.length(), bounds);
        upDistance = bounds.height();
    }

    @Override protected void drawFrame(Canvas canvas) {

        float offset = startX;
        float oldOffset = oldStartX;

        int maxLength = Math.max(mText.length(), mOldText.length());

        for (int i = 0; i < maxLength; i++) {

            // draw old text
            if (i < mOldText.length()) {
                //
                float percent = progress / (charTime + charTime / mostCount * (mText.length() - 1));

                mOldPaint.setTextSize(mTextSize);
                int move = CharacterUtils.needMove(i, differentList);
                if (move != -1) {
                    mOldPaint.setAlpha(255);
                    float p = percent * 2f;
                    p = p > 1 ? 1 : p;
                    float distX = CharacterUtils.getOffset(i, move, p, startX, oldStartX, gaps, oldGaps);
                    canvas.drawText(mOldText.charAt(i) + "", 0, 1, distX, startY, mOldPaint);
                } else {

                    mOldPaint.setAlpha(255);
                    float centerX = oldOffset + oldGaps[i] / 2;
                    float width = mOldPaint.measureText(mOldText.charAt(i) + "");

                    float p = percent * 1.4f;
                    p = p > 1 ? 1 : p;
                    p = new OvershootInterpolator().getInterpolation(p);
                    double angle = (1 - p) * (Math.PI);
                    if (i % 2 == 0) {
                        angle = (p * Math.PI) + Math.PI;
                    }
                    float disX = centerX + (float) (width / 2 * Math.cos(angle));
                    float disY = startY + (float) (width / 2 * Math.sin(angle));
                    mOldPaint.setStyle(Paint.Style.STROKE);
                    Path path = new Path();
                    path.moveTo(disX, disY);
                    //求点A（m,n)关于点P(a,b)的对称点B(x,y)
                    // (m+x)/2=a ,x=2a-m
                    // (n+y)/2=b ,y=2b-n
                    path.lineTo(2 * centerX - disX, 2 * startY - disY);
                    if (percent <= 0.7) {
                        // 旋转
                        canvas.drawTextOnPath(mOldText.charAt(i) + "", path, 0, 0, mOldPaint);
                    } else {
                        // 下落
                        float p2 = (float) ((percent - 0.7) / 0.3f);
                        mOldPaint.setAlpha((int) ((1 - p2) * 255));
                        float y = (float) ((p2) * upDistance);
                        HLog.i(y);
                        Path path2 = new Path();
                        path2.moveTo(disX, disY + y);
                        path2.lineTo(2 * centerX - disX, 2 * startY - disY + y);
                        canvas.drawTextOnPath(mOldText.charAt(i) + "", path2, 0, 0, mOldPaint);
                    }

                }
                oldOffset += oldGaps[i];
            }

            // draw new text
            if (i < mText.length()) {

                if (!CharacterUtils.stayHere(i, differentList)) {

                    int alpha = (int) (255f / charTime * (progress - charTime * i / mostCount));
                    alpha = alpha > 255 ? 255 : alpha;
                    alpha = alpha < 0 ? 0 : alpha;

                    float size = mTextSize * 1f / charTime * (progress - charTime * i / mostCount);
                    size = size > mTextSize ? mTextSize : size;
                    size = size < 0 ? 0 : size;

                    mPaint.setAlpha(alpha);
                    mPaint.setTextSize(size);
                    float width = mPaint.measureText(mText.charAt(i) + "");
                    canvas.drawText(mText.charAt(i) + "", 0, 1, offset + (gaps[i] - width) / 2, startY, mPaint);
                }

                offset += gaps[i];
            }
        }
    }

}

@@ -412,10 +412,12 @@
 %0A * 
-%E8%92%B8%E5%8F%91
+%E6%82%AC%E6%8C%82%E5%9D%A0%E8%90%BD
 %E6%95%88%E6%9E%9C%0A 
@@ -491,24 +491,32 @@
 Text %7B%0A%0A    
+private 
 float charTi
@@ -520,16 +520,17 @@
 rTime   
+ 
 = 400; /
@@ -546,24 +546,32 @@
 %E9%97%B4 500ms%0A    
+private 
 int   mostCo
@@ -575,16 +575,17 @@
 tCount  
+ 
 = 20; //
@@ -605,24 +605,33 @@
     
-float upDistance
+private float mTextHeight
  = 0
@@ -632,24 +632,32 @@
 ht = 0;%0A    
+private 
 float progre
@@ -664,56 +664,155 @@
 ss;%0A
-%0A    @Override protected void initVariables() %7B%0A
+    private OvershootInterpolator interpolator;%0A%0A    @Override protected void initVariables() %7B%0A        interpolator = new OvershootInterpolator();
 %0A   
@@ -1727,26 +1727,27 @@
         
-upDistance
+mTextHeight
  = bound
@@ -2976,32 +2976,33 @@
  p %3E 1 ? 1 : p;%0A
+%0A
                 
@@ -3009,30 +3009,17 @@
     p = 
-new OvershootI
+i
 nterpola
@@ -3021,18 +3021,16 @@
 rpolator
-()
 .getInte
@@ -4149,18 +4149,19 @@
 ) * 
-upDistance
+mTextHeight
 );%0A 

format FallText