星座图
Some checks failed
/ lint-build-and-check (push) Failing after 2m57s
/ build-and-deploy-to-vercel (push) Failing after 3m0s
/ surge (push) Successful in 2m39s
/ playwright (push) Successful in 1m2s

This commit is contained in:
严浩
2025-04-07 16:56:04 +08:00
parent c06cc44cbd
commit 371b7a71c9
10 changed files with 8064 additions and 5 deletions

View File

@ -0,0 +1,60 @@
<script setup lang="ts">
import { onMounted } from 'vue';
import { 星座图示例数据_50点 } from './_星座图示例数据_50.js';
import { PlanisphereWidget } from './planispherewidget.js'; // 导入 onMounted
definePage({
meta: {
title: '星座图',
},
});
// 在组件挂载后执行
onMounted(() => {
// 创建 PlanisphereWidget 实例,指定容器 ID
const widget = new PlanisphereWidget('constellation-container', {
// 可以根据需要传递配置选项,例如背景色
bg_color: '#1e1e2f',
border_color: '#4a4a6a',
wave_color: '#00bcd4', // 更改波形颜色以便更清晰
});
// 调用 feed 方法绘制星座图
// 默认 viewmodel 为 0会调用 drawWave_planis
widget.feed(星座图示例数据_50点);
// 如果需要明确设置模式(虽然默认就是星座图)
// widget.setViewMode(0); // 0=星座图
// widget.feed(testData);
// 如果想测试余晖效果
// widget.setViewMode(3); // 3=余晖图
// setInterval(() => {
// const newData = [];
// for (let i = 0; i < 20; i++) { // 每次添加少量新点
// const x = Math.random() * 2 - 1;
// const y = Math.random() * 2 - 1;
// newData.push([x, y]);
// }
// widget.feed(newData); // 传入新数据以观察余晖
// }, 500); // 每 500ms 更新一次
});
</script>
<template>
<div>
<h2>星座图示例</h2>
<!-- 添加一个具有 ID div 作为 Konva 的容器 -->
<div id="constellation-container" class="canvas-container"></div>
</div>
</template>
<style scoped>
.canvas-container {
width: 500px; /* 设置容器宽度 */
height: 500px; /* 设置容器高度 */
border: 1px solid #ccc; /* 添加边框以便观察容器位置 */
margin-top: 20px;
}
</style>

View File

