雷达扩散效果的实现

    相信大家都看像搜索附近、周边人或事物的雷达扩散效果吧,那这个效果是这样实现的呢,怎样以一种高效的方式来实现呢?好了,先看看效果吧
在这里插入图片描述

实现思路

    雷达扩散效果我们可以把它看成是一组同心圆,并且随着半径的不断增大,圆的填充色逐渐变成透明;并且发现两个相邻的同心圆的间距是相等的,这样我们就可以只要最外边缘的半径值,就可以退出其他圆的半径,从而用一个定时任务去实现这种渐变效果。

代码部分

自定义一个RadarView

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
 *@date 2019/5/14
 *@desc 雷达扩散view
 *
 */

public class RadarView extends View {
    private int mWidth;
    private int mHeigth;
    private int mRadius;
    private int mCenterX;
    private int mCenterY;
    private int mColor;
    private int mAlpha;
    private boolean mIsAlpha;//是否需要渐变
    private int mSpace;//两个环之间的间距
    private int mSpeed;//速度
    private Paint mPaint;
    private int mNum=1;
    private int mCurrMaxRadius;//当前显示的最大半径
    private boolean mIsStart;
    private int mDelayMillis=60;
    private Bitmap mCenterBitmap;//中心图片

    private Runnable mRunnable=new Runnable() {
        @Override
        public void run() {
            if(mIsStart){
                invalidate();
                postDelayed(mRunnable,mDelayMillis);
            }
        }
    };



    public RadarView(Context context) {
        super(context);
        init();
    }

    public RadarView(Context context, @Nullable AttributeSet attrs) {
        this(context,attrs,0);
    }

    public RadarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.radar_view, defStyleAttr, 0);
        mSpace=attributes.getInteger( R.styleable.radar_view_radar_view_space,150);
        mColor=attributes.getColor( R.styleable.radar_view_radar_view_color,0x80FF00FF);
        mSpeed=attributes.getInteger( R.styleable.radar_view_radar_view_speed,10);
        mIsAlpha=attributes.getBoolean(R.styleable.radar_view_radar_view_is_alpha,true);
        int imageId=attributes.getResourceId(R.styleable.radar_view_radar_view_center_image,0);
        if(imageId>0){
            mCenterBitmap= BitmapFactory.decodeResource(getResources(), imageId);
        }
        attributes.recycle();
        init();
    }

    private void init(){
        mPaint=new Paint();
        mPaint.setColor(mColor);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
        mAlpha=(mColor>>24)&0xFF;
    }

    public void setColor(int color){
        mColor=color;
        mPaint.setColor(mColor);
        mAlpha=(mColor>>24)&0xFF;
    }

    public void startSearch(){
        removeCallbacks(mRunnable);
        mIsStart=true;
        postDelayed(mRunnable,mDelayMillis);
    }

    public void stopSearch(){
        mIsStart=false;
        removeCallbacks(mRunnable);
    }




    @Override
    protected void onDraw(Canvas canvas) {
        if(mCurrMaxRadius>mRadius){
            mCurrMaxRadius-=mSpace;
        }
        mCurrMaxRadius+=mSpeed;
        int minRadius=0;
        if(mCenterBitmap!=null){
            minRadius=mCenterBitmap.getWidth()/2;
        }
        if(mIsAlpha) {
            for (int i = 0; i < mNum; i++) {
                int radius = mCurrMaxRadius - i * mSpace;
                if(radius>minRadius){
                    int colorGradient = mAlpha;
                    if (radius < mRadius) {
                        colorGradient = mAlpha * radius / mRadius;
                    }
                    colorGradient <<= 24;
                    mPaint.setColor(mColor - colorGradient);
                Log.d("RadarView","i="+i+" mAlpha="+Integer.toHexString(mAlpha).toUpperCase()+" radius="+radius+" colorGradient="+Integer.toHexString(colorGradient).toUpperCase()+" color="+Integer.toHexString(mColor - colorGradient).toUpperCase());
                    canvas.drawCircle(mCenterX, mCenterY, radius, mPaint);
                }
            }
        }else{
            for (int i = 0; i < mNum; i++) {
                int radius = mCurrMaxRadius - i * mSpace;
                if(radius>minRadius){
                    canvas.drawCircle(mCenterX, mCenterY, radius, mPaint);
                }
            }
        }
        if(minRadius>0){
            canvas.drawBitmap(mCenterBitmap,mCenterX-mCenterBitmap.getWidth()/2,mCenterY-mCenterBitmap.getHeight()/2,mPaint);
        }
    }






    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mWidth=measureValue(widthMeasureSpec);
        mHeigth=measureValue(heightMeasureSpec);
        mRadius=Math.max(mWidth,mHeigth)/2;
        setMeasuredDimension(mWidth,mHeigth);
        mNum=mRadius/mSpace;
        mRadius=mNum*mSpace;
        mCenterX=mWidth/2;
        mCenterY=mHeigth/2;
    }

    private int measureValue(int value){
        int specMode=MeasureSpec.getMode(value);
        int specSize=MeasureSpec.getSize(value);
        int result=0;
        switch (specMode){
            case MeasureSpec.EXACTLY:
                result=specSize;
                break;
            case MeasureSpec.AT_MOST:
                result=specSize;
                break;
            case MeasureSpec.UNSPECIFIED:
                result=200;
                break;
        }
        return result;
    }
}

