【问题标题】:Canva how to set specific percantage?Canva如何设置具体百分比?
【发布时间】:2021-04-11 22:40:18
【问题描述】:

我正在开发一个微调器,但我一直不知道如何为微调器设置特定的百分比。

这是我的演示 => https://jsfiddle.net/fmvucqno/

options 变量中我有10%90% 我想实现10% 填充和90% 填充用户名。

<input type="button" value="spin" style="float:left;" id='spin'/>
<canvas id="canvas" width="500" height="500"></canvas>
<body style="background-color: white">

<script>
    var options = [
        [
            '@david',
            '10%',
        ],
        [
            '@burn',
            '90%'
        ]
    ];

    var startAngle  = 0;
    var arc         = Math.PI / (options.length / 2);
    var spinTimeout = null;

    var spinArcStart  = 10;
    var spinTime      = 0;
    var spinTimeTotal = 0;

    var ctx;

    document.getElementById("spin").addEventListener("click", spin);

    function byte2Hex(n)
    {
        var nybHexString = "0123456789ABCDEF";
        return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1);
    }

    function RGB2Color(r, g, b)
    {
        return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
    }

    function getColor(item, maxitem)
    {
        var phase     = 0;
        var center    = 128;
        var width     = 127;
        var frequency = Math.PI * 2 / maxitem;

        red   = Math.sin(frequency * item + 2 + phase) * width + center;
        green = Math.sin(frequency * item + 0 + phase) * width + center;
        blue  = Math.sin(frequency * item + 4 + phase) * width + center;

        return RGB2Color(red, green, blue);
    }

    function drawRouletteWheel()
    {
        var canvas = document.getElementById("canvas");
        if (canvas.getContext)
        {
            var outsideRadius = 200;
            var textRadius    = 160;
            var insideRadius  = 125;

            ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, 500, 500);

            ctx.strokeStyle = "black";
            ctx.lineWidth   = 2;

            ctx.font = 'bold 12px Helvetica, Arial';

            for (var i = 0; i < options.length; i++)
            {
                var angle     = startAngle + i * arc;
                ctx.fillStyle = getColor(i, options.length);

                ctx.beginPath();
                ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
                ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
                ctx.stroke();
                ctx.fill();

                ctx.save();
                ctx.shadowOffsetX = -1;
                ctx.shadowOffsetY = -1;
                ctx.shadowBlur    = 0;
                ctx.shadowColor   = "rgb(220,220,220)";
                ctx.fillStyle     = "black";
                ctx.translate(250 + Math.cos(angle + arc / 2) * textRadius,
                    250 + Math.sin(angle + arc / 2) * textRadius);
                ctx.rotate(angle + arc / 2 + Math.PI / 2);
                var text = options[i];
                ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
                ctx.restore();
            }

            //Arrow
            ctx.fillStyle = "black";
            ctx.beginPath();
            ctx.moveTo(250 - 4, 250 - (outsideRadius + 5));
            ctx.lineTo(250 + 4, 250 - (outsideRadius + 5));
            ctx.lineTo(250 + 4, 250 - (outsideRadius - 5));
            ctx.lineTo(250 + 9, 250 - (outsideRadius - 5));
            ctx.lineTo(250 + 0, 250 - (outsideRadius - 13));
            ctx.lineTo(250 - 9, 250 - (outsideRadius - 5));
            ctx.lineTo(250 - 4, 250 - (outsideRadius - 5));
            ctx.lineTo(250 - 4, 250 - (outsideRadius + 5));
            ctx.fill();
        }
    }

    function spin()
    {
        spinAngleStart = Math.random() * 10 + 10;
        spinTime       = 0;
        spinTimeTotal  = Math.random() * 3 + 4 * 1000;
        rotateWheel();
    }

    function rotateWheel()
    {
        spinTime += 30;
        if (spinTime >= spinTimeTotal)
        {
            stopRotateWheel();
            return;
        }
        var spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
        startAngle += (spinAngle * Math.PI / 180);
        drawRouletteWheel();
        spinTimeout = setTimeout('rotateWheel()', 30);
    }

    function stopRotateWheel()
    {
        clearTimeout(spinTimeout);
        var degrees = startAngle * 180 / Math.PI + 90;
        var arcd    = arc * 180 / Math.PI;
        var index   = Math.floor((360 - degrees % 360) / arcd);
        ctx.save();
        ctx.font = 'bold 30px Helvetica, Arial';
        var text = options[index]
        ctx.fillText(text, 250 - ctx.measureText(text).width / 2, 250 + 10);
        ctx.restore();
    }

    function easeOut(t, b, c, d)
    {
        var ts = (t /= d) * t;
        var tc = ts * t;
        return b + c * (tc + -3 * ts + 3 * t);
    }

    drawRouletteWheel();
</script>

【问题讨论】:

标签: html css canvas


【解决方案1】:

虽然为不同的人设置了一些选项,包括他们应该占据的百分比,但实际上并没有使用这些选项。

计算出的弧对所有用户都是相等的 - Math.PI / (options.length / 2)