@ -0,0 +1,112 @@
/* eslint-disable unicorn/numeric-separators-style */
// const numberOfPoints = 100
// for (let i = 0; i < numberOfPoints; i++) {
// // 生成 [-1, 1] 范围内的随机 x, y 坐标
// const x = Math.random() * 2 - 1
// const y = Math.random() * 2 - 1
// testData.push([x, y])
// }
export const _100点 = [
[0.21363714678690515, -0.3663730133534915],
[-0.3049424523923636, 0.46250294568227446],
[0.5763977559044402, 0.2905029629148188],
[-0.42717461634876486, -0.0599718875542008],
[0.8873878653064973, -0.7027102303960167],
[0.5920730284007314, -0.13550715036563976],
[-0.0072958263326332595, -0.48565095117616086],
[0.3248803851104163, 0.3811487646297467],
[-0.9124332096117334, 0.17517838456659462],
[0.7489008990919834, 0.2733556286067682],
[0.3234310944305949, 0.7807692000618618],
[0.6430157249404669, -0.43219878105872267],
[-0.9481784971106835, 0.6559912547850726],
[0.8514412070737949, -0.35129583674112674],
[-0.6966065981636458, -0.3835624477243509],
[-0.24621180866026338, 0.14263022509825873],
[-0.008212464861134805, -0.12409436823057729],
[-0.18614403246305566, -0.040154026805054865],
[0.8131697020253128, -0.7366788871187182],
[0.047520577466690916, 0.4370624724129999],
[0.8637972276658736, 0.1876669945706062],
[0.22992164251178226, 0.3806822879694305],
[-0.3248744576028255, 0.014121075416148265],
[-0.1721479993412569, 0.996715342965949],
[0.22960118628005644, 0.4280335247554554],
[-0.9086633187680739, 0.33836219445724613],
[-0.3877168247773146, 0.22687545210257465],
[-0.8513753146325116, 0.6634579474907081],
[0.2757705984162848, -0.46081706725021476],
[-0.18577235165325812, -0.4925564276232488],
[-0.7384064287646008, -0.025076297234075007],
[-0.246632132631597, -0.5044200562907697],
[-0.9729796335084444, 0.40803320077892047],
[-0.8700742610238659, 0.1359266803485042],
[0.11734759539234996, 0.603289998105327],
[0.3223384800483904, -0.4711947485904868],
[0.9884350528954153, 0.5070306650478877],
[0.334118866032016, 0.23421838147674245],
[-0.7685379794563654, 0.32955063319059774],
[0.44389262139742636, 0.1683379290525926],
[-0.07731307812783128, -0.35794315390741116],
[0.10949833776644757, 0.6605521725418899],
[0.20116702336133363, -0.6849055364202248],
[0.45656304101466283, 0.598512211642408],
[-0.252238546795192, 0.3353886528144425],
[-0.0584193639148336, 0.525317225974075],
[-0.3260245859112956, 0.4940851928264005],
[-0.7529522389176406, 0.7605406504973962],
[-0.30394066411712317, -0.6882224402231423],
[-0.1516316506123052, -0.7110117257975521],
[-0.02582907354899011, 0.5219983137479713],
[-0.4210088065460973, -0.1972583644595285],
[-0.8504028521438651, 0.2411769630652405],
[0.7741409831957538, 0.5420776559640528],
[0.5215217202248721, 0.01695662589022895],
[-0.7573777724043325, 0.7369690220426113],
[-0.7080310996357289, -0.18974860993709886],
[0.22548121664379783, 0.6555023556490953],
[0.06882569839490449, -0.04883956599466521],
[-0.914137143803265, 0.26953477628275313],
[-0.22096000035551744, 0.8474057732914777],
[0.8795056788551432, -0.04767153439148708],
[-0.5693073903072123, 0.1845416590402813],
[-0.8420489619056974, -0.3965980052642992],
[-0.11194976130639889, 0.4928536605031355],
[0.28600205690506586, 0.9544902837612133],
[0.5477644825486052, 0.7847988760760962],
[-0.24869908778383665, -0.6470745752898646],
[-0.6912035577283631, -0.056120871599610656],
[-0.6505182790989161, 0.41533498405806],
[-0.2575744767189039, 0.4389391929092006],
[0.16257340669789588, -0.5762062097517071],
[0.7199139714644798, 0.30913697931329764],
[0.7547097920993389, 0.5069242321168623],
[0.12369081509711055, -0.06731255961184557],
[0.5344827496023894, -0.5424248906300813],
[0.634433441656145, 0.4562639892002007],
[0.39520488595278924, 0.6986258973762778],
[-0.32004796518840717, 0.4165468864260935],
[0.9767362385058369, -0.8531153384376036],
[-0.28140349767511497, -0.20284430650097218],
[-0.26787201583558495, 0.05245571528936899],
[0.7413912554069997, 0.389840184669094],
[0.2774714978147965, 0.4047831143909977],
[0.7653587324493083, 0.9801723380002705],
[0.8449431820669029, -0.60887149918718],
[-0.8238411033170792, 0.4563915959793903],
[0.23178399415513407, 0.988099210128994],
[0.6774945465104807, -0.6201598374502229],
[-0.23170899732623207, -0.38262999463577585],
[0.8094407444086347, -0.9003566566619849],
[0.4522668741985343, -0.7256489369376415],
[-0.6815751067335964, 0.5550548305239227],
[-0.18061411667914884, 0.6200462607613331],
[0.8273789155477869, 0.03209157246939487],
[0.8362462565242788, 0.4381943409257538],
[0.3901082433072811, -0.7249986420086525],
[-0.9996583265812691, 0.1244453914861341],
[-0.2630950110928403, 0.5754914126206647],
[-0.37193932019270637, -0.07271803571179047],
];

View File

