您的位置:首页 > 移动开发 > Android开发

android 饿了么 加入购物车动画(贝塞尔曲线绘制)

2016-08-25 11:39 791 查看
先看下效果吧


为什么要做这个

1,每天使用某订餐软件,加入购物车比较炫酷,加入的时候 加了一系列的动画,物品掉落到篮子里面。上网查证这个是贝塞尔曲线。
canvas中提供了绘制 贝塞尔曲线的方法,包括 二阶跟三阶的。但是 做动画效果,我们使用 红点代替物品,要让上面的红点动起来

其实 我是分了三部分去做的。

第一,绘制红点。这个大家都会

第二,让红点走个直线。

第三,直线改成贝塞尔曲线的路径


第一步 绘制红点 无非就是
canvas.drawCircle


第二,如何动起来 是关键,动起来的话 可以使用 属性动画。很多人都不明白 什么是属性动画 ,属性动画是如何使用

其实 我也是这两天才彻底的明白里面的真意。不要问我是怎么明白的,使用多了 突然就开窍了。

举个例子吧。比如说有个属性 t(这个东西后来会用到) 怎么让你的t用动画让他动起来。属性动画 是根据 t的 setter getter

方法在不同的动画阶段去设置值  既然你的 t 可以在不同的时间阶段获得的值不通,你完全可以去重新绘制
postInvalidate() 去重新绘制,绘制不同的位置。
看下代码吧
public float getT() {
return t;
}

public void setT(float t) {
Log.e("=====", t + "  ");
this.t = t;
postInvalidate();
}

private float t;

private ObjectAnimator animatorT = ObjectAnimator.ofFloat(this, "t", 0, 1);
这样的话 就可以 利用动画,获取不同的值,绘制动画
</pre><span style="font-family:Menlo;"><span style="font-size: 12pt;">利用这个 都是可变的 </span></span><pre style="font-family: Menlo; font-size: 12pt; background-color: rgb(255, 255, 255);"><span style="color:#000080;"><strong>public void </strong></span>drawCircle(<span style="color:#000080;"><strong>float </strong></span>cx, <span style="color:#000080;"><strong>float </strong></span>cy, <span style="color:#000080;"><strong>float </strong></span>radius, @NonNull Paint paint) 里面的参数cx,xy也是可以
利用动画去写的
现在已经可以动起来了
第三步 如何 按照 贝塞尔曲线走哪?这才是重点
Android 给的就是给我点,我去给你绘制,没有说 给我t 我给你返回 你所需要的点。
这里说明下,差了好多资料,好多博客没有博客是说,公式如何用,如何计算的,怎么给T 返回 X Y 的。统一 都是,
拿一样的图,说一样的话
索性  我就去看看维基百科 贴个地址吧 维基百科包含了所有的人的博客用的图 跟公式https://zh.wikipedia.org/wiki/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A
贴公式吧。
现在问题就出来了 这个公式我怎么看 P0 P1 P2 P3 又代表什么。B(t)又代表什么
P0 P1 P2 P3 是给定的四个点,这四个点我们是知道。 从P0 出发  趋近P1 P2 到达  在 android 中对应的 api 就是 move(P0) que(P1,P2,P3) 这个样子的。
当四个点 确定 四个点的坐标也是确定的 我们现在暂且认为 p0(x0,y0)...p3(x3,y3) 这样的一个顺序。那么 当给定t之后 获取到 确定的X x =x0*(1-t)^3+3*x1*t(1-t)^2+3*x2*t^2(1-t)+x3*t^3 获取 对应的 y坐标
只需要把X 换成Y 就可以。
这样的话 我们就可以根据公式 去推导出不同的T 下的X Y坐标,根据动画 从新去绘制 图标 让圆动起来。
维基百科 也给了 一个C 语言的推导公式 我这里改成了JAVA 的
private PointF PointOnCubicBezier(PointF[] pointFs, float t) {
double ax, bx, cx;
double ay, by, cy;
double tSquared, tCubed;
PointF result = new PointF();

/*計算多項式係數*/
cx = 4.0 * (pointFs[1].x - pointFs[0].x);
bx = 4.0 * (pointFs[2].x - pointFs[1].x) - cx;
ax = pointFs[3].x - pointFs[0].x - cx - bx;

cy = 4.0 * (pointFs[1].y - pointFs[0].y);
by = 4.0 * (pointFs[2].y - pointFs[1].y) - cy;
ay = pointFs[3].y - pointFs[0].y - cy - by;

/*計算位於參數值t的曲線點*/
tSquared = t * t;
tCubed = tSquared * t;

result.x = (float) ((ax * tCubed) + (bx * tSquared) + (cx * t) + pointFs[0].x);
result.y = (float) ((ay * tCubed) + (by * tSquared) + (cy * t) + pointFs[0].y);

return result;
}

没有解决的问题 我还没有很好的找到 某外卖平台的 约束点在哪里 为什么 这样定这个约束点。应该是个抛物线
贴下代码吧 git https://github.com/liqingju123/view (里面不止这一个效果)
不懂 企鹅:973683374 或者留言

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息