视频直播中的心形漂浮效果
来源:互联网 发布:js防水涂料设备 编辑:程序博客网 时间:2024/05/17 08:25
实现效果:
思路:
1.首先要给心形图片创建一个平滑的悬浮路径,那就要用到贝塞尔曲线,这里采用自定义TypeEvaluator实现。
2.路径有了,就要考虑实现动画的两个步骤
a.缩放,伴随透明度变化
b.底部悬浮到顶部
这里是用的是Matrix
3.自定义View,然后绘制心形图片。
详细步骤,看源码
代码:
1.自定义BezierEvaluator
package com.test.paintdemo.loveflyover;import android.animation.TypeEvaluator;import android.graphics.PointF;/** * Created by ygdx_lk on 17/6/26. */public class BezierEvaluator implements TypeEvaluator<PointF> { private final PointF p0, p3; public BezierEvaluator(PointF point0, PointF point3){ this.p0 = point0; this.p3 = point3; } @Override public PointF evaluate(float t, PointF p1, PointF p2) { //贝塞尔曲线的三次方公式 PointF pointF = new PointF(); pointF.x = (float) (p0.x * Math.pow((1 - t), 3) + 3 * p1.x * t * Math.pow((1 - t), 2) + 3 * p2.x * Math.pow(t, 2) * (1 - t) + p3.x * Math.pow(t, 3)); pointF.y = (float) (p0.y * Math.pow((1 - t), 3) + 3 * p1.y * t * Math.pow((1 - t), 2) + 3 * p2.y * Math.pow(t, 2) * (1 - t) + p3.y * Math.pow(t, 3)); return pointF; }}
2.创建FlyOverModel
package com.test.paintdemo.loveflyover;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.animation.AnimatorSet;import android.animation.ValueAnimator;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.PointF;import android.view.animation.AccelerateDecelerateInterpolator;import android.view.animation.AccelerateInterpolator;import android.view.animation.AnticipateInterpolator;import android.view.animation.AnticipateOvershootInterpolator;import android.view.animation.DecelerateInterpolator;import android.view.animation.Interpolator;import android.view.animation.LinearInterpolator;import android.view.animation.OvershootInterpolator;import com.test.paintdemo.R;import java.util.Random;/** * Created by ygdx_lk on 17/6/26. */public class FlyOverModel { private static final String TAG = "FlyOverModel"; private Paint mPaint; private PointF p0, p1, p2, p3;//p0起点,p1、p2拐点,p3终点 private float love_w, love_h;//爱心的宽高 private Bitmap mBitMap;//图片 private Matrix matrix; //图片 private int[] resources = {R.drawable.red, R.drawable.blue, R.drawable.yellow}; //差值器 private Interpolator[] interpolator = {new AccelerateDecelerateInterpolator(), new AnticipateInterpolator(), new OvershootInterpolator(), new AnticipateOvershootInterpolator(), new LinearInterpolator(), new AccelerateInterpolator(), new DecelerateInterpolator() }; public FlyOverModel(final Context context, final int width, final int height, final Invalidate invalidate){ //初始化画笔 mPaint = new Paint(); mPaint.setAntiAlias(true); //矩阵变换,用来控制图片的缩放位移 matrix = new Matrix(); //三次方贝塞尔曲线:初始化四个点,p0起点,p1、p2拐点,p3终点 p0 = new PointF(); p1 = new PointF(); p2 = new PointF(); p3 = new PointF(); //初始化bitmap mBitMap = BitmapFactory.decodeResource(context.getResources(), resources[new Random().nextInt(resources.length)]); //获取bitmap的宽高 love_w = mBitMap.getWidth(); love_h = mBitMap.getHeight(); //p0正好将图片贴底居中显示 p0.x = (width - love_w) / 2; p0.y = height - love_h; p2.x = (float) (Math.random() * width); p2.y = (float) (Math.random() * height / 2); p1.x = (float) (Math.random() * width); p1.y = (float) ((1 + Math.random()) * height / 2); //p3正好图片移出屏幕 p3.x = (float) (Math.random() * width); p3.y = -love_h; //缩放动画 ValueAnimator scaleAnimator = ValueAnimator.ofFloat(0, 1); scaleAnimator.setDuration(1000); scaleAnimator.setInterpolator(new LinearInterpolator()); scaleAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { //平移到底部 matrix.setTranslate(p0.x, p0.y); //以图片中心底部为轴,进行缩放 matrix.preScale(animation.getAnimatedFraction(), animation.getAnimatedFraction(), love_w / 2, love_h); //设置画笔透明度 mPaint.setAlpha((int) (255 * animation.getAnimatedFraction())); invalidate.invalidate(); } }); //位移动画 BezierEvaluator bezierEvaluator = new BezierEvaluator(p0, p3); ValueAnimator valueAnimator = ValueAnimator.ofObject(bezierEvaluator, p1, p2); valueAnimator.setInterpolator(interpolator[new Random().nextInt(interpolator.length)]); valueAnimator.setDuration(3000); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF pointF = (PointF) animation.getAnimatedValue(); matrix.reset(); matrix.setTranslate(pointF.x, pointF.y); invalidate.invalidate(); } }); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(valueAnimator).after(scaleAnimator); animatorSet.start(); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { //如果动画结束了,重新开始动画 animation.start(); super.onAnimationEnd(animation); } }); } interface Invalidate{ void invalidate(); } /** * 绘制bitmap * @param canvas */ public void drawBitmap(Canvas canvas){ canvas.drawBitmap(mBitMap, matrix, mPaint); }}
3.创建自定义View:LoveFlyOver
package com.test.paintdemo.loveflyover;import android.content.Context;import android.graphics.Canvas;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;import java.util.List;/** * Created by ygdx_lk on 17/6/26. */public class LoveFlyOver extends View { private int width;//控件宽 private int height;//控件高 private static final String TAG = "loveFlyOver"; private List<FlyOverModel> list; public LoveFlyOver(Context context) { this(context, null); } public LoveFlyOver(Context context, @Nullable AttributeSet attrs) { super(context, attrs); list = new ArrayList<>(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); //控件宽高 width = w; height = h; } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //点击后添加图片 addLove(); break; } return super.onTouchEvent(event); } private void addLove(int count){ for (int i = 0; i < count; i++) { addLove(); } } //添加心形图片 private void addLove(){ FlyOverModel flyOverModel = new FlyOverModel(getContext(), width, height, new FlyOverModel.Invalidate() { @Override public void invalidate() { postInvalidate(); } }); list.add(flyOverModel); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); //绘制 for (FlyOverModel item : list) { item.drawBitmap(canvas); } }}
阅读全文
0 0
- 视频直播中的心形漂浮效果
- 漂浮效果
- 两个surfaceview的重叠效果类似直播效果中的视频和讲义实践
- 两个surfaceview的重叠效果类似直播效果中的视频和讲义实践
- js图片漂浮效果
- ANDROID-漂浮背景效果
- UGUI的漂浮效果
- 音视频直播技术--实时互动中的多视频展示
- 视频直播
- 视频直播
- 视频直播
- 视频直播
- 视频直播
- 视频直播
- js实现广告漂浮效果
- JAVA 实现漂浮效果
- javascript广告漂浮效果代码
- js效果之漂浮广告
- Redis安装报错 error: jemalloc/jemalloc.h: No such file or directory解决方法
- 【网易2017实习生编程题】分饼干
- 好的学习网站收藏
- jxbrowser 实现自定义右键菜单 jxbrowser破解版请联系作者
- Java中hashCode的作用
- 视频直播中的心形漂浮效果
- 【服务器】-tomcat
- Codefores Round #419 (Div.2)
- jdbctemplate之crud操作
- WPF 启动页面
- C++中,为什么构造函数不能够是虚函数,而析构函数可以是虚函数,而且最好是虚函数
- [树的点分治] [BZOJ3648] 寝室管理
- sublime text的使用
- Unity Shader:雾的数学运算以及在Unity中使用Global Fog