@ -0,0 +1,58 @@
/* eslint-disable unicorn/numeric-separators-style */
// export const 星座图示例数据 = Array.from({ length: 50 }, () => [
// (Math.random() - 0.5) * 1.8, // x 坐标在 -0.9 到 0.9 之间 (避免太靠近边缘)
// (Math.random() - 0.5) * 1.8, // y 坐标在 -0.9 到 0.9 之间
// ]) as const;
export const _50点 = [
[0.20898877234451796, 0.8329353515647436],
[-0.6589349632101078, 0.5886313023998213],
[-0.5525702944049637, -0.7953057951401711],
[-0.7286802811178293, -0.13748979414481416],
[0.14913740071943704, -0.522854879374756],
[0.8488154787364501, -0.5861295932153839],
[0.8624885393093125, 0.3074491250075289],
[-0.2343397554419738, 0.7188825753635304],
[0.20212765614417344, -0.2890128110044041],
[-0.19707322005818997, -0.6870478750347606],
[0.5854675629512068, -0.8368442650963684],
[0.09803006451892214, -0.3125201636107396],
[0.20272647398499002, 0.5816458166058257],
[0.42711062084774276, 0.7351269753064013],
[-0.04213094098741941, -0.03908247574723105],
[-0.25548327059417436, -0.27678686772429817],
[0.11106238126237485, 0.6662930766519914],
[-0.2934624459808759, -0.5961291437670906],
[0.8160933257874935, 0.6504846073142646],
[-0.047329705669115256, 0.20186667633801933],
[0.5414090034330172, -0.6144068205148969],
[-0.4038036936769534, -0.8851239874177442],
[-0.2479685372538528, 0.18610585058251922],
[0.1679363017630682, -0.6988109065768248],
[0.7481286052134636, 0.7710708533549472],
[-0.8716647296944757, -0.04351748246681442],
[0.06417983986542519, 0.7593528839137039],
[0.22415295736769536, 0.018886780890588217],
[-0.19259655979092496, 0.2948187898105549],
[0.18764246792757017, -0.7555801415456128],
[-0.4411407445051105, -0.2560903463496074],
[-0.49580983354966224, -0.12146263028149436],
[0.724240942038349, 0.21056744129122174],
[0.23997508610723733, 0.6649178713483602],
[-0.4184485374073378, 0.0402199731045928],
[0.6477516159740487, 0.8727895544617056],
[0.3445814818072597, -0.7279603899182095],
[-0.21256718232078176, 0.6310693070982953],
[0.1657970728094785, 0.6705099741461983],
[0.3637242806323097, 0.6695322112050762],
[-0.5404468994895113, 0.3425250597752695],
[-0.05164675195167974, -0.47688106891973275],
[0.14678198434124787, 0.8234483395132538],
[0.44149909466870313, -0.223205933404428],
[-0.05478287781815774, -0.5456000090176168],
[0.7940074021771125, 0.6493060427855019],
[-0.47764282879519254, 0.6365124273535734],
[0.14039652915911924, -0.8016960339708364],
[-0.4950654418652219, 0.8789853092911614],
[0.7868284493275342, 0.2351654187769108],
] as const;

