购物车特效-贝塞尔曲线动画(点击添加按钮的进候,产生抛物线动画效果)

六月JuneJune 六月JuneJune     2022-08-26     372

关键词:

demo效果:




购物车特效原理:

1.从添加按钮获取开始坐标

2.从购物车图标获取结束坐标

3.打气一个视图,添加属性动画ObjectAnimator(缩小),ValueAnimator(路线)

4.动画开始时添加该视图,动画结束删除该视图

5.运动路径使用TypeEvaluator与贝塞尔函数计算


activity布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!--贝塞尔曲线动画自定义控件-->
    <custom.BezierAnim
        android:id="@+id/bezier_anim"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <!--添加按钮-->
    <Button
        android:id="@+id/bt_good"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_margin="10dp"
        android:text="+" />
    <!--购物车-->
    <ImageView
        android:id="@+id/iv_cart"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentBottom="true"
        android:src="@drawable/cart91" />
</RelativeLayout>


移动控件布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="50dp"
    android:layout_height="50dp"
    android:orientation="vertical">

    <ImageView
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:src="@drawable/coin91" />

</RelativeLayout>

贝塞尔曲线动画的自定义控件编写:

public class BezierAnim extends FrameLayout {
    public BezierAnim(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public BezierAnim(Context context) {
        this(context, null, 0);
    }

    public BezierAnim(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    //PointF等价于float[]数组,里面存放的x和y的值 (point相当于int[])
    private PointF mLocation = new PointF();//这样创建出来,里面还没有值

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        //获取当前父布局在界面的屏幕坐标(也就是父布局左上角坐标)
        int[] layoutLoc = new int[2];
        getLocationInWindow(layoutLoc);
        mLocation.set(layoutLoc[0], layoutLoc[1]);//将父布局左上角的值赋值给mLocation
    }

    /**
     * 开始贝塞尔动画
     *
     * @param startView    动画从哪个view开始(+号)
     * @param endView      动画在哪个view结束(购物车)
     * @param layoutIdMove 动画作用的移动控件(钱袋子的布局)
     */
    public void startCartAnim(View startView, View endView, int layoutIdMove) {
        //1,开始位置
        int[] startLoc = new int[2];
        startView.getLocationInWindow(startLoc);//获取当前view在屏幕上的坐标
        PointF startF = new PointF(startLoc[0] - mLocation.x, startLoc[1] - mLocation.y);//得到当前view相对于父布局左上角位置的坐标
        // 2,结束位置
        int[] endLoc = new int[2];
        endView.getLocationInWindow(endLoc);
        final PointF endF = new PointF(endLoc[0] - mLocation.x, endLoc[1] - mLocation.y);
        //3.移动控件。inflate()参数:作用布局,参考布局,false
        final View moveView = LayoutInflater.from(getContext()).inflate(layoutIdMove, this, false);
        //开始动画  使用属性动画合集
        AnimatorSet set = new AnimatorSet();
        //缩小动画
        ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(moveView, "scaleX", 1.0f, 0.1f);
        ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(moveView, "scaleY", 1.0f, 0.1f);
        //路径动画(baisaier曲线路径,开始坐标,结束坐标)
        ValueAnimator pathAnim = ObjectAnimator.ofObject(beisaier, startF, endF);
        pathAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //更新坐标
                PointF newPointF = (PointF) animation.getAnimatedValue();
                moveView.setX(newPointF.x);
                moveView.setY(newPointF.y);
            }
        });
        //将这些动画放入集合中
        set.playTogether(scaleXAnim, scaleYAnim, pathAnim);
        Animator.AnimatorListener listener = new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                BezierAnim.this.addView(moveView);//加入动画作用的控件
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                BezierAnim.this.removeView(moveView);//移除动画作用的控件
            }

            @Override
            public void onAnimationCancel(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
        };
        set.addListener(listener);//动画播放监听器
        set.setDuration(1000);  //运动时间
        set.start();            
    }

    //路径计算器
    private TypeEvaluator<PointF> beisaier = new TypeEvaluator<PointF>() {
        @Override
        public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
            //返回变化的轨迹坐标
            PointF newF = new PointF((startValue.x + endValue.x) / 2, 0);//控制点
            return BezierCurve.bezier(fraction, startValue, newF, endValue);
        }
    };
}


