环形可拖动进度条

789 阅读1分钟

640.webp

`

圆形进度条拖拽滑动
<script type="text/javascript">
    var canvas = document.getElementById("canvasId")
    var ctx = canvas.getContext("2d")
    var ox = 200
    var oy = 200
    var or = 100 //半径
    var br = 15
    var moveFlag = false

    // 画刻度线
    function animation(m, t, clickWidth, q, r) {
        obj = {
            width: 400,
            height: 400,
            dx: clickWidth,   // 刻度宽度
            dy: 3,            // 刻度高度
            num: m,           // 刻度条数
            r: r,             // 半径
            start: t,         // 开始角度,与结束角度相对称
            progress: 80,     // 显示进度 (单位百分比)
            index: 0,         // 开始刻度
            defaultColor: '#ABB1C1', // 开始颜色
        };
        obj.deg = (q - 2 * obj.start) / obj.num;


        for (var x = 0; x < obj.num + 1; x++) {    //灰色刻度线
            drawpc(x, obj.defaultColor)
        }

        function drawpc(x, color) {               // 画出环形刻度线
            ctx.save()
            var deg = Math.PI / 180 * (obj.start + obj.deg * x) // 角度换算弧度   Math.PI/180 * 角度 = 弧度
            var offsetY = -(Math.sin(deg) * obj.r)              // 计算刻度Y轴位置
            var offsetX = -(Math.cos(deg) * obj.r)              // 计算刻度X轴位置
            ctx.fillStyle = color
            ctx.translate(obj.width / 2 + offsetX, obj.height / 2 + offsetY) // 修改画布坐标原点
            ctx.rotate(deg) // 旋转刻度
            ctx.fillRect(0, 0, obj.dx, obj.dy) // 画出刻度
            ctx.restore()
        }
    }

    function offset(r, d) {//根据弧度与距离计算偏移坐标
        return { x: -Math.sin(r) * d, y: Math.cos(r) * d }
    };

    function draw(n) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        // 填充渐变
        const grd = ctx.createLinearGradient(150, 70, 150, 200)
		grd.addColorStop(0, 'white')
		grd.addColorStop(1, '#DEE5ED')
        // 外圆
        ctx.strokeStyle = "#F0F2F6"
        ctx.fillStyle = grd
        ctx.lineWidth = 20
        ctx.beginPath()
        ctx.arc(ox, oy, or-6, 0, 2 * Math.PI, true);//整圆
        ctx.stroke()
        ctx.fill()
        // 内圆(进度条)
        ctx.strokeStyle = "#1E7FFF"
        ctx.lineCap = 'round'
        ctx.lineWidth = 10
        ctx.beginPath()
        ctx.arc(ox,oy,or,0.5*Math.PI,(n*2+0.5)*Math.PI,false)
        ctx.stroke()
        // 中心文字
        ctx.fillStyle = "#181818"
        ctx.font = "40px Arial"
        ctx.textAlign = "center"
        ctx.textBaseline = "middle"
        ctx.fillText(Math.round(n*100)+"%",ox,oy)

        // 圆行滑块
        ctx.save()
        ctx.fillStyle = "#FAFBFC"
        ctx.shadowColor = '#D8DBE2'
        ctx.shadowBlur = 8
        ctx.shadowOffsetX = 1
        ctx.shadowOffsetY = 4
        ctx.beginPath()
        var d = offset(n * 2 * Math.PI, or)
        ctx.arc(ox + d.x, oy + d.y, br, 0, 2 * Math.PI, true)
        ctx.fill()
        ctx.restore()

    }

    var on = ("ontouchstart" in document) ? {
        start: "touchstart", move: "touchmove", end: "touchend"
    } : {
        start: "mousedown", move: "mousemove", end: "mouseup"
    };

    function getXY(e, obj) {
        var et = e.touches ? e.touches[0] : e
        var x = et.clientX
        var y = et.clientY
        return {
            x: x - obj.offsetLeft + (document.body.scrollLeft || document.documentElement.scrollLeft),
            y: y - obj.offsetTop + (document.body.scrollTop || document.documentElement.scrollTop)
          
        }
    }

    canvas.addEventListener(on.start, function (e) {
        moveFlag = true
    }, false)

    canvas.addEventListener(on.move, function (e) {
        if (moveFlag) {
            var k = getXY(e, canvas)
            var r = Math.atan2(k.x - ox, oy - k.y)
            console.log("xxxxxxxx=" + k.x)
            console.log("yyyyyyyy=" + k.y)
            var hd = (Math.PI + r) / (2 * Math.PI)
            console.log(hd)
            draw(hd)
            animation(16, -90, 10, 180, 125)
            animation(48, -97.5, 5, 165, 120)
        }
    }, false)

    canvas.addEventListener(on.end, function (e) {
        moveFlag = false
    }, false)

    draw(0)
    animation(16, -90, 10, 180, 125)
    animation(48, -97.5, 5, 165, 120)
</script>
`