public class MainActivity extends AppCompatActivity {
private static final float mPointNum = 50f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
private void init() {
PointF mStartPoint = new PointF(0, 0);
PointF mEndPoint = new PointF(0, 1200);
PointF mControlPoint = new PointF(500, 600);
List<PointF> mPointList = new ArrayList<>();
for (int i = 0; i <= mPointNum; i++) {
mPointList.add(getBezierPoint(mStartPoint, mEndPoint, mControlPoint, i / mPointNum));
Log.d("Bezier", "X:" + mPointList.get(i).x + " Y:" + mPointList.get(i).y);
}
}
private PointF getBezierPoint(PointF start, PointF end, PointF control, float t) {
PointF bezierPoint = new PointF();
bezierPoint.x = (1 - t) * (1 - t) * start.x + 2 * t * (1 - t) * control.x + t * t * end.x;
bezierPoint.y = (1 - t) * (1 - t) * start.y + 2 * t * (1 - t) * control.y + t * t * end.y;
return bezierPoint;
}
}
//用递归获取贝塞尔曲线点的x轴坐标
private float getBezierPointX(int n, int position, float t) {
if (n == 1) {
return (1 - t) * mPointList.get(position).x + t * mPointList.get(position + 1).x;
}
return (1 - t) * getBezierPointX(n - 1, position, t) + t * getBezierPointX(n - 1, position + 1, t);
}
//用递归获取贝塞尔曲线点的x轴坐标
private float getBezierPointX(int n, int position, float t) {
if (n == 1) {
return (1 - t) * mPointList.get(position).x + t * mPointList.get(position + 1).x;
}
return (1 - t) * getBezierPointX(n - 1, position, t) + t * getBezierPointX(n - 1, position + 1, t);
}
private ArrayList<PointF> buildBezierPoints() {
ArrayList<PointF> points = new ArrayList<>();
int order = mPointList.size() - 1;
float delta = 1.0f / POINT_NUM;
for (float t = 0; t <= 1; t += delta) {
// Bezier点集
points.add(new PointF(getBezierPointX(order, 0, t), getBezierPointY(order, 0, t)));
}
return points;
}
canvas.drawLine(start.x,start.y,end.x,end.y);
mPath.moveTo(startPoint.x, startPoint.y);//起点 mPath.quadTo(controlPoint1.x, controlPoint1.y, endPoint.x, endPoint.y); canvas.drawPath(mPath, mPaint);
mPath.moveTo(startPoint.x, startPoint.y);//起点 mPath.cubicTo(controlPoint1.x, controlPoint1.y, controlPoint2.x, controlPoint2.y, endPoint.x, endPoint.y); canvas.drawPath(mPath, mPaint);
private float[] mData = new float[8]; // 顺时针记录绘制圆形的四个数据点 private float[] mCtrl = new float[16]; // 顺时针记录绘制圆形的八个控制点 private float mDuration = 1000; // 变化总时长 private float mCurrent = 0; // 当前已进行时长 private float mCount = 100; // 将时长总共划分多少份 private float mPiece = mDuration / mCount; // 每一份的时长
path.reset();
path.moveTo(mData[0], mData[1]);
path.cubicTo(mCtrl[0], mCtrl[1], mCtrl[2], mCtrl[3], mData[2], mData[3]);
path.cubicTo(mCtrl[4], mCtrl[5], mCtrl[6], mCtrl[7], mData[4], mData[5]);
path.cubicTo(mCtrl[8], mCtrl[9], mCtrl[10], mCtrl[11], mData[6], mData[7]);
path.cubicTo(mCtrl[12], mCtrl[13], mCtrl[14], mCtrl[15], mData[0], mData[1]);
canvas.drawPath(path, mPaint);
mCurrent += mPiece;
if (mCurrent < mDuration) {
mData[1] -= 120 / mCount;
mCtrl[7] += 80 / mCount;
mCtrl[9] += 80 / mCount;
mCtrl[4] -= 20 / mCount;
mCtrl[10] += 20 / mCount;
postInvalidateDelayed((long) mPiece);
}
public class BezierEvaluator implements TypeEvaluator<PointF> {
private PointF mControlP1;
private PointF mControlP2;
public BezierEvaluator(PointF controlP1, PointF controlP2) {
this.mControlP1 = controlP1;
this.mControlP2 = controlP2;
}
@Override
public PointF evaluate(float time, PointF start, PointF end) {
float timeLeft = 1.0f - time;
PointF point = new PointF();
point.x = timeLeft * timeLeft * timeLeft * (start.x) + 3 * timeLeft * timeLeft * time *
(mControlP1.x) + 3 * timeLeft * time *
time * (mControlP2.x) + time * time * time * (end.x);
point.y = timeLeft * timeLeft * timeLeft * (start.y) + 3 * timeLeft * timeLeft * time *
(mControlP1.y) + 3 * timeLeft * time *
time * (mControlP2.y) + time * time * time * (end.y);
return point;
}
}
private void init() {
// 初始化显示的图片
drawables = new Drawable[3];
drawables[0] = getResources().getDrawable(R.drawable.red);
drawables[1] = getResources().getDrawable(R.drawable.yellow);
drawables[2] = getResources().getDrawable(R.drawable.green);
// 初始化插补器
mInterpolators = new Interpolator[4];
mInterpolators[0] = new LinearInterpolator();// 线性
mInterpolators[1] = new AccelerateInterpolator();// 加速
mInterpolators[2] = new DecelerateInterpolator();// 减速
mInterpolators[3] = new AccelerateDecelerateInterpolator();// 先加速后减速
// 底部 并且 水平居中
dWidth = drawables[0].getIntrinsicWidth();
dHeight = drawables[0].getIntrinsicHeight();
lp = new LayoutParams(dWidth, dHeight);
lp.addRule(CENTER_HORIZONTAL, TRUE);// 这里的TRUE 要注意 不是true
lp.addRule(ALIGN_PARENT_BOTTOM, TRUE);
}
private AnimatorSet getEnterAnimator(final View target) {
ObjectAnimator alpha = ObjectAnimator.ofFloat(target, View.ALPHA, 0.2f, 1f);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(target, View.SCALE_X, 0.2f, 1f);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(target, View.SCALE_Y, 0.2f, 1f);
AnimatorSet enter = new AnimatorSet();
enter.setTarget(target);
enter.setInterpolator(new LinearInterpolator());
enter.setDuration(500).playTogether(alpha, scaleX, scaleY);
return enter;
}
private ValueAnimator getBezierValueAnimator(final View target) {
// 初始化贝塞尔估值器
BezierEvaluator evaluator = new BezierEvaluator(getPointF(2), getPointF(1));
// 起点在底部中心位置,终点在底部随机一个位置
ValueAnimator animator = ValueAnimator.ofObject(evaluator, new PointF((mWidth - dWidth) /
2, mHeight - dHeight), new PointF(random.nextInt(getWidth()), 0));
animator.setTarget(target);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// 这里获取到贝塞尔曲线计算出来的的x y值 赋值给view 这样就能让爱心随着曲线走啦
PointF pointF = (PointF) valueAnimator.getAnimatedValue();
target.setX(pointF.x);
target.setY(pointF.y);
// alpha动画
target.setAlpha(1 - valueAnimator.getAnimatedFraction());
}
});
animator.setDuration(3000);
return animator;
}
public void addHeart() {
final ImageView imageView = new ImageView(getContext());
// 随机选一个爱心
imageView.setImageDrawable(drawables[random.nextInt(3)]);
imageView.setLayoutParams(lp);
addView(imageView);
AnimatorSet finalSet = new AnimatorSet();
AnimatorSet enterAnimatorSet = getEnterAnimator(imageView);//入场动画
ValueAnimator bezierValueAnimator = getBezierValueAnimator(imageView);//贝塞尔曲线路径动画
finalSet.playSequentially(enterAnimatorSet, bezierValueAnimator);
finalSet.setInterpolator(mInterpolators[random.nextInt(4)]);
finalSet.setTarget(imageView);
finalSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
removeView((imageView));//删除爱心
}
});
finalSet.start();
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有