添加自定义属性

 <declare-styleable name="radar_view">
        <attr name="radar_view_space" format="integer"/><!--两个环之间的间距-->
        <attr name="radar_view_color" format="color"/><!--圆环的颜色-->
        <attr name="radar_view_speed" format="integer"/><!--扩散的速度-->
        <attr name="radar_view_is_alpha" format="boolean"/><!--扩散是否需要渐变-->
        <attr name="radar_view_center_image" format="reference"/><!--中心图片-->
    </declare-styleable>

接下来在自己的代码中使用起来就可以了。如果想要demo的源码,可以到这里下载

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Uniapp是一款跨平台开发的应用程序开发框架,可以帮助开发者快速地开发出高质量的移动应用程序。如果需要实现雷达动态效果,可以使用Uniapp中的canvas组件进行实现。 以下是实现雷达动态效果的步骤: 1. 创建一个canvas组件,并设置宽度和高度,用于绘制雷达图。 2. 在canvas中绘制雷达图的背景,可以使用context.arc()方法绘制圆形,使用context.stroke()方法绘制出雷达图的网格线。 3. 根据数据绘制雷达图的数据线。首先需要计算出数据点的坐标,然后使用context.moveTo()方法将画笔移动到第一个点的位置,使用context.lineTo()方法将画笔移动到下一个点的位置,最后使用context.stroke()方法将数据线绘制出来。 4. 如果需要实现动态效果,可以使用定时器不断更新数据,并重新绘制雷达图。可以使用requestAnimationFrame()方法来实现动画效果。 5. 最后,将绘制好的雷达图显示在页面中即可。 以下是示例代码: ``` <template> <canvas canvas-id="canvas" style="width: 300px; height: 300px;"></canvas> </template> <script> export default { onReady() { const ctx = uni.createCanvasContext('canvas', this); // 绘制雷达图的背景 const centerX = 150; const centerY = 150; const radius = 100; ctx.beginPath(); for (let i = 0; i < 6; i++) { const angle = Math.PI / 3 * i; const x = centerX + Math.cos(angle) * radius; const y = centerY + Math.sin(angle) * radius; ctx.moveTo(centerX, centerY); ctx.lineTo(x, y); } ctx.stroke(); // 更新数据并绘制雷达图 let data = [0.5, 0.8, 0.6, 0.4, 0.9, 0.7]; const step = 0.01; function animate() { ctx.clearRect(0, 0, 300, 300); // 绘制雷达图的背景 ctx.beginPath(); for (let i = 0; i < 6; i++) { const angle = Math.PI / 3 * i; const x = centerX + Math.cos(angle) * radius; const y = centerY + Math.sin(angle) * radius; ctx.moveTo(centerX, centerY); ctx.lineTo(x, y); } ctx.stroke(); // 绘制雷达图的数据线 ctx.beginPath(); for (let i = 0; i < 6; i++) { const angle = Math.PI / 3 * i; const x = centerX + Math.cos(angle) * radius * data[i]; const y = centerY + Math.sin(angle) * radius * data[i]; if (i === 0) { ctx.moveTo(x, y); } else { ctx.lineTo(x, y); } } ctx.closePath(); ctx.stroke(); // 更新数据 for (let i = 0; i < 6; i++) { data[i] += step; if (data[i] > 1) { data[i] = 0; } } // 循环动画 requestAnimationFrame(animate); } animate(); } } </script> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值