discord/js 和弧度函数的角度

discord/js and angle of arc function

示例:

尝试获取 Arc 上的句柄,我 运行 撞墙试图找出结束角度。我需要一些简单的东西,所以可以给它一个百分比,它会生成一个圆的百分比的圆弧。

我让弧线从顶部开始,我知道 math.pi*2 会让我一路走来,但是当我尝试用旧的 *0.p 技巧修改它时转换百分比我明白了。

白色为 0.1/10% 红色为 0.95/95% 绿色为 0.5/50% 蓝色是 0.7/70%

但其中 none 个看起来像那样,我只是想不通它是如何计算弧度的。

    var radius = 250 / 2 - 5;
    var centerx = 250 / 2;
    var centery = 250 / 2;
    const startagle = Math.PI * 1.5;
    var endagle = (Math.PI * 2)*0.1;
    context.beginPath();
    context.fillStyle = 'white';
    context.arc(centerx, centery, radius, startagle, endagle, false);
    context.lineTo(centerx, centery);
    context.fill();
    context.closePath();        
    
    var endagle = (Math.PI * 2)*0.95;
    context.beginPath();
    context.fillStyle = 'red';
    context.arc(centerx, centery, radius-5, startagle, endagle, false);
    context.lineTo(centerx, centery);
    context.fill();
    context.closePath();        
    
    var endagle = (Math.PI * 2)*0.5;
    context.beginPath();
    context.fillStyle = 'green';
    context.arc(centerx, centery, radius-10, startagle, endagle, false);
    context.lineTo(centerx, centery);
    context.fill();
    context.closePath();        

    var endagle = (Math.PI * 2)*0.7;
    context.beginPath();
    context.fillStyle = 'blue';
    context.arc(centerx, centery, radius-15, startagle, endagle, false);
    context.lineTo(centerx, centery);
    context.fill();
    context.closePath();        

    context.beginPath();
    context.arc(centerx, centery, radius-20, 0, 360, false);
    context.closePath();
    context.clip();
    const avatar = await Canvas.loadImage('https://i.imgur.com/lleYAsg.png');
    context.drawImage(avatar, 10, 10, 250, 250);

Finalized/Fixed代码