路径计算器:

public class BezierCurve {
    /**
     * 二次贝塞尔曲线插值
     * t:值范围from = 0, to = 1
     */
    public static PointF bezier(float t, PointF point0, PointF point1, PointF point2) {
        float oneMinusT = 1.0f - t;
        PointF point = new PointF();
        point.x = oneMinusT * oneMinusT * point0.x
                + 2 * t * oneMinusT * point1.x
                + t * t * point2.x;
        point.y = oneMinusT * oneMinusT * point0.y
                + 2 * t * oneMinusT * point1.y
                + t * t * point2.y;
        return point;
    }

    /**
     * 三次贝塞尔曲线插值
     * t:值范围from = 0, to = 1
     */
    public static PointF bezier(float t, PointF point0, PointF point1, PointF point2, PointF point3) {
        float oneMinusT = 1.0f - t;
        PointF point = new PointF();
        point.x = oneMinusT * oneMinusT * oneMinusT * (point0.x)
                + 3 * oneMinusT * oneMinusT * t * (point1.x)
                + 3 * oneMinusT * t * t * (point2.x)
                + t * t * t * (point3.x);

        point.y = oneMinusT * oneMinusT * oneMinusT * (point0.y)
                + 3 * oneMinusT * oneMinusT * t * (point1.y)
                + 3 * oneMinusT * t * t * (point2.y)
                + t * t * t * (point3.y);
        return point;
    }
}

activity开始动画:

public class CartBazierActivity extends Activity {
    @InjectView(R.id.bt_good)
    Button btGood;
    @InjectView(R.id.iv_cart)
    ImageView ivCart;
    @InjectView(R.id.bezier_anim)
    BezierAnim bezierAnim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cart_bezier);
        ButterKnife.inject(this);
    }

    @OnClick(R.id.bt_good)
    public void bezierMove() {
        Toast.makeText(this, "添加了一件商品", Toast.LENGTH_SHORT).show();
        bezierAnim.startCartAnim(btGood, ivCart, R.layout.moveview);
    }
}

若是startView和endView不在一个界面,可以用EventBus传值


更多:http://www.jb51.net/article/95991.htm



把商品添加到购物车的动画效果(贝塞尔曲线)

目录(?)[+]如图:参考:Android补间动画,属性动画实现购物车添加动画思路:确定动画的起终点在起终点之间使用二次贝塞尔曲线填充起终点之间的点的轨迹设置属性动画,ValueAnimator插值器,获取中间点的坐标将执行动画的控件... 查看详情

贝塞尔曲线实现的购物车添加商品动画效果

效果图如下:1.activity_main.xml<?xmlversion="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/rly_bezier_curve_shopping_cart"android:l 查看详情

css贝塞尔曲线模仿饿了么购物车小球动画

在线观看贝塞尔曲线值:传送门在线观看动画效果:传送门代码:<!DOCTYPEhtml><html><head><metacharset="utf-8"><metaname="viewport"content="width=device-width"><title>JSBin</title><style> 查看详情

【css动画】饿了么加入购物车抛物线动画实现

...肥宅,手动滑稽),或者在淘宝购物的时候,将商品加入购物车时会有一个很炫酷的动画,如下图饿了么点餐动画:所以百度了一下前端使用css实现这个效果,然后就自己就照葫芦画瓢的写了一个小小的demo,完全当作学习了一... 查看详情

安卓自定义view仿小米商城购物车动画

通过自定义View与ViewGroup实现小米商城购物车效果用到的知识点自定义View自定义ViewGroup贝塞尔曲线原理通过贝塞尔曲线实现商品抛入购物车的路径自定义ViewGroup实现添加多个商品进购物车的动画自定义View绘制心以及购物车图案代... 查看详情

安卓自定义view仿小米商城购物车动画

通过自定义View与ViewGroup实现小米商城购物车效果用到的知识点自定义View自定义ViewGroup贝塞尔曲线原理通过贝塞尔曲线实现商品抛入购物车的路径自定义ViewGroup实现添加多个商品进购物车的动画自定义View绘制心以及购物车图案代... 查看详情

替换产品类别的 Woocommerce 单一产品页面上的“添加到购物车”按钮

