Внимание! Это дубль вопроса с тостера! Автор не я, просто вопрос показался интересным:
Добрый день. Возникла необходимость сверстать круговую диаграмму с фоновым изображением, что бы можно было редактировать процент заполнения. Пытался сделать с помощью SVG, но скудные знания в этой области не позволили это реализовать. Причем нужно решение без использования jQuery библиотек, можно на ванильном JS, либо с использованием VUE.
UPD: Полупрозрачная подложка под диаграммой просто отдельное изображение, которого потенциально может и не быть. Интересует только создание диаграммы.
UPD 2: Я в курсе что нарушил Правила сообщества, не предоставив хоть попыток решения, но я считаю, здесь вопрос не кода, а подхода к решению данного вопроса.
На картинку наложена маска из серого круга и белого сектора.
Для того чтобы нарисовать сектор нужно посчитать вторую точку дуги по формуле.
addEventListener('mousemove', e => {
// процент заполнения
let percent = Math.min(99.99, Math.max(0, (e.y-20)/(innerHeight-40)*100));
// радиус сектора
let r = 120;
// угол второй точки сектора
let angle = percent/50*Math.PI - Math.PI/2;
// признак большой дуги
let largeArc = percent > 50 ? 1 : 0;
// аргументы команды ARC
let arc = [r, r, 0, largeArc, 1, Math.cos(angle)*r, Math.sin(angle)*r];
// устанавливаем сектору
path.setAttribute('d', `M0,${-r}A${arc}L0,0z`);
text.innerHTML = percent.toFixed() + "%";
});
<body style="margin:0;overflow:hidden">
<svg viewbox="-150 -150 300 300" style="height:100vh" id=svg>
<defs>
<mask id=mask>
<circle r=100 fill=gray></circle>
<path id=path fill=white></path>
</mask>
</defs>
<text id=text text-anchor=middle font-size=28px font-family=arial y=-122></text>
<image mask="url(#mask)" width=300 height=300 x=-150 y=-150
xlink:href="https://picsum.photos/id/63/300/300"></image>
</svg>
</body>
По просьбам трудящихся добавляю вариант с канвой, тут уже почти ничего считать не надо, т.к. на входе у команды рисующей дугу уже углы.
let ctx = canvas.getContext('2d');
let image = new Image();
image.src = "https://picsum.photos/id/63/300/300";
image.onload = e => draw(ctx.fillStyle = ctx.createPattern(image, 'repeat'));
addEventListener('mousemove', draw);
function draw(e){
let percent = Math.min(99.99, Math.max(0, (e.y||0-20)/(innerHeight-40)*100));
let angle = percent/50*Math.PI - Math.PI/2;
ctx.clearRect(0, 0, canvas.width, canvas.height);
arc(0.5, 100, 0, Math.PI*2);
arc(1.0, 120, -Math.PI/2, angle);
}
function arc(alpha, radius, startAngle, endAngle){
ctx.globalAlpha = alpha
ctx.beginPath();
ctx.arc(canvas.width/2,canvas.height/2,radius,startAngle,endAngle);
ctx.lineTo(canvas.width/2,canvas.height/2);
ctx.fill();
}
<canvas id=canvas width=300 height=300/>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Для выгрузки операций из БД на html-странице есть 2 окна для ввода периода времени "с" и "по"Если написать в коде страницы: body onload = "ShowMonthDate();", то при...
У меня есть сетка товаров сделанная на гридахКоличество товаров в ряду - 4, рядов может неопределенное количество
Дорого времени суток! Я пишу WPF контрол экранной клавиатурыУ нее должен быть режим пароля
Всем доброго времени сутокРаботаю с 8-битными индексированными изображениями в формате png