const Canvas = require('canvas');
      var canvas = Canvas.createCanvas(700, 250);
      var context = canvas.getContext('2d');
  
      const background = await Canvas.loadImage('./images/photo-1538370965046-79c0d6907d47.jpg');
      context.drawImage(background, 0, 0, canvas.width, canvas.height);
  
      context.strokeStyle = '#0099ff';
      context.strokeRect(0, 0, canvas.width, canvas.height);

        var answers = [
          "Red Ranger",
          "Blue Ranger",
          "Yellow Ranger",
          "Pink Ranger",
          "Green Ranger",
          "Black Ranger",
          "Orange Ranger",
          "Violet Ranger",
          "White Ranger",
          "Silver Ranger",
          "Gold Ranger",
          "Bronze Ranger",
          "Brown Ranger",
          "Extra Hero",
          "Meta Hero",
          "Rider",
          "Ultra",
          "Kaiju"
        ];
        var stats = [
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99),
          Math.floor(Math.random() * 99)
        ];
        var toonnamelist = [
          "Evelyn Leon",
          "Salvador Knight",
          "Alyson Hensley",
          "Tobias Harvey",
          "Selah Frazier",
          "Morgan Ward",
          "Ronald Shepherd",
          "Miriam Moody",
          "Maren Gallagher",
          "Alexia Crawford",
          "Aliya Weiss",
          "Jan Garrison"
        ];
        var toonavatars = [
          "https://i.imgur.com/lleYAsg.png",
          "https://i.imgur.com/0x008b.png",
          "https://i.imgur.com/ESPP3b.png",
          "https://i.imgur.com/qv7cvb.png",
          "https://i.imgur.com/VuYRAb.png",
          "https://i.imgur.com/RB6lSb.png",
          "https://i.imgur.com/hMlrIb.png",
          "https://i.imgur.com/mLuRIb.png",
          "https://i.imgur.com/QVQ7mb.png",
          "https://i.imgur.com/IXEuqb.png",
          "https://i.imgur.com/CgMlpb.png",
          "https://i.imgur.com/vO008b.png"
        ];
        var randomrank = answers[Math.floor(Math.random() * answers.length)];
        var randomavy = toonavatars[Math.floor(Math.random() * toonavatars.length)];
        var toonname = `${msg.member.displayName}`;
            toonname = toonnamelist[Math.floor(Math.random() * toonnamelist.length)];;
        var toonlevel = Math.floor(Math.random() * 99);
        var toonrank = randomrank;
        var curentexp = Math.floor(Math.random() * 9999);
        var maxexp = Math.floor(Math.random() * 9999);
        if (curentexp > maxexp){curentexp = maxexp;}

        const cFont = context.font;
        var fontArgs = context.font.split(' ');
        var newSize = '30px';
        context.font = newSize + ' ' + fontArgs[fontArgs.length - 1];
        context.fillText(toonname, 250, 50);

        fontArgs = context.font.split(' ');
        newSize = '20px';
        context.font = newSize + ' ' + fontArgs[fontArgs.length - 1];
        context.fillText(`Level: `+toonlevel, 250, 80);
        context.fillText(`Rank: `+toonrank, 350, 80);

        context.font = '30px monospace';
        context.fillText(`S:`+stats[0], 250, 170);
        context.fillText(`P:`+stats[1], 355, 170);
        context.fillText(`E:`+stats[2], 450, 170);
        context.fillText(`W:`+stats[3], 250, 200);
        context.fillText(`I:`+stats[4], 355, 200);
        context.fillText(`L:`+stats[5], 450, 200);
        context.fillText(`A:`+stats[6], 250, 230);
        context.fillText(`F:`+stats[7], 355, 230);
        context.fillText(`R:`+stats[8], 450, 230);

        var recx = 250;
        var recy = 90;
        var recw = 300;
        var rech = 40;
        context.fillStyle = 'grey';
        context.strokeStyle = 'silver';
        context.lineWidth = '3';
        context.beginPath();
        context.fillRect(recx, recy, recw*(curentexp/maxexp), rech);
        context.strokeRect(recx, recy, recw, rech);
        context.fillStyle = 'white';
        context.font = '20px sans-serif';
        context.fillText('XP: '+curentexp+'/'+maxexp, 260, recy+28);
        context.closePath();        

        let strokeWidth = 5;
        var radius = 250 / 2 - strokeWidth;
        let center = {
          x: 250 / 2,
          y: 250 / 2,
        };
        //var centerX = 250 / 2;
        //var centerY = 250 / 2;
        //const fullCircle = Math.PI * 2;
        //const startAngle = Math.PI * 1.5;
        //let endAngle;
        let sectors = [
          { color: 'white', size: 0.1 },
          { color: 'crimson', size: 0.95 },
          { color: 'springgreen', size: 0.5 },
          { color: 'dodgerblue', size: 0.7 },
        ];

        function drawSector({ context, color, center, radius, size }) {
          let startAngle = Math.PI * 1.5;
          let endAngle = startAngle + Math.PI * 2 * size;
        
          context.beginPath();
          context.fillStyle = color;
          context.arc(center.x, center.y, radius, startAngle, endAngle);
          context.lineTo(center.x, center.y);
          context.fill();
          context.closePath();
        }

        sectors.forEach(({ color, size }, i) => drawSector({
          context, color, center, radius: radius - i * strokeWidth, size
        }));
        
        const conditionx = 575;
        const conditiony = 5;
        const conditionw = 125;
        const conditionh = 250;
        var conditionpic1 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2ArmS1_White.png');
        var conditionpic2 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2ArmS2_White.png');
        var conditionpic3 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2Head_White.png');
        var conditionpic4 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2Torso_White.png');
        var conditionpic5 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2LegS1_White.png');
        var conditionpic6 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Base/NekollxComm_BaseV2LegS2_White.png');

        var conditionpic3 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Adjustments/CatPeople/NekollxComm2_CatHead_F_White.png');
        var conditionpic7 = await Canvas.loadImage('https://maskedriders.info/Mee6RP/PaperDoll/White_Adjustments/CatPeople/NekollxComm2_CatTail_F_White.png');
        context.drawImage(conditionpic1, conditionx, conditiony, conditionw, conditionh);
        context.drawImage(conditionpic2, conditionx, conditiony, conditionw, conditionh);
        context.drawImage(conditionpic3, conditionx, conditiony, conditionw, conditionh);
        context.drawImage(conditionpic4, conditionx, conditiony, conditionw, conditionh);
        context.drawImage(conditionpic5, conditionx, conditiony, conditionw, conditionh);
        context.drawImage(conditionpic6, conditionx, conditiony, conditionw, conditionh);
        context.drawImage(conditionpic7, conditionx, conditiony, conditionw, conditionh);

        context.beginPath();
        context.arc(center.x, center.y, radius - sectors.length * strokeWidth, 0, 360, false);
        context.closePath();
        context.clip();
        const avatar = await Canvas.loadImage(randomavy);
        context.drawImage(avatar, 10, 10, 250, 250);

