圆环进度条,内环阴影,这种要怎么实现?

项目中有一个这种进度条,网上找了很多这种进度条的,基本写完了,但是总是实现不了内环周围那层模糊阴影。

后台转前端新手,基础不牢,真的太难,求助有没有好的方法或者其他思路。

我只能实现到下面这种:

tample

<view class="circle">
    <view class="circle-l"></view>
    <view class="circle-left" >
        <view class="left" :style="leftStyle"></view>
    </view>
    <view class="circle-right" >
        <view class="right" :style="rightStyle"></view>
    </view>
    <view class="circle-s"></view>
    <view class="circle_num">{{percent}}%</view>
</view>
<slider value="100" @changing="onchange" min="0" max="100" show-value />

script

    const percent = ref(0);
    const leftStyle = computed(()=>{
        if (percent.value >= 50) {
            let rotate = 180+percent.value * 3.6
            return 'transform: rotate('+rotate+'deg)'
        } else {
            return ''
        }
    });
    const rightStyle = computed(()=>{
        if (percent.value<=50) {
            return 'transform: rotate('+percent.value * 3.6+'deg)'
        } else {
            return 'display: none;'
        }
    });
    
    const onchange = (value)=>{
        percent.value = value.detail.value;
    }

css

.circle {
    position: relative;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 450rpx;
    .circle-left{
        position: absolute;
        width: 400rpx;
        height: 400rpx;
        clip: rect(0rpx,200rpx,400rpx,0rpx);
        border-radius: 50%;
        background-size: cover;
        background-image: url('');
        .left {
            position: absolute;
            width: 400rpx;
            height: 400rpx;
            clip: rect(0rpx,200rpx,400rpx,0rpx);
            background-color: #1C1D23;
            border-radius: 50%;
            background-size: cover;
        }
    }
    .circle-right{
        position: absolute;
        width: 400rpx;
        height: 400rpx;
        clip: rect(0rpx,400rpx,400rpx,200rpx);
        border-radius: 50%;
        background-size: cover;
        background-image: url('');
        .right {
            position: absolute;
            width: 400rpx;
            height: 400rpx;
            clip: rect(0rpx,400rpx,400rpx,200rpx);
            background-color: #1C1D23;
            border-radius: 50%;
            background-size: cover;
        }
    }
    .circle-l {
        position: absolute;
        width: 450rpx;
        height: 450rpx;
        border-radius: 50%;
        box-shadow: 0rpx 0rpx 20rpx #4F4F5B;
        background: #1C1D23;
    }
    .circle-s {
        position: absolute;
        width: 280rpx;
        height: 280rpx;
        border-radius: 50%;
        box-shadow: -2rpx -2rpx 6rpx #fff;
        background: #23232B;
    }
    .circle_num {
        width: 100%;
        font-size: 2rem;
        color: #fff;
        z-index: 6;
    }
}
回复
阅读 1.3k
3 个回答

使用canvas绘图解决
此处使用的uniapp,小程序的代码

template

<view class="circle-canvas">
    <canvas class="canvas" canvas-id="bgId" id="bgId"></canvas>
    <canvas class="canvas" canvas-id="progressId" id="progressId"></canvas>
</view>

js

const percent = ref(30);
watch(percent,(n,o)=>{
    drawProgress();
    drawText();
})
//绘制外圆圈
const drawCanBg = () => {
    let context = uni.createCanvasContext('bgId');
    const radius = uni.upx2px(190);
    const wid = uni.upx2px(70);
    context.setLineWidth(wid); // 设置圆环的宽度
    let cirgradient = context.createCircularGradient(radius + wid, radius + wid, radius+wid/2);
    cirgradient.addColorStop(1,'#15151A');
    cirgradient.addColorStop(.9,'#1A1A20')
    cirgradient.addColorStop(.6,'#212128');
    context.setStrokeStyle(cirgradient);
    context.setShadow(0, 0, 30, '#363640');
    context.beginPath(); // 开始创建一个路径
    context.arc(radius + wid, radius + wid, radius, 0, 2 * Math.PI, false);
    context.stroke(); // // 画出当前路径
    context.beginPath();
    context.setShadow(-1, -1, 2, '#868686');
    context.arc(radius + wid, radius + wid,uni.upx2px(145),0,2*Math.PI);
    context.setFillStyle('#23232B')
    context.fill()
    context.draw();
}

//绘制进度
const drawProgress = ()=> {
    let ctx = wx.createCanvasContext("progressId");
    const ringrad = uni.upx2px(230);
    const ringwid = uni.upx2px(30);
    ctx.setLineWidth(ringwid); // 宽度为10
    let gradient = ctx.createLinearGradient(uni.upx2px(90), 0, 0, uni.upx2px(90)); // 圆环为从右上到左下渐变
    gradient.addColorStop('0', '#00B9FF');
    gradient.addColorStop('1.0', '#98DEF8');
    ctx.setStrokeStyle(gradient); // 填充颜色
    ctx.setShadow(0, 0, 8, '#00B9FF');
    // const pattern = ctx.createPattern("",'repeat');
    // ctx.setStrokeStyle(pattern); //可以直接使用图片作为圆环背景;
    // 若设置线条的端点样式为圆形,当进度为0时会显示一个圆点
    if (percent.value !== 0) {
        ctx.setLineCap('round')
    }
    ctx.beginPath()
    ctx.arc(
        ringrad + ringwid,
        ringrad + ringwid,
        ringrad - ringwid * 1.4,
        -Math.PI / 2,
        percent.value / 100 * Math.PI * 2 - Math.PI / 2,
        0,
        2 * Math.PI,
        false
    )
    ctx.stroke()
    ctx.draw()
}

css

.circle-canvas {
    position: relative;
    width: 500rpx;
    height: 500rpx;
    .canvas {
        position: absolute;
        width: 500rpx;
        height: 500rpx;
    }
}
新手上路,请多包涵

1、 用svg来做圆环的图案,和进度【可以参考Element UI的做法】

2、阴影可以用filter 的高斯模糊来做【做一个形状一样的svg给他添加模糊来实现阴影】

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