基於前端le5le-topology寫一個自定義的元件(溫度計)
阿新 • • 發佈:2021-01-25
這樣寫出來的自定義元件就是靈活的,可以自己隨意修改值。也可以通過後臺,動態改變。
自定義資料 name 對應值為自定義函式的名。
{
name: 'thermometer',
icon: 't-icon t-rect',
data: {
rect: {
width: 60,
height: 250,
},
name: 'thermometer',
value:10,
data: {
thermometer: { Maximum:20,Minimum:-20,criticalValue:0,thresholdsColor:"#F40" },
},
},
},
TS 程式碼
declare const window: any;
程式碼入口
export function thermometer(ctx: CanvasRenderingContext2D, node: any) {
const R = Math.floor(node.rect.width / 2);
//獲取畫布節點的寬度。計算出大R。
const r = Math.round((R * 1) / 2);
ctx.fillStyle = node?.value > node?.data?.thermometer?.criticalValue ? node?.data?.thermometer?.thresholdsColor : node?.fillStyle ?? '#FF3C65';
//這裡是一個三元,和js2020 新語法。可以去了解一下
ctx.fill();
drawScale(ctx, node);
ctx.clearRect(node?.rect.x + r, node?.rect.y, node?.rect?.width - R, getYByValue (node,node?.value));
createdthermometer(ctx,node);
}
//畫骨架
function createdthermometer(ctx: CanvasRenderingContext2D, node: any){
const R = Math.floor(node.rect.width / 2)
const r = Math.round((R * 1) / 2)
ctx.beginPath();
ctx.lineWidth = node?.lineWidth;
// 上半個圓形
ctx.arc(node.rect.x + R, node.rect.y + r, r, 0, Math.PI, true);
// 下半個圓形
const theta = Math.acos((r * 1.0) / R);
ctx.arc(
node.rect.x + R,
node.rect.y + node.rect.height - R,
R,
theta + Math.PI,
-theta,
true
);
ctx.closePath();
ctx.stroke();
}
function getYByValue(node:any,v:number) {
const R = Math.floor(node.rect.width / 2);
const r = Math.round((R * 1) / 2);
const min = node?.data?.thermometer?.Minimum;
const max = node?.data?.thermometer?.Maximum;
// 刻度線總高度
const height = node.rect.height - 2 * R - 2 * r;
// 起始刻度線所在位置
const zeroY = node.rect.height - 2 * R;
//每條刻度線的距離。
const dy = height / (max - min);
return zeroY - dy * v + dy * min; //返回當前值的刻度位置, (+ dy * min) 的意義是,假設min < 0 。要加上超出的位置的距離。
}
// 畫刻度線
function drawScale(ctx: CanvasRenderingContext2D, node: any){
const R = Math.floor(node.rect.width / 2);
const r = Math.round((R * 1) / 2);
const min = node?.data?.thermometer?.Minimum;
const max = node?.data?.thermometer?.Maximum;
let x = node.rect.ex -r;
let ey = node.rect.y;
ctx.fillStyle = node.font.color ?? '#000';
for (let i = min; i <= max; i++) { // 刻度線
const y = getYByValue(node,i);
ctx.beginPath();
ctx.moveTo(x, y + ey);
if (i % 10 == 0) {
ctx.lineWidth = 2;
ctx.lineTo(x + r * 2 / 3, y + ey );
ctx.fillText(i as any, x + 15, y + 6 + ey);
ctx.stroke();
} else {
ctx.lineWidth = 1;
if (i % 5 == 0) {
ctx.lineTo(x + r / 2, y + ey );
} else {
ctx.lineTo(x + r / 3, y + ey );
}
}
ctx.stroke();
}
}
//溫度計上的錨點
export function thermometerAnchors(node: any) {
node.anchors.push(new window.topologyPoint(node.rect.x , node.rect.y + node.rect.height / 2, 4) );
node.anchors.push(new window.topologyPoint(node.rect.x + node.rect.width / 2, node.rect.y, 1));
node.anchors.push(new window.topologyPoint(node.rect.x + node.rect.width, node.rect.y + node.rect.height / 2, 2));
node.anchors.push(new window.topologyPoint(node.rect.x + node.rect.width / 2, node.rect.y + node.rect.height, 3));
}
註冊節點。
export function register() {
window.registerTopologyNode('thermometer', thermometer, thermometerAnchors);
}
mounted() {
register();
}
寫的不好,可以去看官網文件,有詳解。