Ashlis
@Ashlis

Как сделать эффект при наведении на доли круговой canvas — диаграммы?

Хочу сделать эффект при наведении мыши на область диаграммы. Как я понял области разделяются методами beginPath() и closePath() внутри цикла. Интересует как с этими областями можно работать?
Первым аргументом в isPointInPath(path) можно положить как раз этот самый путь. Можно ли его как - то получить с методами beginPath() и closePath() или тут обязательно надо использовать, что - то вроде Path2D() ?

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


Функции отрисовки
function drawLine(ctx, startX, startY, endX, endY){
    ctx.beginPath();
    ctx.moveTo(startX,startY);
    ctx.lineTo(endX,endY);
    ctx.stroke();
}

function drawArc(ctx, centerX, centerY, radius, startAngle, endAngle){
    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, startAngle, endAngle);
    ctx.stroke();
}

function drawPieSlice(id ,ctx,centerX, centerY, radius, startAngle, endAngle, color ){
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.moveTo(centerX,centerY);
    ctx.arc(centerX, centerY, radius, startAngle, endAngle);
    ctx.closePath();
    ctx.fill();
}


Исполняющий класс
let Piechart = function(options){
    this.options = options;
    this.canvas = options.canvas;
    this.ctx = this.canvas.getContext("2d");
    this.colors = options.colors;
 
    this.draw = function(){
        let total_value = 0;
        let color_index = 0;
        let val;
        for (let categ in this.options.data){
            val = this.options.data[categ];
            total_value += val;
        }

        let start_angle = 0;
        for (categ in this.options.data){
            let = this.options.data[categ];
            let slice_angle = 2 * Math.PI * val / total_value;
    
            drawPieSlice(
                Math.round(start_angle),
                this.ctx,
                this.canvas.width/2,
                this.canvas.height/2,
                Math.min(this.canvas.width/2,this.canvas.height/2),
                start_angle,
                start_angle+slice_angle,
                this.colors[color_index%this.colors.length]
            );
 
            start_angle += slice_angle;
            color_index++;
        }
      
      start_angle = 0;
    }
}


Данные для диаграммы
var myVinyls = {
    "Classical music": 10,
    "Alternative rock": 14,
    "Pop": 5,
    "Jazz": 12
};


Инициализация и вызов
var myPiechart = new Piechart(
    {
        canvas:myCanvas,
        data:myVinyls,
        colors:["#fde23e","#f16e23", "#57d9ff","red"]
    }
);

myPiechart.draw();


Обработчик событий
myCanvas.addEventListener('mousemove', function (event) {
  console.log(ctx.isPointInPath(event.offsetX, event.offsetY));
})
  • Вопрос задан
  • 120 просмотров
Решения вопроса 1
twobomb
@twobomb
Да можно типа такого, только у вас косяк еще тут
let = this.options.data[categ];
            let slice_angle = 2 * Math.PI * val / total_value;

наверно предполагалось let val.., поэтому рисовалось еще не правильно
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы