史上最全的貝塞爾曲線(Bezier)全解(三):貝塞爾曲線實現滿屏愛心

這一篇文章會完整的介紹如何通過貝塞爾曲線實現愛心點贊的效果,如果實在看不懂,可以看第一篇貝塞爾曲線的簡介,還有第二篇安卓中的簡單使用;

好了,終于到了放大招的時候了,真實憋了很久了


這里寫圖片描述
這里寫圖片描述

先做一些準備工作,繪制各種顏色的紅心:

  private Bitmap creatHeart(int color) {

   int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Bitmap newBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(newBitmap);
        canvas.drawBitmap(bitmap, 0, 0, criPaint);
        canvas.drawColor(color, PorterDuff.Mode.SRC_ATOP);
        canvas.setBitmap(null);
        return newBitmap;

這里面比較關鍵的代碼只有是 canvas.drawColor(color, PorterDuff.Mode.SRC_ATOP),關于PorterDuff,還是可以去學習了解一下的,很多時候還是很有用的,在這里簡單的介紹一下;


這里寫圖片描述
這里寫圖片描述

這樣就比較清晰明了了吧,這里使用的就是SRC_ATOP,去心的圖形和顏色重疊部分,就是心了;
這樣只要準備一個心形圖片,就能實現格式各樣的心了;

接下來就是進行根據軌跡進行繪制了,看過第一篇文章的,就應該根據幾個點,就能繪制出來一條軌跡;這里使用屬性動畫,來獲取相對應的軌跡;

首先

 /**
     * 繪制一個增值器
     */
    class TypeE implements TypeEvaluator<PointF> {

        private PointF pointFFirst,pointFSecond;

        public TypeE(PointF start,PointF end){
            this.pointFFirst =start;
            this.pointFSecond = end;
        }

        @Override
        public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
            PointF result = new PointF();
            float left = 1 - fraction;
            result.x = (float) (startValue.x*Math.pow(left,3)+3*pointFFirst.x*Math.pow(left,2)*fraction+3*pointFSecond.x*Math.pow(fraction, 2)*left+endValue.x*Math.pow(fraction,3));
            result.y= (float) (startValue.y*Math.pow(left,3)+3*pointFFirst.y*Math.pow(left,2)*fraction+3*pointFSecond.y*Math.pow(fraction, 2)*left+endValue.y*Math.pow(fraction,3));
            return result;
        }
    }

這個很簡單,就是單純的使用公式了,所以說想要繪制復雜的軌跡,我還是要重新拾起來被扔進糞坑的小學數學課本重新看看,當真是熏得淚流滿面啊!!
接下來就很簡單了,只要不停使用屬性動畫,不斷變換位置就好了;

private void moveHeart(final ImageView view){
        PointF pointFFirst = this.pointFFirst;
        PointF pointFSecond = this.pointFSecond;
        PointF pointFStart = this.pointFStart;
        PointF pointFEnd = this.pointFEnd;


        ValueAnimator animator = ValueAnimator.ofObject(new TypeE(pointFFirst, pointFSecond), pointFStart, pointFEnd);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF value = (PointF) animation.getAnimatedValue();
                view.setX(value.x);
                view.setY(value.y);
            }
        });

        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                AdvancePathView.this.removeView(view);
            }
        });

        ObjectAnimator af = ObjectAnimator.ofFloat(view, "alpha", 1f, 0);
        af.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                AdvancePathView.this.removeView(view);
            }
        });

       AnimatorSet set = new AnimatorSet();
        set.setDuration(3000);
        set.play(animator).with(af);
        set.start();

    }

就是這么簡單,完全沒有難度啊有木有!!!
總的來說還是三步:
第一

  1. :繪制各種顏色的心
  2. 繪制一個增值器,獲取軌跡
  3. 使用屬性動畫,根據軌跡移動位置

好了,到這里我這一系列的文章就結束了,兩天水時間搞的,感覺稍微有點水,但是就這樣啦,畢竟本身不是很難的東西,有什么問題可以問我,有時間一定會耐心解答的;

最后附上源碼:https://github.com/sangxiaonian/BezierIntroduce.git

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容