相反,我们需要为该用户使用选项中给定的值,并且我们必须逐渐增加起始角度才能知道从哪里开始下一个弧。

这是带有更改的 sn-p:

    var options = [
        [
            '@david',
            '10%',
        ],
        [
            '@burn',
            '90%'
        ]
    ];

    var startAngle  = 0;
    var arc         = Math.PI / (options.length / 2);
    var spinTimeout = null;

    var spinArcStart  = 10;
    var spinTime      = 0;
    var spinTimeTotal = 0;

    var ctx;

    document.getElementById("spin").addEventListener("click", spin);

    function byte2Hex(n)
    {
        var nybHexString = "0123456789ABCDEF";
        return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1);
    }

    function RGB2Color(r, g, b)
    { 
        return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
    }

    function getColor(item, maxitem)
    {
        var phase     = 0;
        var center    = 128;
        var width     = 127;
        var frequency = Math.PI * 2 / maxitem;

        red   = Math.sin(frequency * item + 2 + phase) * width + center;
        green = Math.sin(frequency * item + 0 + phase) * width + center;
        blue  = Math.sin(frequency * item + 4 + phase) * width + center;

        return RGB2Color(red, green, blue);
    }

    function drawRouletteWheel()
    {
        var canvas = document.getElementById("canvas");
        if (canvas.getContext)
        {
            var outsideRadius = 200;
            var textRadius    = 160;
            var insideRadius  = 125;

            ctx = canvas.getContext("2d");
            ctx.clearRect(0, 0, 500, 500);

            ctx.strokeStyle = "black";
            ctx.lineWidth   = 2;

            ctx.font = 'bold 12px Helvetica, Arial';
      var angle = startAngle;
            for (var i = 0; i < options.length; i++)
            {  arc = Math.PI * Number(options[i][1].replace('%','')) / 50;
                ctx.fillStyle = getColor(i, options.length);

                ctx.beginPath();
                ctx.arc(250, 250, outsideRadius, angle, angle + arc, false);
                ctx.arc(250, 250, insideRadius, angle + arc, angle, true);
                ctx.stroke();
                ctx.fill();

                ctx.save();
                ctx.shadowOffsetX = -1;
                ctx.shadowOffsetY = -1;
                ctx.shadowBlur    = 0;
                ctx.shadowColor   = "rgb(220,220,220)";
                ctx.fillStyle     = "black";
                ctx.translate(250 + Math.cos(angle + arc / 2) * textRadius,
                    250 + Math.sin(angle + arc / 2) * textRadius);
                ctx.rotate(angle + arc / 2 + Math.PI / 2);
                var text = options[i];
                ctx.fillText(text, -ctx.measureText(text).width / 2, 0);
                ctx.restore();
        
                angle += (i+1) * arc;
            }

            //Arrow
            ctx.fillStyle = "black";
            ctx.beginPath();
            ctx.moveTo(250 - 4, 250 - (outsideRadius + 5));
            ctx.lineTo(250 + 4, 250 - (outsideRadius + 5));
            ctx.lineTo(250 + 4, 250 - (outsideRadius - 5));
            ctx.lineTo(250 + 9, 250 - (outsideRadius - 5));
            ctx.lineTo(250 + 0, 250 - (outsideRadius - 13));
            ctx.lineTo(250 - 9, 250 - (outsideRadius - 5));
            ctx.lineTo(250 - 4, 250 - (outsideRadius - 5));
            ctx.lineTo(250 - 4, 250 - (outsideRadius + 5));
            ctx.fill();
        }
    }

    function spin()
    {
        spinAngleStart = Math.random() * 10 + 10;
        spinTime       = 0;
        spinTimeTotal  = Math.random() * 3 + 4 * 1000;
        rotateWheel();
    }

    function rotateWheel()
    {
        spinTime += 30;
        if (spinTime >= spinTimeTotal)
        {
            stopRotateWheel();
            return;
        }
        var spinAngle = spinAngleStart - easeOut(spinTime, 0, spinAngleStart, spinTimeTotal);
        startAngle += (spinAngle * Math.PI / 180);
        drawRouletteWheel();
        spinTimeout = setTimeout('rotateWheel()', 30);
    }

    function stopRotateWheel()
    {
        clearTimeout(spinTimeout);
        var degrees = startAngle * 180 / Math.PI + 90;
        var arcd    = arc * 180 / Math.PI;
        var index   = Math.floor((360 - degrees % 360) / arcd);
        ctx.save();
        ctx.font = 'bold 30px Helvetica, Arial';
        var text = options[index]
        ctx.fillText(text, 250 - ctx.measureText(text).width / 2, 250 + 10);
        ctx.restore();
    }

    function easeOut(t, b, c, d)
    {
        var ts = (t /= d) * t;
        var tc = ts * t;
        return b + c * (tc + -3 * ts + 3 * t);
    }

    drawRouletteWheel();
<input type="button" value="spin" style="float:left;" id='spin'/>
<canvas id="canvas" width="500" height="500"></canvas>

【讨论】:

    猜你喜欢
    • 2021-03-13
    • 2013-03-24
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多