У меня возникли проблемы с вращением круга с помощью холста HTML5. функция об управлении кругом, но масштаб выходит из-под контроля ...
кто-нибудь знает, как настроить (или установить поворот) масштаб, чтобы он соответствовал кругу холста?
Начальный угол (0,7 пи) и конечный угол (0,3 пи). Мне нужно сбросить поворот? -> ctx.rotate (Math.PI * 3/16); -> (math.pi * 15/10 * 1/8)
var degrees = 0;
var color = "lightblue";
var bgcolor = "#222";
var canvas, ctx, W, Htext;
function init_rpm(name, val) {
canvas = document.getElementById(name);
ctx = canvas.getContext("2d");
//dimensions
W = canvas.width;
H = canvas.height;
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.lineWidth = 25;
ctx.strokeStyle = bgcolor;
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.3 * Math.PI, false); //you can see thr src now
ctx.stroke();
//center circle
ctx.save();
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, .2)';
ctx.lineWidth = 10;
ctx.arc(W / 2, H / 2, Math.floor(W / 3) - 40, 0.7 * Math.PI, 0.3 * Math.PI, false);
ctx.stroke();
ctx.restore();
// scale
ctx.save();
ctx.translate(300, 300);
for (var i = 0; i < 9; i++) {
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(255, 255, 255, .3)';
ctx.moveTo(130, 0);
ctx.lineTo(140, 0);
ctx.stroke();
ctx.rotate(Math.PI * 3 / 16);
}
ctx.restore();
//angle in radians =angle in drgrees*pi/180 make color
var percent = val / 8000 * 100;
ctx.beginPath();
ctx.lineWidth = 30;
// ctx.strokeStyle= color;
var my_gradient = ctx.createLinearGradient(0, 150, 250, 300);
my_gradient.addColorStop(0, "#B31918");
my_gradient.addColorStop(1, "#FFA000");
ctx.strokeStyle = my_gradient;
//the arc start from the rightmost end. if we deduct 90 degrees from the angles
//the arc will start from the top most end
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.7 * Math.PI + 1.6 * Math.PI / 100 * percent, false); //you can see thr src now
ctx.stroke();
//add text
ctx.fillStyle = color;
ctx.font = "7vh play";
// text=Math.floor(degrees/360*8)+' RPM';
text = degrees / 360 * 8;
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
ctx.font = "3vh play";
text2 = 'RPM';
ctx.fillText(text2, W / 2 - text_width / 2, H / 2 + 70);
}
function draw(val, name, type) {
// console.info(val);
if (name != "" || name != null) {
if (type == "rpm") {
if (val != "" || val != null) {
degrees = val / 1000 / 8 * 360;
} else {
degrees = 180;
}
init_rpm(name, val);
} else if (type == "kmh") {
if (val != "" || val != null) {
degrees = val;
} else {
degrees = 180;
}
init_kmh(name);
}
} else {
console.info('can not find canvas id');
}
}
$(document).ready(function () {
//canvas init
draw(0, "canvas3", "rpm");
var rpmControl2 = document.querySelector('input[id=get_rpm]');
rpmControl2.addEventListener('input', function () {
draw(this.value, "canvas3", "rpm");
});
});#canvas2{
display:inline;
}
body{
background:#333;
font-family: 'Play', sans-serif;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class = "container-fluid">
<input id = "get_rpm" type = "number" value = "0" min = "0" max = "8000" step = "100" />
<span style = "color:white">RPM</span>
<canvas id = "canvas3" width = "600" height = "600"></canvas>


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Масштаб нарисован путем рисования линий в одном направлении и последующего управления поворотом контекста, чтобы все эти линии указывали под другим углом. Точно так же, как если бы вы всегда держали линейку в одном и том же направлении и просто вращали лист бумаги под ней. Итак, чтобы управлять поворотом вашей шкалы, вы должны установить поворот контекста (или листа бумаги), прежде чем рисовать первую линию.
var ctx = c.getContext('2d');
angle.oninput = function(e) {
ctx.clearRect(0, 0, c.width, c.height);
var rad = angle.value * (Math.PI / 180);
// move the context so its center be at 0,0
ctx.setTransform(1, 0, 0, 1, c.width/2, c.height/2);
// rotate it so we face the required angle
ctx.rotate(rad);
var stepAngle = Math.PI*2 / 14,
innerRad = c.width / 2.8,
outerRad = c.width / 2.5;
ctx.beginPath();
for(var i = 0; i < 12; i++) {
ctx.moveTo(0, innerRad); // move vertically
ctx.lineTo(0, outerRad); // draw line vertically
ctx.rotate(stepAngle); // rotate by fixed increment
}
ctx.stroke(); // all drawn, we can stroke
ctx.setTransform(1, 0, 0, 1, 0, 0); // reset context's position
};
angle.oninput();<input type = "range" min = "0" max = "360" id = "angle"><br>
<canvas id = "c" width = "200" height = "200"></canvas>И с вашим кодом:
var degrees = 0;
var color = "lightblue";
var bgcolor = "#222";
var canvas, ctx, W, Htext;
function init_rpm(name, val) {
canvas = document.getElementById(name);
ctx = canvas.getContext("2d");
//dimensions
W = canvas.width;
H = canvas.height;
//Clear the canvas everytime a chart is drawn
ctx.clearRect(0, 0, W, H);
//Background 360 degree arc
ctx.beginPath();
ctx.lineWidth = 25;
ctx.strokeStyle = bgcolor;
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.3 * Math.PI, false); //you can see thr src now
ctx.stroke();
//center circle
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 255, 255, .2)';
ctx.lineWidth = 10;
ctx.arc(W / 2, H / 2, Math.floor(W / 3) - 40, 0.7 * Math.PI, 0.3 * Math.PI, false);
ctx.stroke();
//EDITS BEGIN HERE
// scale
ctx.setTransform(1, 0, 0, 1, 300, 300);
ctx.beginPath();
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(255, 255, 255, .3)';
// there should be 10 lines
var stepAngle = (Math.PI * 2) / 10;
// begin angle
ctx.rotate(0.7 * Math.PI);
// draw only 9 of the 10 lines
for (var i = 0; i < 9; i++) {
ctx.moveTo(130, 0);
ctx.lineTo(140, 0);
ctx.rotate(stepAngle);
}
ctx.stroke();
ctx.setTransform(1, 0, 0, 1, 0, 0);
//EDITS END HERE
var percent = val / 8000 * 100;
ctx.beginPath();
ctx.lineWidth = 30;
var my_gradient = ctx.createLinearGradient(0, 150, 250, 300);
my_gradient.addColorStop(0, "#B31918");
my_gradient.addColorStop(1, "#FFA000");
ctx.strokeStyle = my_gradient;
//the arc start from the rightmost end. if we deduct 90 degrees from the angles
//the arc will start from the top most end
ctx.arc(W / 2, H / 2, Math.floor(W / 3), 0.7 * Math.PI, 0.7 * Math.PI + 1.6 * Math.PI / 100 * percent, false); //you can see thr src now
ctx.stroke();
//add text
ctx.fillStyle = color;
ctx.font = "7vh play";
// text=Math.floor(degrees/360*8)+' RPM';
text = degrees / 360 * 8;
text_width = ctx.measureText(text).width;
ctx.fillText(text, W / 2 - text_width / 2, H / 2 + 15);
ctx.font = "3vh play";
text2 = 'RPM';
ctx.fillText(text2, W / 2 - text_width / 2, H / 2 + 70);
}
function draw(val, name, type) {
// console.info(val);
if (name != "" || name != null) {
if (type == "rpm") {
if (val != "" || val != null) {
degrees = val / 1000 / 8 * 360;
} else {
degrees = 180;
}
init_rpm(name, val);
} else if (type == "kmh") {
if (val != "" || val != null) {
degrees = val;
} else {
degrees = 180;
}
init_kmh(name);
}
} else {
console.info('can not find canvas id');
}
}
$(document).ready(function () {
//canvas init
draw(0, "canvas3", "rpm");
var rpmControl2 = document.querySelector('input[id=get_rpm]');
rpmControl2.addEventListener('input', function () {
draw(this.value, "canvas3", "rpm");
});
});#canvas2{
display:inline;
}
body{
background:#333;
font-family: 'Play', sans-serif;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>
<div class = "container-fluid">
<input id = "get_rpm" type = "number" value = "0" min = "0" max = "8000" step = "100" />
<span style = "color:white">RPM</span>
<canvas id = "canvas3" width = "600" height = "600"></canvas>Думаю, с scole txt тоже есть проблемы? как я могу вращать число до той же степени ... codepen.io/wanroulin/pen/jxJBvO?editors=1010
@iWJ да, если вы хотите, чтобы весь текст был обращен на север, вам нужно снова повернуть в обратном направлении, взяв положение текста в качестве точки привязки для поворота. Таким образом, вам было бы лучше перемещать только матрицу преобразования контекста и рисовать текст всегда на 0,0. codepen.io/anon/pen/odOWpP?editors=1010
[ссылка] codepen.io/wanroulin/pen/jxJBvO?editors=1010