【问题标题】:discord/js and angle of arc functiondiscord/js 和圆弧函数的角度
【发布时间】:2022-01-24 12:35:27
【问题描述】:

示例:

尝试在 Arc 上进行处理,但我正在撞墙试图找出结束角度。我需要一些简单的东西,这样可以给它一个百分比,它会形成一个圆的百分比的弧。

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

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

但它们都不是那样的,我只是无法弄清楚它是如何绘制弧线的。

    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);

最终/固定代码

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);

【问题讨论】:

    标签: javascript node.js discord.js html5-canvas


    【解决方案1】:

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

    // ** 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>

    【讨论】:

    • 做到了,虽然我很犹豫是否要使用你的画布初始化,因为我的画布做的不仅仅是圆圈米res,包括部门工作得很好。如果其他人想要制作自己的类似玩家卡,包括我的用于随机化值的占位符代码,我会用修改代码进行编辑,因为所有显示数据都将从 jason 文件中提取
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 1970-01-01
    • 2014-05-12
    • 2012-07-12
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多