那是因为你忘记改变起始角度了。您需要使圆弧结束的角度相对于起始角度。因此,如果您将值增加起始值,它将按预期工作:

// ** For this demo only ** //
const canvas = document.querySelector('canvas');
const context = canvas.getContext('2d');

canvas.height = 250;
canvas.width = 250;
context.fillStyle = 'dimgray';
context.fillRect(0, 0, canvas.width, canvas.height);
// ** End ** //

const radius = canvas.width / 2 - 5;
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const fullCircle = Math.PI * 2;
const startAngle = Math.PI * 1.5;
let endAngle;

endAngle = startAngle + fullCircle * 0.1;
context.beginPath();
context.fillStyle = 'white';
context.arc(centerX, centerY, radius, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();

endAngle = startAngle + fullCircle * 0.95;
context.beginPath();
context.fillStyle = 'crimson';
context.arc(centerX, centerY, radius - 5, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();

endAngle = startAngle + fullCircle * 0.5;
context.beginPath();
context.fillStyle = 'springgreen';
context.arc(centerX, centerY, radius - 10, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();

endAngle = startAngle + fullCircle * 0.7;
context.beginPath();
context.fillStyle = 'dodgerblue';
context.arc(centerX, centerY, radius - 15, startAngle, endAngle, false);
context.lineTo(centerX, centerY);
context.fill();
context.closePath();

context.beginPath();
context.arc(centerX, centerY, radius - 20, 0, 360, false);
context.closePath();
context.clip();

// ** For this demo only ** //
let url = 'https://i.imgur.com/lleYAsg.png';
let img = new Image();
new Promise((resolve) => (img.onload = resolve), (img.src = url)).then(() =>
  context.drawImage(img, 10, 10, 250, 250),
);
body {
  align-items: center;
  background-color: dimgray;
  display: flex;
  justify-content: center;
  margin: 0;
  min-height: 100vh;
}
<canvas></canvas>

它按预期工作;但是,您也可以简化创建扇区的方式。我会写一个函数来绘制这些 (drawSector) 并将颜色和大小存储在数组中 (sectors)。

// ** For this demo only ** //
let canvas = document.querySelector('canvas');
let context = canvas.getContext('2d');

canvas.height = 250;
canvas.width = 250;
context.fillStyle = '#232425';
context.fillRect(0, 0, canvas.width, canvas.height);
// ** End ** //

let center = {
  x: canvas.width / 2,
  y: canvas.height / 2,
};
let strokeWidth = 5;
let radius = canvas.width / 2 - strokeWidth;
let sectors = [
  { color: 'white', size: 0.1 },
  { color: 'crimson', size: 0.95 },
  { color: 'springgreen', size: 0.5 },
  { color: 'dodgerblue', size: 0.7 },
];

function drawSector({ context, color, center, radius, size }) {
  let startAngle = Math.PI * 1.5;
  let endAngle = startAngle + Math.PI * 2 * size;

  context.beginPath();
  context.fillStyle = color;
  context.arc(center.x, center.y, radius, startAngle, endAngle);
  context.lineTo(center.x, center.y);
  context.fill();
  context.closePath();
}

sectors.forEach(({ color, size }, i) => drawSector({
  context, color, center, radius: radius - i * strokeWidth, size
}));

context.beginPath();
context.arc(center.x, center.y, radius - sectors.length * strokeWidth, 0, 360);
context.closePath();
context.clip();

// ** For this demo only ** //
let url = 'https://i.imgur.com/lleYAsg.png';
let img = new Image();
new Promise((resolve) => (img.onload = resolve), (img.src = url)).then(() =>
  context.drawImage(img, 10, 10, 250, 250),
);
body {
  align-items: center;
  background-color: #232425;
  display: flex;
  justify-content: center;
  margin: 0;
  min-height: 100vh;
}
<canvas></canvas>