HTML Canvas: сложная фигура на основе дуги заливки

#javascript #html #html5-canvas

#javascript #HTML #html5-canvas

Вопрос:

Ниже приведена структура JSON, которая рисует дуги с разным начальным и конечным углом

 var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");

var elementDetail =  {"element":[{"type":"ARC","x1":510,"y1":10,"x2":74.585653306513848,"y2":74.585653306514814,"r":1500,"xm":510,"ym":1510,"alpha":4.4178734952765524,"beta":4.71238898038469,"color":2},{"type":"ARC","x1":74.585653306514587,"y1":74.585653306514928,"x2":10,"y2":510,"r":1500,"xm":1510,"ym":510,"alpha":3.1415926535897931,"beta":3.43610813869793,"color":2},{"type":"ARC","x1":10,"y1":510,"x2":74.585653306514587,"y2":945.41434669348541,"r":1500,"xm":1510,"ym":510,"alpha":2.8470771684816563,"beta":3.1415926535897931,"color":2},{"type":"ARC","x1":74.585653306514871,"y1":945.41434669348541,"x2":510,"y2":1010,"r":1500,"xm":510,"ym":-490,"alpha":1.5707963267948966,"beta":1.8653118119030334,"color":2},{"type":"ARC","x1":510,"y1":1010,"x2":945.4143466934853,"y2":945.41434669348541,"r":1500,"xm":510,"ym":-490,"alpha":1.2762808416867597,"beta":1.5707963267948966,"color":2},{"type":"ARC","x1":945.41434669348541,"y1":945.41434669348541,"x2":1010,"y2":510,"r":1500,"xm":-490,"ym":510,"alpha":0,"beta":0.29451548510813697,"color":2},{"type":"ARC","x1":1010,"y1":510,"x2":945.41434669348519,"y2":74.585653306514132,"r":1500,"xm":-490,"ym":510,"alpha":5.9886698220714489,"beta":6.2831853071795862,"color":2},{"type":"ARC","x1":945.41434669348553,"y1":74.585653306514587,"x2":510,"y2":10,"r":1500,"xm":510,"ym":1510,"alpha":4.71238898038469,"beta":5.006904465492827,"color":2},{"type":"POINT","x1":510,"y1":510,"color":7}]}
    
ctx.beginPath();
elementDetail.element.map((elem, index) => {
  ctx.arc(elem.xm, elem.ym, elem.r, elem.alpha, elem.beta);  
})

ctx.closePath();
ctx.stroke();
ctx.fillStyle = "#6fd0ff";
ctx.fill();  
 canvas{ zoom:.25}  
 <canvas id="myCanvas" width="1200" height="1200"></canvas>  

Форма, которую мне нужно получить, это:

введите описание изображения здесь

Я смог выполнить цикл через json и заполнить обводку рисования, но не смог заполнить цвет внутри фигуры

Мне нужна помощь, чтобы заполнить фигуру цветом

Спасибо

Комментарии:

1. опубликуйте написанный вами код для рисования фигуры.

2. при этом заполняется только сегмент окружности

Ответ №1:

Чтобы избежать странных результатов в сложных фигурах, я бы предпочел выполнить рисование в два этапа :

  • Рендеринг сплошного тела: рисуем и заливаем фигуру
  • Рендеринг контуров: рисуем фигуру внешним штрихом

Примечание : При рисовании дуг вам нужно знать, что ctx.arc() будет создаваться line от последних координат текущего пути до первой позиции дуги. Чтобы избежать этого, вам нужно вызвать moveTo() , чтобы поднять перо для рисования в первую позицию дуги.

 var elementDetail =  {"element":[{"type":"ARC","x1":510,"y1":10,"x2":74.585653306513848,"y2":74.585653306514814,"r":1500,"xm":510,"ym":1510,"alpha":4.4178734952765524,"beta":4.71238898038469,"color":2},{"type":"ARC","x1":74.585653306514587,"y1":74.585653306514928,"x2":10,"y2":510,"r":1500,"xm":1510,"ym":510,"alpha":3.1415926535897931,"beta":3.43610813869793,"color":2},{"type":"ARC","x1":10,"y1":510,"x2":74.585653306514587,"y2":945.41434669348541,"r":1500,"xm":1510,"ym":510,"alpha":2.8470771684816563,"beta":3.1415926535897931,"color":2},{"type":"ARC","x1":74.585653306514871,"y1":945.41434669348541,"x2":510,"y2":1010,"r":1500,"xm":510,"ym":-490,"alpha":1.5707963267948966,"beta":1.8653118119030334,"color":2},{"type":"ARC","x1":510,"y1":1010,"x2":945.4143466934853,"y2":945.41434669348541,"r":1500,"xm":510,"ym":-490,"alpha":1.2762808416867597,"beta":1.5707963267948966,"color":2},{"type":"ARC","x1":945.41434669348541,"y1":945.41434669348541,"x2":1010,"y2":510,"r":1500,"xm":-490,"ym":510,"alpha":0,"beta":0.29451548510813697,"color":2},{"type":"ARC","x1":1010,"y1":510,"x2":945.41434669348519,"y2":74.585653306514132,"r":1500,"xm":-490,"ym":510,"alpha":5.9886698220714489,"beta":6.2831853071795862,"color":2},{"type":"ARC","x1":945.41434669348553,"y1":74.585653306514587,"x2":510,"y2":10,"r":1500,"xm":510,"ym":1510,"alpha":4.71238898038469,"beta":5.006904465492827,"color":2},{"type":"POINT","x1":510,"y1":510,"color":7}]}

let canvas = document.getElementById("myCanvas");
let ctx = canvas.getContext("2d")

// draw the solid body
ctx.beginPath();
elementDetail.element.map((elem, index) => {     
  ctx.moveTo(0,0);
  ctx.arc(elem.xm, elem.ym, elem.r, elem.alpha, elem.beta);   
})
ctx.fillStyle = "#6fd0ff";
ctx.fill();
ctx.closePath();

// draw the outline
elementDetail.element.map((elem, index) => {  
  ctx.beginPath();
  ctx.arc(elem.xm, elem.ym, elem.r, elem.alpha, elem.beta);   
  ctx.stroke();
})
ctx.closePath();  
 canvas{ zoom:.25}  
 <canvas id="myCanvas" width="1200" height="1200"></canvas>  

Комментарии:

1. Что, если данные содержат как линию, так и дугу?

Ответ №2:

Вы пробовали использовать context.fillStyle="your shape colour" ? Я думаю, вы могли бы использовать путь для построения фигуры, поэтому каждый раз, когда вы запускаете path, вам нужно назначить цвет каждой фигуре. Попробуйте нарисовать дугу и полигон отдельно.

 function drawGraphics(ctx){
  ctx.beginPath();
  ctx.fillStyle="#6fd0ff"
  elementDetail.element.reverse().map((elem, index) => {
      if(elem.type==="ARC"amp;amp;index<=8){
        ctx.arc(elem.xm, elem.ym, elem.r, elem.alpha, elem.beta); 
      }
  })
  ctx.stroke()
  ctx.fill();
  ctx.closePath();
}
  

Комментарии:

1. elementDetail.element.map((элемент, индекс) => { ctx.fillStyle = элемент.color; ctx.arc(элемент.xm, элемент.ym, элемент.r, элемент.альфа, элемент.бета); })

2. Я тоже пробовал это, результат все тот же. заполняется только сегмент

3. Я нашел основную причину, по которой заполняются только сегменты. Это потому, что направление самого json неверно. Я проверил параметры в json. Если вы перевернете массив, то можно заполнить и выровнять.