7379
src/pages/Page/canvas/konva.2.4.2.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,442 @@
import './konva.2.4.2.min';
export class PlanisphereWidget {
constructor(id, options) {
console.log('PlanisphereWidget ' + id);
this.options = options;
this.container = document.getElementById(id);
this.bg_color = options && options.bg_color ? options.bg_color : '#27293D';
this.fore_color = options && options.bg_color ? options.bg_color : '#CCCCCC';
this.coor_color = options && options.coor_color ? options.coor_color : '#1B1B24';
this.border_color = options && options.border_color ? options.border_color : '#CCCCCC';
this.wave_color = options && options.wave_color ? options.wave_color : '#1D8CF8';
this.margin_left = options && options.margin_left ? options.margin_left : 0;
this.margin_top = options && options.margin_top ? options.margin_top : 0;
this.stage = new Konva.Stage({
container: id,
width: this.container.clientWidth || 500,
height: this.container.clientHeight || 500,
});
this.layer_coor = new Konva.Layer();
this.layer_coor.hitGraphEnabled(false);
this.layer_wave = new Konva.Layer();
this.layer_wave.hitGraphEnabled(false);
this.stage.add(this.layer_coor);
this.stage.add(this.layer_wave);
this.canvas = document.createElement('canvas');
this.ctx_canvas = this.canvas.getContext('2d');
this.ctx_canvas.fillStyle = this.bg_color;
this.init();
// this.initResize();
this.dAlpha = false;
this.d1 = null;
this.d2 = null;
this.d3 = null;
this.d4 = null;
}
init() {
if (this.container.clientHeight === 0) return;
this.stage.setWidth(this.container.clientWidth);
this.stage.setHeight(this.container.clientWidth);
this.area_x = this.margin_left;
this.area_y = this.margin_top;
this.area_width = this.stage.getWidth() - this.margin_left;
this.area_height = this.stage.getHeight() - this.margin_top;
this.drawCoor();
this.canvas.height = this.area_height;
this.canvas.width = this.area_width;
this.ctx_canvas.strokeStyle = this.wave_color;
this.ctx_canvas.lineWidth = 1;
this.pointer = new Konva.Circle({
x: 0,
y: 0,
radius: 1,
stroke: this.wave_color,
strokeWidth: 1,
});
this.pointer.cache();
}
drawCoor() {
var layer = this.layer_coor;
layer.destroyChildren();
var len = this.area_width;
var rval = this.area_width / 2;
layer.add(
new Konva.Rect({
x: this.area_x,
y: this.area_y,
width: this.area_width,
height: this.area_height,
stroke: this.border_color,
strokeWidth: 1,
}),
);
layer.add(
new Konva.Line({
points: [0, 0, this.area_width, this.area_height],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Line({
points: [this.area_width, 0, 0, this.area_height],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Line({
points: [0, rval, this.area_width, rval],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Line({
points: [0, rval / 2, this.area_width, rval / 2],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Line({
points: [0, (rval / 2) * 3, this.area_width, (rval / 2) * 3],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
///
layer.add(
new Konva.Line({
points: [rval, 0, rval, len],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Line({
points: [rval / 2, 0, rval / 2, len],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Line({
points: [(rval / 2) * 3, 0, (rval / 2) * 3, len],
stroke: this.border_color,
strokeWidth: 1,
lineJoin: 'round',
dash: [1, 1],
}),
);
layer.add(
new Konva.Circle({
x: rval,
y: rval,
radius: rval,
stroke: this.border_color,
strokeWidth: 1,
}),
);
layer.add(
new Konva.Circle({
x: rval,
y: rval,
radius: rval / 2,
stroke: this.border_color,
strokeWidth: 1,
}),
);
layer.batchDraw();
}
setViewMode(vm) {
if (vm == 3) {
//0=星座图3=余晖图。2021.03.31李伟添加;
this.dAlpha = true;
vm = 0;
} else {
this.dAlpha = false;
}
this.viewmodel = vm;
this.clear();
}
//星座图
feed(d, di, dq) {
if (!this.viewmodel || this.viewmodel == 0) {
this.drawWave_vector(d);
// this.drawWave_planis(d);
return;
}
}
//矢量图
feedVector(d) {
if (!this.viewmodel || this.viewmodel == 0) {
this.drawWave_vector(d);
return;
}
}
//眼图
feedIQ(di, dq) {
if (this.viewmodel == 1 && di != null) {
this.drawIQ(di);
} else if (this.viewmodel == 2 && dq != null) {
this.drawIQ(dq);
}
}
drawIQ(IQBuff) {
this.clear();
for (var j = 0; j < IQBuff.length; j++) {
this.drawWave_eye(IQBuff[j]);
}
}
clear() {
this.imgData = null;
this.drawWave_planis([]);
this.drawWave_vector([]);
}
drawWave_eye(d) {
// console.log("in drawWave_eye" + d.length);
var layer = this.layer_wave;
var width = this.area_width;
var height = this.area_height;
var rwidth = width / 2;
var rHeight = height / 2;
var ctx_canvas = layer.getContext();
ctx_canvas.strokeStyle = this.wave_color;
ctx_canvas.lineWidth = 1;
ctx_canvas.beginPath();
for (var n = 0; n < d.length; n++) {
//var x = Math.floor(width*(1-1/1.4)/2+ n * width / d.length / 1.4);
var x = Math.floor((n * width) / d.length);
var y = Math.floor(rHeight + (d[n] * rHeight) / 1.4);
if (n == 0) {
ctx_canvas.moveTo(x, y);
} else {
ctx_canvas.lineTo(x, y);
}
}
ctx_canvas.stroke();
}
drawWave_planis(d) {
//console.log("in plan" + d.length);
var layer = this.layer_wave;
var width = this.getDrawWHByPixelRatio(this.area_width);
var height = this.getDrawWHByPixelRatio(this.area_height);
var rwidth = width / 2;
var rHeight = height / 2;
//不显示的时候不报错
if (!width || !height || width == 0 || height == 0) {
return;
}
var context = layer.getContext();
context.clearRect(0, 0, width, height);
var imgData = context.createImageData(width, height);
var dlen = imgData.data.length;
//2021.03.31 李伟增加余晖效果
if (this.dAlpha && d) {
this.drawWave_plainsD(rwidth, rHeight, width, imgData, dlen, this.d4, 32);
this.drawWave_plainsD(rwidth, rHeight, width, imgData, dlen, this.d3, 32);
this.drawWave_plainsD(rwidth, rHeight, width, imgData, dlen, this.d2, 64);
this.drawWave_plainsD(rwidth, rHeight, width, imgData, dlen, this.d1, 128);
this.d4 = this.d3;
this.d3 = this.d2;
this.d2 = this.d1;
this.d1 = d;
}
this.drawWave_plainsD(rwidth, rHeight, width, imgData, dlen, d, 255);
/*
for (var n = 0; n < d.length; n++) {
//console.log(rwidth+d[n][0] * rwidth);
var x = Math.floor(rwidth + d[n][0] * rwidth/1.4);
var y = Math.floor(rHeight+ d[n][1] * rHeight/1.4);
var p = ( y * width + x )* 4;
this.setWaveColor(imgData, p, dlen,width*4);
}
*/
context.putImageData(imgData, 0, 0);
}
drawWave_plainsD(rwidth, rHeight, width, imgData, dlen, d, a) {
if (!d) return;
for (var n = 0; n < d.length; n++) {
//console.log(rwidth+d[n][0] * rwidth);
var x = Math.floor(rwidth + (d[n][0] * rwidth) / 1.4);
var y = Math.floor(rHeight + (d[n][1] * rHeight) / 1.4);
var p = (y * width + x) * 4;
this.setWaveColor(imgData, p, dlen, width * 4, a);
}
}
drawWave_vector(d) {
var maxLine = 100;
var dlen = Math.min(maxLine, d.length);
var layer = this.layer_wave;
var width = this.area_width;
var height = this.area_height;
var rwidth = width / 2;
var rHeight = height / 2;
//不显示的时候不报错
if (!width || !height || width == 0 || height == 0) {
return;
}
var context = layer.getContext();
context.clearRect(0, 0, width, height);
var ctx_canvas = layer.getContext();
ctx_canvas.strokeStyle = this.wave_color;
ctx_canvas.lineWidth = 1;
ctx_canvas.beginPath();
for (var n = 0; n < dlen; n++) {
var x = Math.floor(rwidth + (d[n][0] * rwidth) / 1.2);
var y = Math.floor(rHeight + (d[n][1] * rHeight) / 1.2);
if (n == 0) {
ctx_canvas.moveTo(x, y);
} else {
ctx_canvas.lineTo(x, y);
}
}
ctx_canvas.stroke();
}
/*像素单位转css单位,该函数返回当前浏览器缩放比例所影响的 x y width height 的绘图位置
仅适用putImageData getImageData等函数*/
getDrawWHByPixelRatio(xory) {
if (xory == 0) return 0;
if (!xory) return xory;
var ret = Math.ceil(window.devicePixelRatio * xory);
//console.log(`xory=${xory} ratio=${window.devicePixelRatio} ret=${ret}`);
return ret;
}
setWaveColor_thin(imgData, p, dlen, rowlen) {
var dp = p + rowlen;
if (p < 0) return;
if (dp + 11 >= dlen) return;
imgData.data[p] = 33;
imgData.data[p + 1] = 129;
imgData.data[p + 2] = 247;
imgData.data[p + 3] = 255;
}
setWaveColor(imgData, p, dlen, rowlen, a = 255) {
//2021.03.31 李伟增加余晖效果 a=alpha
var dp = p + rowlen;
if (p < 0) return;
if (dp + 11 >= dlen) return;
var r = 33;
var g = 129;
var b = 247;
if (a != 255) {
r = 0;
g = 255;
b = 0;
}
//console.log(a);
imgData.data[p] = r;
imgData.data[p + 1] = g;
imgData.data[p + 2] = b;
imgData.data[p + 3] = a; //255;//2021.03.31 李伟增加余晖效果
imgData.data[p + 4] = r;
imgData.data[p + 5] = g;
imgData.data[p + 6] = b;
imgData.data[p + 7] = a; //255;
imgData.data[p + 8] = r;
imgData.data[p + 9] = g;
imgData.data[p + 10] = b;
imgData.data[p + 11] = a; //255;
imgData.data[dp] = r;
imgData.data[dp + 1] = g;
imgData.data[dp + 2] = b;
imgData.data[dp + 3] = a; //255;
imgData.data[dp + 4] = r;
imgData.data[dp + 5] = g;
imgData.data[dp + 6] = b;
imgData.data[dp + 7] = a; //255;
imgData.data[dp + 8] = r;
imgData.data[dp + 9] = g;
imgData.data[dp + 10] = b;
imgData.data[dp + 11] = a; //255;
}
destroy() {
this.imgData = null;
this.stage.destroy();
this.color_map = null;
}
dispose() {
console.log('dispose wfmin');
this.destroy();
}
// initResize() {
// var _self = this;
// $(this.container).resize(function () {
// var target = this;
// if (target.resizeFlag) {
// clearTimeout(target.resizeFlag);
// }
// target.resizeFlag = setTimeout(function () {
// _self.init();
// target.resizeFlag = null;
// }, 100);
// });
// }
}