gpt4 book ai didi

html - 如何使用 Canvas 减少从中心到起始角度的线条大小?

转载 作者:行者123 更新时间:2023-11-28 00:40:18 25 4
gpt4 key购买 nike

我正在处理 R gauge 小部件定制。使用 Canvas 属性,我必须将我的 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;
}

};

enter image description here

而不是大针(从中心到起始角),针的尺寸应该小,类似于下图。

enter image description here

最佳答案

请阅读我在代码中的注释

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" />

更新2

OP 正在评论:

my min value is 40 and max is 700..... So I need to show the needle based on the value between these value range.

为了做到这一点,我需要将角度映射到这些值,所以我添加了一个映射函数并更新了代码:

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" />

关于html - 如何使用 Canvas 减少从中心到起始角度的线条大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53870095/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com