325 lines
9.4 KiB
JavaScript
325 lines
9.4 KiB
JavaScript
const TriggerSrc = document.getElementById ('trigger_src');
|
|
const TriggerMode = document.getElementById ('trigger_mode');
|
|
const TriggerEdge = document.getElementById ('trigger_edge');
|
|
|
|
const MarkerTime = document.getElementById ('time');
|
|
const MarkerVolt = document.getElementById ('volt');
|
|
|
|
const TimeBase = document.getElementById ('time_base');
|
|
const MoveElem = document.getElementById ('move');
|
|
const StartBut = document.getElementById ('Start');
|
|
const ConnectBut = document.getElementById ('Connect');
|
|
const Connected = document.getElementById ('Connected');
|
|
const Canvas = document.getElementById ('canvas');
|
|
var gBGCanvas = null;
|
|
var gMark = {
|
|
type : 'time',
|
|
volt : { a : 0.5, b : 1.0 },
|
|
time : { a : 100, b : 200 },
|
|
};
|
|
|
|
const REF_Y = 3.3;
|
|
const MAX_Y = 4096.0;
|
|
const MAX_X = 1024.0;
|
|
const gTimeStep = [
|
|
2.0e-6, 5.0e-6, 10.0e-6,
|
|
2.0e-5, 5.0e-5, 10.0e-5,
|
|
2.0e-4, 5.0e-4, 10.0e-4,
|
|
2.0e-3, 5.0e-3, 10.0e-3,
|
|
2.0e-2, 5.0e-2, 10.0e-2,
|
|
2.0e-1, 5.0e-1, 1.0, ];
|
|
|
|
var gMZ = { m11 : 1.0, m12 : 0.0, m21 : 0.0, m22 : 1.0, ox : 0.0, oy : 0.0 };
|
|
var gTC = { x : 100.0, y : 2048.0 };
|
|
const gTB = new Array ();
|
|
const gCA = new Array ();
|
|
const gCB = new Array ();
|
|
var gItemToMove = 0, gIndex = 512;
|
|
/************************************************************************/
|
|
var websocket = null;
|
|
var wsUri = null;
|
|
var connected = false;
|
|
|
|
function js_get_id () {
|
|
var host;
|
|
const locate = window.location;
|
|
if (locate.protocol == 'file:') host = 'ws://unknown';
|
|
else if (locate.port) host = 'ws://' + locate.hostname + ':' + (parseInt(locate.port, 10) + 0) + '/ws';
|
|
else host = 'ws://' + locate.hostname + '/ws';
|
|
console.log ('host is: ' + host);
|
|
return host;
|
|
}
|
|
function initWebSocket() {
|
|
try {
|
|
if (typeof MozWebSocket == 'function') WebSocket = MozWebSocket;
|
|
if ( websocket && websocket.readyState == 1 ) websocket.close();
|
|
websocket = new WebSocket( wsUri );
|
|
websocket.onopen = function (evt) {
|
|
ConnectBut.value = 'Disconnect';
|
|
Connected.innerHTML = 'CONNECTED';
|
|
const stored = localStorage.getItem ('mark_store');
|
|
console.log (stored);
|
|
if (stored) {
|
|
gMark = JSON.parse (stored);
|
|
if (gMark.type === 'volt') MarkerVolt.checked = true;
|
|
}
|
|
connected = true;
|
|
};
|
|
websocket.onclose = function (evt) {
|
|
ConnectBut.value = 'Connect';
|
|
Connected.innerHTML = 'DISCONNECTED';
|
|
localStorage.setItem ('mark_store', JSON.stringify (gMark));
|
|
connected = false;
|
|
};
|
|
websocket.onmessage = function (evt) {
|
|
const obj = JSON.parse (evt.data);
|
|
if (Object.hasOwn (obj, 'channel')) {
|
|
RefreshSettings (obj);
|
|
return;
|
|
}
|
|
PrepareChannel (0, obj.a);
|
|
PrepareChannel (1, obj.b);
|
|
DrawAll ();
|
|
};
|
|
websocket.onerror = function (evt) {
|
|
console.log ('ERROR: ' + evt.data);
|
|
};
|
|
} catch (exception) {
|
|
console.log ('EXCEPT: ' + exception);
|
|
}
|
|
}
|
|
/************************************************************************/
|
|
function RefreshSettings (obj) {
|
|
console.log (obj);
|
|
document.getElementById('trigger_src' ).value = obj.channel;
|
|
document.getElementById('trigger_mode').value = obj.mode;
|
|
document.getElementById('trigger_edge').value = obj.rising;
|
|
document.getElementById('time_base' ).value = obj.tim;
|
|
gTC.x = obj.offset; gTC.y = obj.value;
|
|
PrepareBG();
|
|
DrawAll ();
|
|
};
|
|
function ReloadMatrix (sz) {
|
|
const xz = sz.x / MAX_X;
|
|
const yz = sz.y / MAX_Y;
|
|
gMZ.m11 = xz; gMZ.m22 = -yz; gMZ.oy = sz.y;
|
|
};
|
|
function TrPt (x, y) { // matice je diagonalni
|
|
const rx = (x * gMZ.m11 + gMZ.ox);
|
|
const ry = (y * gMZ.m22 + gMZ.oy);
|
|
return { x : rx, y : ry };
|
|
};
|
|
function InPt (x, y) { // matice je diagonalni
|
|
const rx = Math.round ((x - gMZ.ox) / gMZ.m11);
|
|
const ry = Math.round ((y - gMZ.oy) / gMZ.m22);
|
|
return { x : rx, y : ry };
|
|
};
|
|
function SendEvent (evt) {
|
|
console.log (evt);
|
|
if (!connected) return;
|
|
const reply = JSON.stringify(evt);
|
|
websocket.send (reply);
|
|
};
|
|
function PrepareBG () {
|
|
var ctx = gBGCanvas.getContext('2d');
|
|
ctx.fillStyle = "black";
|
|
ctx.fillRect(0, 0, gBGCanvas.width, gBGCanvas.height);
|
|
ctx.lineWidth = 2.0;
|
|
ctx.strokeStyle = 'blue';
|
|
ctx.beginPath();
|
|
var b,e;
|
|
b = TrPt (24, gTC.y);
|
|
e = TrPt (1000, gTC.y);
|
|
ctx.moveTo(b.x, b.y);
|
|
ctx.lineTo(e.x, e.y);
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
b = TrPt (gTC.x, 96);
|
|
e = TrPt (gTC.x, 4000);
|
|
ctx.moveTo(b.x, b.y);
|
|
ctx.lineTo(e.x, e.y);
|
|
ctx.stroke();
|
|
ctx.save();
|
|
// dopsat grid, markers
|
|
ctx.lineWidth = 1.0;
|
|
ctx.strokeStyle = '#808080';
|
|
ctx.setLineDash([4, 10]);
|
|
const stepx = 100, stepm = MAX_Y / REF_Y, stepy = 0.5 * stepm;
|
|
for (let x=stepx; x<MAX_X; x+=stepx) {
|
|
ctx.beginPath();
|
|
b = TrPt (x, 0);
|
|
ctx.moveTo(b.x, b.y);
|
|
e = TrPt (x, MAX_Y);
|
|
ctx.lineTo(e.x, e.y);
|
|
ctx.stroke();
|
|
}
|
|
for (let y=stepy; y<MAX_Y; y+=stepy) {
|
|
ctx.beginPath();
|
|
b = TrPt (0, y);
|
|
ctx.moveTo(b.x, b.y);
|
|
e = TrPt (MAX_X, y);
|
|
ctx.lineTo(e.x, e.y);
|
|
ctx.stroke();
|
|
}
|
|
ctx.restore ();
|
|
ctx.lineWidth = 2.0;
|
|
ctx.strokeStyle = '#FFFF00';
|
|
var ba, bb, ea, eb;
|
|
if (gMark.type === 'time') {
|
|
ba = TrPt (gMark.time.a, 0);
|
|
ea = TrPt (gMark.time.a, MAX_Y - 256);
|
|
bb = TrPt (gMark.time.b, 0);
|
|
eb = TrPt (gMark.time.b, MAX_Y - 256);
|
|
} else {
|
|
ba = TrPt (0, gMark.volt.a * stepm);
|
|
ea = TrPt (MAX_Y, gMark.volt.a * stepm);
|
|
bb = TrPt (0, gMark.volt.b * stepm);
|
|
eb = TrPt (MAX_Y, gMark.volt.b * stepm);
|
|
}
|
|
ctx.beginPath();
|
|
ctx.moveTo(ba.x, ba.y);
|
|
ctx.lineTo(ea.x, ea.y);
|
|
ctx.stroke();
|
|
ctx.beginPath();
|
|
ctx.moveTo(bb.x, bb.y);
|
|
ctx.lineTo(eb.x, eb.y);
|
|
ctx.stroke();
|
|
|
|
var A,B,D;
|
|
const timz = gTimeStep [parseInt (TimeBase.value, 10)];
|
|
if (gMark.type === 'time') {
|
|
const d = (gMark.time.b - gMark.time.a) * timz;
|
|
const z = d === 0 ? 0 : 1.0 / d;
|
|
A = (gMark.time.a * timz).toExponential(2) + 's';
|
|
B = (gMark.time.b * timz).toExponential(2) + 's';
|
|
D = d.toExponential(2) + 's, f='+ z.toExponential(2) + 'Hz';
|
|
} else {
|
|
A = gMark.volt.a.toFixed(2) + 'V';
|
|
B = gMark.volt.b.toFixed(2) + 'V';
|
|
D =(gMark.volt.b - gMark.volt.a).toFixed(2) + 'V';
|
|
}
|
|
const txt = '0.5V/d, Mark A:' + A + ', B:' + B + ', Δ:' + D;
|
|
ctx.font = '16px Arial';
|
|
ctx.fillStyle = '#00FFFF';
|
|
ctx.fillText(txt,100,20);
|
|
};
|
|
function DrawAll () {
|
|
DrawBG ();
|
|
DrawPolyLine (0, '#00FF00');
|
|
DrawPolyLine (1, '#FF0000');
|
|
}
|
|
function DrawBG () {
|
|
var context = Canvas.getContext('2d');
|
|
context.drawImage (gBGCanvas, 0, 0);
|
|
};
|
|
function PrepareChannel (ch, data) {
|
|
var out = ch === 0 ? gCA : gCB;
|
|
if (data.length === 1) {
|
|
out [gIndex] = data [0];
|
|
if (ch === 1) {
|
|
gIndex += 1;
|
|
gIndex = gIndex % 1024;
|
|
}
|
|
} else {
|
|
const max = data.length < 1024 ? data.length : 1024;
|
|
for (let n=0; n<max; n++) {
|
|
out [n] = data [n];
|
|
}
|
|
}
|
|
}
|
|
function DrawPolyLine (ch, col) {
|
|
var out = ch === 0 ? gCA : gCB;
|
|
var ctx = Canvas.getContext('2d');
|
|
ctx.lineWidth = 2.0;
|
|
ctx.strokeStyle = col;
|
|
ctx.beginPath();
|
|
ctx.moveTo (gTB[0], out[0] * gMZ.m22 + gMZ.oy);
|
|
for (let n=1; n<1024; n++) {
|
|
ctx.lineTo(gTB[n], out[n] * gMZ.m22 + gMZ.oy);
|
|
}
|
|
ctx.stroke();
|
|
};
|
|
function MoveMarker (n, p) {
|
|
const q = InPt (p.x, p.y);
|
|
const m = REF_Y / MAX_Y;
|
|
if (gMark.type === 'time') {
|
|
if (n === 0) { gMark.time.a = q.x; } else { gMark.time.b = q.x; }
|
|
} else {
|
|
if (n === 0) { gMark.volt.a = q.y * m; } else { gMark.volt.b = q.y * m; }
|
|
}
|
|
};
|
|
Canvas.addEventListener ('click', function(event) {
|
|
const p = { x : event.clientX, y : event.clientY };
|
|
const q = InPt (p.x, p.y);
|
|
switch (gItemToMove) {
|
|
case 0: gTC.y = q.y; SendEvent ({ type : "trg_val", value: q.y }); break;
|
|
case 1: gTC.x = q.x; SendEvent ({ type : "trg_ofs", value: q.x }); break;
|
|
case 2: MoveMarker (0, p); break;
|
|
case 3: MoveMarker (1, p); break;
|
|
default: return;
|
|
};
|
|
PrepareBG ();
|
|
DrawAll ();
|
|
});
|
|
/************************************************************************/
|
|
TriggerSrc.onchange = (event) => {
|
|
const e = { type : "trg_src", value : parseInt(event.target.value, 10) };
|
|
SendEvent (e);
|
|
};
|
|
TriggerMode.onchange = (event) => {
|
|
const e = { type : "trg_mod", value : parseInt(event.target.value, 10) };
|
|
SendEvent (e);
|
|
const res = event.target.value;
|
|
if (e.value === 2) {
|
|
StartBut.disabled = false;
|
|
} else {
|
|
StartBut.disabled = true;
|
|
}
|
|
};
|
|
TriggerEdge.onchange = (event) => {
|
|
const e = { type : "trg_edg", value : parseInt(event.target.value, 10) };
|
|
SendEvent (e);
|
|
};
|
|
TimeBase.onchange = (event) => {
|
|
const e = { type : "tim_bas", value : parseInt(event.target.value, 10) };
|
|
SendEvent (e);
|
|
};
|
|
MoveElem.onchange = (event) => {
|
|
const e = { type : "mov_ele", value : parseInt(event.target.value, 10) };
|
|
gItemToMove = e.value;
|
|
console.log(e);
|
|
};
|
|
MarkerTime.onclick = (event) => {
|
|
console.log ('time_mark');
|
|
gMark.type = 'time';
|
|
PrepareBG ();
|
|
DrawAll ();
|
|
};
|
|
MarkerVolt.onclick = (event) => {
|
|
console.log ('volt_mark');
|
|
gMark.type = 'volt';
|
|
PrepareBG ();
|
|
DrawAll ();
|
|
};
|
|
window.onload = (event) => {
|
|
const dim = { x : Canvas.clientWidth, y : Canvas.clientHeight };
|
|
Canvas.width = dim.x; Canvas.height = dim.y;
|
|
ReloadMatrix (dim);
|
|
for (let n=0; n<MAX_X; n++) {
|
|
gTB.push (n * gMZ.m11 + gMZ.ox);
|
|
gCA.push (2000);
|
|
gCB.push (1000);
|
|
}
|
|
wsUri = js_get_id ();
|
|
gBGCanvas = new OffscreenCanvas (dim.x, dim.y);
|
|
};
|
|
function Connect () {
|
|
if (connected) {
|
|
websocket.close();
|
|
} else {
|
|
initWebSocket ();
|
|
}
|
|
};
|
|
function Start () {
|
|
SendEvent ({ type : 'start', value : 1 });
|
|
};
|