##关于贝赛尔曲线
####首先关于贝赛尔曲线的点的问题(二阶):
主要用的是: public void quadTo(float x,float y,float x1,float y1) 方法
参数说明:
(x,y):代表控制点的坐标.
(x1,y1):代表曲线终点的坐标
####坐标的分布: 坐标原点是在 出发点 ,然后上面为负坐标 左侧为负方向
(有点不敢证实,待分析.....)
####核心代码:
实现从一个点开始,到另外一个点的贝赛尔曲线,其中包含一些动画效果:
包括缩放和透明度的动画:
activity 代码:
private ImageButton imageButton;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageButton = (ImageButton) findViewById(R.id.imagebtn);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(this);
}
private float getScale(ImageView target) {
return 2f;
}
@Override
public void onClick(View view) {
imageButton.setVisibility(View.VISIBLE);
ViewPath path = new ViewPath(); //偏移坐标
path.moveTo(0, 0);
path.quadTo(200, -800, 500, 10);
ObjectAnimator anim = ObjectAnimator.ofObject(this, "fabLoc", new ViewPathEvaluator(), path.getPoints().toArray());
addAnimation(anim, imageButton);
}
private void addAnimation(ObjectAnimator animator1, ImageButton target) {
ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f,1, 0.01f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, 1, getScale(target), 1.0f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 1, getScale(target), 1.0f);
AnimatorSet all2 = new AnimatorSet();
all2.setDuration(4800);
all2.playTogether(alpha, scaleX, scaleY, animator1);
all2.addListener(new AnimEndListener(target));
all2.start();
}
private class AnimEndListener extends AnimatorListenerAdapter {
private View target;
public AnimEndListener(View target) {
this.target = target;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
target.setVisibility(View.GONE);
}
@Override
public void onAnimationResume(Animator animation) {
super.onAnimationResume(animation);
}
}
public void setFabLoc(ViewPoint newLoc) {
imageButton.setTranslationX(newLoc.x);
imageButton.setTranslationY(newLoc.y);
}
ViewPath.java 贝赛尔曲线 路径的集合
public class ViewPoint {
public float x;
public float y;
float x1, y1;
float x2, y2;
int operation;
public ViewPoint(float x, float y) {
this.x = x;
this.y = y;
}
public static ViewPoint moveTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint lineTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint curveTo(float x, float y, float x1, float y1, float x2, float y2, int operation) {
return new ViewPoint(x, y, x1, y1, x2, y2, operation);
}
public static ViewPoint quadTo(float x, float y, float x1, float y1, int operation) {
return new ViewPoint(x, y, x1, y1, operation);
}
private ViewPoint(float x, float y, int operation) {
this.x = x;
this.y = y;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.operation = operation;
}
}
ViewPathEvaluator.java:
public class ViewPathEvaluator implements TypeEvaluator<ViewPoint> {
// 自定义估值器:ViewPathEvaluator
public ViewPathEvaluator() {
}
@Override
public ViewPoint evaluate(float t, ViewPoint startValue, ViewPoint endValue) {
// 返回一个路径信息,其中包含偏移坐标x和偏移坐标y。
// 【返回用于反射调用setFabLoc时函数的传参】、
// startValue:前一个操作路径 endValue:后一个操作路径 t:操作进度(0->1)
// startValue和endValue为传入的路径集合数组中相邻的两个路径
float x ,y;
float startX,startY;
//分情况进行判断,计算出返回的偏移坐标:
if(endValue.operation == ViewPath.LINE){
//起点判断:
startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
startX = (startValue.operation == ViewPath.CURVE)?startValue.x2:startX;
startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;
startY = (startValue.operation == ViewPath.CURVE)?startValue.y2:startY;
//返回的偏移坐标计算:根据公式
x = startX + t * (endValue.x - startX);
y = startY+ t * (endValue.y - startY);
}else if(endValue.operation == ViewPath.CURVE){
//起点判断:
startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;
float oneMinusT = 1 - t;
//返回的偏移坐标计算:根据公式
x = oneMinusT * oneMinusT * oneMinusT * startX +
3 * oneMinusT * oneMinusT * t * endValue.x +
3 * oneMinusT * t * t * endValue.x1+
t * t * t * endValue.x2;
y = oneMinusT * oneMinusT * oneMinusT * startY +
3 * oneMinusT * oneMinusT * t * endValue.y +
3 * oneMinusT * t * t * endValue.y1+
t * t * t * endValue.y2;
}else if(endValue.operation == ViewPath.MOVE){
x = endValue.x;
y = endValue.y;
}else if(endValue.operation == ViewPath.QUAD){
//起点判断:
startX = (startValue.operation==ViewPath.CURVE)?startValue.x2:startValue.x;
startY = (startValue.operation==ViewPath.CURVE)?startValue.y2:startValue.y;
//返回的偏移坐标计算:根据公式
float oneMinusT = 1 - t;
x = oneMinusT * oneMinusT * startX +
2 * oneMinusT * t * endValue.x +
t * t * endValue.x1;
y = oneMinusT * oneMinusT * startY +
2 * oneMinusT * t * endValue.y +
t * t * endValue.y1;
}else {
// 其他
x = endValue.x;
y = endValue.y;
}
return new ViewPoint(x,y);
}
}
ViewPoint.java:贝赛尔曲线的路径信息
public class ViewPoint {
public float x;
public float y;
float x1, y1;
float x2, y2;
int operation;
public ViewPoint(float x, float y) {
this.x = x;
this.y = y;
}
public static ViewPoint moveTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint lineTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint curveTo(float x, float y, float x1, float y1, float x2, float y2, int operation) {
return new ViewPoint(x, y, x1, y1, x2, y2, operation);
}
public static ViewPoint quadTo(float x, float y, float x1, float y1, int operation) {
return new ViewPoint(x, y, x1, y1, operation);
}
private ViewPoint(float x, float y, int operation) {
this.x = x;
this.y = y;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.operation = operation;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="@+id/imagebtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:background="@drawable/imgbg"
android:padding="14dp"
android:scaleType="centerInside"
android:src="@drawable/stop" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="查看动画" />
</RelativeLayout>
#### 参考链接:
http://blog.csdn.net/cxmscb/article/details/52485878
http://www.2cto.com/kf/201604/497130.html
https://github.com/diamondlin2016/LauncherView
http://www.jianshu.com/p/138ad32540ce
http://blog.csdn.net/tyk0910/article/details/51626828
####首先关于贝赛尔曲线的点的问题(二阶):
主要用的是: public void quadTo(float x,float y,float x1,float y1) 方法
参数说明:
(x,y):代表控制点的坐标.
(x1,y1):代表曲线终点的坐标
####坐标的分布: 坐标原点是在 出发点 ,然后上面为负坐标 左侧为负方向
(有点不敢证实,待分析.....)
####核心代码:
实现从一个点开始,到另外一个点的贝赛尔曲线,其中包含一些动画效果:
包括缩放和透明度的动画:
activity 代码:
private ImageButton imageButton;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageButton = (ImageButton) findViewById(R.id.imagebtn);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(this);
}
private float getScale(ImageView target) {
return 2f;
}
@Override
public void onClick(View view) {
imageButton.setVisibility(View.VISIBLE);
ViewPath path = new ViewPath(); //偏移坐标
path.moveTo(0, 0);
path.quadTo(200, -800, 500, 10);
ObjectAnimator anim = ObjectAnimator.ofObject(this, "fabLoc", new ViewPathEvaluator(), path.getPoints().toArray());
addAnimation(anim, imageButton);
}
private void addAnimation(ObjectAnimator animator1, ImageButton target) {
ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f,1, 0.01f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, 1, getScale(target), 1.0f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 1, getScale(target), 1.0f);
AnimatorSet all2 = new AnimatorSet();
all2.setDuration(4800);
all2.playTogether(alpha, scaleX, scaleY, animator1);
all2.addListener(new AnimEndListener(target));
all2.start();
}
private class AnimEndListener extends AnimatorListenerAdapter {
private View target;
public AnimEndListener(View target) {
this.target = target;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
target.setVisibility(View.GONE);
}
@Override
public void onAnimationResume(Animator animation) {
super.onAnimationResume(animation);
}
}
public void setFabLoc(ViewPoint newLoc) {
imageButton.setTranslationX(newLoc.x);
imageButton.setTranslationY(newLoc.y);
}
ViewPath.java 贝赛尔曲线 路径的集合
public class ViewPoint {
public float x;
public float y;
float x1, y1;
float x2, y2;
int operation;
public ViewPoint(float x, float y) {
this.x = x;
this.y = y;
}
public static ViewPoint moveTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint lineTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint curveTo(float x, float y, float x1, float y1, float x2, float y2, int operation) {
return new ViewPoint(x, y, x1, y1, x2, y2, operation);
}
public static ViewPoint quadTo(float x, float y, float x1, float y1, int operation) {
return new ViewPoint(x, y, x1, y1, operation);
}
private ViewPoint(float x, float y, int operation) {
this.x = x;
this.y = y;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.operation = operation;
}
}
ViewPathEvaluator.java:
public class ViewPathEvaluator implements TypeEvaluator<ViewPoint> {
// 自定义估值器:ViewPathEvaluator
public ViewPathEvaluator() {
}
@Override
public ViewPoint evaluate(float t, ViewPoint startValue, ViewPoint endValue) {
// 返回一个路径信息,其中包含偏移坐标x和偏移坐标y。
// 【返回用于反射调用setFabLoc时函数的传参】、
// startValue:前一个操作路径 endValue:后一个操作路径 t:操作进度(0->1)
// startValue和endValue为传入的路径集合数组中相邻的两个路径
float x ,y;
float startX,startY;
//分情况进行判断,计算出返回的偏移坐标:
if(endValue.operation == ViewPath.LINE){
//起点判断:
startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
startX = (startValue.operation == ViewPath.CURVE)?startValue.x2:startX;
startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;
startY = (startValue.operation == ViewPath.CURVE)?startValue.y2:startY;
//返回的偏移坐标计算:根据公式
x = startX + t * (endValue.x - startX);
y = startY+ t * (endValue.y - startY);
}else if(endValue.operation == ViewPath.CURVE){
//起点判断:
startX = (startValue.operation==ViewPath.QUAD)?startValue.x1:startValue.x;
startY = (startValue.operation==ViewPath.QUAD)?startValue.y1:startValue.y;
float oneMinusT = 1 - t;
//返回的偏移坐标计算:根据公式
x = oneMinusT * oneMinusT * oneMinusT * startX +
3 * oneMinusT * oneMinusT * t * endValue.x +
3 * oneMinusT * t * t * endValue.x1+
t * t * t * endValue.x2;
y = oneMinusT * oneMinusT * oneMinusT * startY +
3 * oneMinusT * oneMinusT * t * endValue.y +
3 * oneMinusT * t * t * endValue.y1+
t * t * t * endValue.y2;
}else if(endValue.operation == ViewPath.MOVE){
x = endValue.x;
y = endValue.y;
}else if(endValue.operation == ViewPath.QUAD){
//起点判断:
startX = (startValue.operation==ViewPath.CURVE)?startValue.x2:startValue.x;
startY = (startValue.operation==ViewPath.CURVE)?startValue.y2:startValue.y;
//返回的偏移坐标计算:根据公式
float oneMinusT = 1 - t;
x = oneMinusT * oneMinusT * startX +
2 * oneMinusT * t * endValue.x +
t * t * endValue.x1;
y = oneMinusT * oneMinusT * startY +
2 * oneMinusT * t * endValue.y +
t * t * endValue.y1;
}else {
// 其他
x = endValue.x;
y = endValue.y;
}
return new ViewPoint(x,y);
}
}
ViewPoint.java:贝赛尔曲线的路径信息
public class ViewPoint {
public float x;
public float y;
float x1, y1;
float x2, y2;
int operation;
public ViewPoint(float x, float y) {
this.x = x;
this.y = y;
}
public static ViewPoint moveTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint lineTo(float x, float y, int operation) {
return new ViewPoint(x, y, operation);
}
public static ViewPoint curveTo(float x, float y, float x1, float y1, float x2, float y2, int operation) {
return new ViewPoint(x, y, x1, y1, x2, y2, operation);
}
public static ViewPoint quadTo(float x, float y, float x1, float y1, int operation) {
return new ViewPoint(x, y, x1, y1, operation);
}
private ViewPoint(float x, float y, int operation) {
this.x = x;
this.y = y;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.operation = operation;
}
public ViewPoint(float x, float y, float x1, float y1, float x2, float y2, int operation) {
this.x = x;
this.y = y;
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.operation = operation;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageButton
android:id="@+id/imagebtn"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerVertical="true"
android:background="@drawable/imgbg"
android:padding="14dp"
android:scaleType="centerInside"
android:src="@drawable/stop" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:text="查看动画" />
</RelativeLayout>
#### 参考链接:
http://blog.csdn.net/cxmscb/article/details/52485878
http://www.2cto.com/kf/201604/497130.html
https://github.com/diamondlin2016/LauncherView
http://www.jianshu.com/p/138ad32540ce
http://blog.csdn.net/tyk0910/article/details/51626828