首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不和谐/js与弧函数角

不和谐/js与弧函数角
EN

Stack Overflow用户
提问于 2021-12-23 14:22:16
回答 1查看 156关注 0票数 1

示例:

试着弄个弧形手柄,我就会撞到墙上,想弄清楚末端的角度。我需要一些简单的东西,这样就可以给它提供一个百分比,它就会形成一个弧度,也就是一个圆圈的百分比。

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

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

但他们都不是这样的,我就是搞不懂它是怎么确定弧线的。

代码语言:javascript
复制
    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);

已完成/固定代码

代码语言:javascript
复制
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);
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-23 20:08:26

这是因为你忘了你改变了起跑线。你需要使角度,其中的弧结束,是相对于开始的角度。因此,如果按起始值增加值,它将如预期的那样工作:

代码语言:javascript
复制
// ** 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),
);
代码语言:javascript
复制
body {
  align-items: center;
  background-color: dimgray;
  display: flex;
  justify-content: center;
  margin: 0;
  min-height: 100vh;
}
代码语言:javascript
复制
<canvas></canvas>

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

代码语言:javascript
复制
// ** 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),
);
代码语言:javascript
复制
body {
  align-items: center;
  background-color: #232425;
  display: flex;
  justify-content: center;
  margin: 0;
  min-height: 100vh;
}
代码语言:javascript
复制
<canvas></canvas>

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70463396

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档