】替换产品类别的Woocommerce单一产品页面上的“添加到购物车”按钮【英文标题】:ReplaceAddtocartbuttononWoocommerceSingleProductPagesforaproductcategory【发布时间】:2018-08-0805:13:59【问题描述】:我正在尝试添加一个指向联系页面的自定义... 查看详情

删除 Woocommerce 中特定产品类别的添加购物车按钮

】删除Woocommerce中特定产品类别的添加购物车按钮【英文标题】:RemoveaddcartbuttoninWoocommerceforaspecificproductcategory【发布时间】:2017-05-3008:57:46【问题描述】:我对如何从类别产品中删除购物车有疑问。如果我将它应用到特定的id或... 查看详情

focusky教程|如何使用变体特效?

Focusky(也称为“FS软件”)的变体特效可以使图形呈动态变化,清晰地演示图形的变化过程,如变成圆形、圆角星、心形等等。具体操作步骤如下: 1.点击右侧工具栏的“图形”按钮,选择“变体”并选择其中一个变体图形... 查看详情

贝塞尔曲线实现购物车飞入效果(代码片段)

...www.demodashi.com/demo/12618.html前言做了一个模仿添加物品飞入购物车效果的例子,下面来讲讲它的简单使用将涉及到以下内容:工具类的使用项目结构图与效果图程序设计与实现一.工具类设计工具类比较多代码,这里就不每个都贴... 查看详情

tween缓动动画(代码片段)

在讲tween类之前,不得不提的是贝塞尔曲线了。首先,贝塞尔曲线是指依据四个位置任意的点坐标绘制出的一条光滑曲线。它在作图工具或动画中中运用得比较多,例如PS中的钢笔工具,firework中的画笔等等。无论运用在哪里,它... 查看详情

android自定义控件demo集合

...完成,俗称占个坑~持续更新中…github地址饿了么加入购物车按钮仿支付宝支付成功动画波浪效果进度条(正弦函数实现+贝塞尔曲线实现)竖排文字多功能按钮RoundLoadingView可自定义圆角、正常/点击/不可用时的背景... 查看详情

focusky教程|自定义动画运动路径

...件”)中,除了可以应用软件里自带的动画效果,如进入特效,强调特效,退出特效,还可以自定义一个对象由一个点按照一定的轨迹运动到另一点。 操作步骤如下: 1点击“动画”进入动画编辑页面。 【图1▲】&nbs... 查看详情

android自定义控件demo集合

...完成,俗称占个坑~持续更新中…github地址饿了么加入购物车按钮仿支付宝支付成功动画波浪效果进度条(正弦函数实现+贝塞尔曲线实现)竖排文字多功能按钮Roun 查看详情

iOS 动画贝塞尔曲线/正弦曲线

】iOS动画贝塞尔曲线/正弦曲线【英文标题】:iOSAnimatedBezier/SineCurve【发布时间】:2013-07-0818:56:18【问题描述】:我希望在iOS中的循环上为单线贝塞尔曲线制作动画。我脑海中的想法类似于Siri之前iPhone4上的语音控制屏幕。曲线不... 查看详情

android自定义view高级特效,神奇的贝塞尔曲线(代码片段)

...效果图效果图中我们实现了一个简单的随手指滑动的二阶贝塞尔曲线,还有一个复杂点的,穿越所有已知点的贝塞尔曲线。学会使用贝塞尔曲线后可以实现例如QQ红点滑动删除啦,360动态球啦,bulabulabula~什么是贝... 查看详情

为贝塞尔曲线的一个点设置动画[重复]

】为贝塞尔曲线的一个点设置动画[重复]【英文标题】:AnimateapointofaBeziercurve[duplicate]【发布时间】:2013-09-1319:05:32【问题描述】:是否可以为贝塞尔曲线的点设置动画?我正在尝试从直线平滑过渡到箭头。这是代码中该行的样... 查看详情

自定义特定 WooCommerce 产品类别上的“添加到购物车”按钮

】自定义特定WooCommerce产品类别上的“添加到购物车”按钮【英文标题】:CustomizeAddtoCartbuttononspecificWooCommerceproductcategories【发布时间】:2019-12-1313:05:20【问题描述】:我正在尝试将我的WooCommerce档案页面上特定产品类别的添加到... 查看详情