我正在进行R gauge
小部件定制。使用画布属性,我必须将Gauge
的针号从中心针减小到“开始角度”。
this.drawNeedle = this.DrawNeedle = function (value, color, index) {
var type = prop['chart.needle.type'];
co.lineWidth = 0.5;
co.strokeStyle = 'gray';
co.fillStyle = color;
var angle = (this.endAngle - this.startAngle) * ((value - this.min) / (this.max - this.min));
angle += this.startAngle;
if (typeof (prop['chart.needle.size']) == 'object' && prop['chart.needle.size'] && typeof (prop['chart.needle.size'][index]) == 'number') {
var size = prop['chart.needle.size'][index];
} else if (typeof (prop['chart.needle.size']) == 'number') {
var size = prop['chart.needle.size'];
} else {
var size = this.radius - 25 - prop['chart.border.width'];
}
if (type == 'line') {
co.beginPath();
co.lineWidth = prop['chart.needle.width'];
co.strokeStyle = color;
co.arc(this.centerx, this.centery, 82, angle, angle + 0.0001, false);
// co.moveTo(this.centerx-58, this.centery-58);
// co.lineTo(this.centerx-43, this.centery-43);
co.lineTo(this.centerx, this.centery);
if (prop['chart.needle.tail']) {
co.arc(this.centerx, this.centery, this.radius * 0.2, angle + RG.PI, angle + 0.00001 + RG.PI, false);
}
co.lineTo(this.centerx, this.centery);
co.stroke();
} else {
co.beginPath();
co.arc(this.centerx, this.centery, size, angle, angle + 0.00001, false);
co.arc(this.centerx, this.centery, this.centerpinRadius * 0.5, angle + RG.HALFPI, angle + 0.00001 + RG.HALFPI, false);
if (prop['chart.needle.tail']) {
co.arc(this.centerx, this.centery, this.radius * 0.2, angle + RG.PI, angle + 0.00001 + RG.PI, false);
}
co.arc(this.centerx, this.centery, this.centerpinRadius * 0.5, angle - RG.HALFPI, angle - 0.00001 - RG.HALFPI, false);
co.stroke();
co.fill();
this.angle = angle;
}
};
代替大针(从中心到起始角度),小针的尺寸应类似于下图。
答案 0 :(得分:1)
请阅读我在代码中的评论
const canvas = document.getElementById("canvas");
const co = canvas.getContext("2d");
let cw = canvas.width = 200,
cx = cw / 2;
let ch = canvas.height = 200,
cy = ch / 2;
//gauge starts at a1
let a1 = 120*Math.PI/180;
//gauge ends at a1
let a2 = 60*Math.PI/180;
// arrow angle
let a = -60*Math.PI/180;
//gauge angle
let R = 82;
// arrow starts at this distance from the center
let r = 70;
// the center
let c = {x:100,y:100}
// coords to draw the arrow
let x1 = c.x+r*Math.cos(a);
let y1 = c.x+r*Math.sin(a);
let x2 = c.x+(R+5)*Math.cos(a);
let y2 = c.x+(R+5)*Math.sin(a);
co.lineWidth = 5;
co.strokeStyle = 'white';
co.lineCap = "round";
//draw the gauge
co.beginPath();
co.arc(c.x, c.y, R, a1, a2);
co.stroke();
//draw the arrow
co.beginPath();
co.moveTo(x1, y1);
co.lineTo(x2, y2);
co.stroke();
body {
background-color: #222;
}
canvas {
border:1px solid #999;
}
<canvas id="canvas"></canvas>
OP评论:指针应指向刻度值,该值将动态更新。这就是我动态执行的方式:
我正在添加输入类型范围以动态更改角度的值
const canvas = document.getElementById("canvas");
const co = canvas.getContext("2d");
let cw = (canvas.width = 200),
cx = cw / 2;
let ch = (canvas.height = 200),
cy = ch / 2;
// arrow angle
let a = aval.getAttribute("value") * Math.PI / 180;
//gauge starts at a1
let a1 = aval.getAttribute("min") * Math.PI / 180;
//gauge ends at a1
let a2 = aval.getAttribute("max") * Math.PI / 180;
//gauge angle
let R = 82;
// arrow starts at this distance from the center
let r = 70;
// the center
let c = { x: 100, y: 100 };
co.lineWidth = 5;
co.strokeStyle = "white";
co.lineCap = "round";
// a function to draw the gauge
function drawGauge() {
//draw the gauge
co.beginPath();
co.arc(c.x, c.y, R, a1, a2);
co.stroke();
}
// a function to draw the arrow
function drawArrow(a) {
// coords to draw the arrow
let x1 = c.x + r * Math.cos(a);
let y1 = c.x + r * Math.sin(a);
let x2 = c.x + (R + 5) * Math.cos(a);
let y2 = c.x + (R + 5) * Math.sin(a);
//draw the arrow
co.beginPath();
co.moveTo(x1, y1);
co.lineTo(x2, y2);
co.stroke();
}
drawGauge();
drawArrow(a);
aval.addEventListener("input", () => {
// on input the angle of the arrow is changing
let a = parseInt(aval.value) * Math.PI / 180;
// clear the canvas
co.clearRect(0, 0, cw, ch);
// and redraw everything
drawGauge();
drawArrow(a);
});
body {
background-color: #222;
}
canvas {
border:1px solid #999;
}
<canvas id="canvas"></canvas>
<input id="aval" type="range" min="-240" max="60" value="-60" />
OP正在评论:
我的最小值是40,最大值是700 .....所以我需要根据这些值范围之间的值来显示针。
为此,我需要将角度映射到这些值,所以我添加了一个映射函数,并更新了代码:
const canvas = document.getElementById("canvas");
const co = canvas.getContext("2d");
let cw = (canvas.width = 200),
cx = cw / 2;
let ch = (canvas.height = 200),
cy = ch / 2;
let min = parseInt(aval.getAttribute("min"));// min value
let a_min = -240 * Math.PI / 180;// min angle to draw the gauge
let max = parseInt(aval.getAttribute("max"));// max value
let a_max = 60 * Math.PI / 180;// max angle to draw the gauge
let val = parseInt(aval.getAttribute("value"));
let angle = getAngle(val) * Math.PI / 180;
//gauge angle
let R = 82;
// arrow starts at this distance from the center
let r = 70;
// the center
let c = { x: 100, y: 100 };
co.lineWidth = 5;
co.strokeStyle = "white";
co.lineCap = "round";
// a function to draw the gauge
function drawGauge() {
//draw the gauge
co.beginPath();
co.arc(c.x, c.y, R, a_min, a_max);
co.stroke();
}
// a function to draw the arrow
function drawArrow(a) {
// coords to draw the arrow
let x1 = c.x + r * Math.cos(a);
let y1 = c.x + r * Math.sin(a);
let x2 = c.x + (R + 5) * Math.cos(a);
let y2 = c.x + (R + 5) * Math.sin(a);
//draw the arrow
co.beginPath();
co.moveTo(x1, y1);
co.lineTo(x2, y2);
co.stroke();
}
drawGauge();
drawArrow(angle);
aval.addEventListener("input", () => {
// on input the angle of the arrow is changing
let val = parseInt(aval.value);
let angle = getAngle(val);
// clear the canvas
co.clearRect(0, 0, cw, ch);
// and redraw everything
drawGauge();
drawArrow(angle);
});
//a p5.js function
function map5(n, a, stop1, start2, stop2, withinBounds) {
var newval = (n - a) / (stop1 - a) * (stop2 - start2) + start2;
if (!withinBounds) {
return newval;
}
if (start2 < stop2) {
return this.constrain(newval, start2, stop2);
} else {
return this.constrain(newval, stop2, start2);
}
};
function constrain(n, low, high) {
return Math.max(Math.min(n, high), low);
};
function getAngle(val){
return map5(val, min, max, a_min, a_max)
}
body {
background-color: #222;
}
canvas {
border:1px solid #999;
}
<canvas id="canvas"></canvas>
<input id="aval" type="range" min="40" max="700" value="460" />