Established several improvments: disabled buttons work more like expected. Started a display UI feature for showing the screen vs the image.
This commit is contained in:
parent
3291201e34
commit
9d27d59e29
|
@ -1,18 +1,33 @@
|
||||||
|
|
||||||
|
interface StateDimensions {
|
||||||
|
width? : number,
|
||||||
|
height? : number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StateOffset {
|
||||||
|
x? : number,
|
||||||
|
y? : number
|
||||||
|
}
|
||||||
|
|
||||||
interface SequenceState {
|
interface SequenceState {
|
||||||
hash : string,
|
hash : string,
|
||||||
name : string,
|
name? : string,
|
||||||
progress : number,
|
progress? : number,
|
||||||
current? : number
|
current? : number,
|
||||||
|
frames? : number,
|
||||||
|
status? : any
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
width? : number,
|
display? : StateDimensions,
|
||||||
height? : number,
|
offset? : StateOffset,
|
||||||
sequence? : SequenceState
|
source? : StateDimensions,
|
||||||
|
screen? : StateDimensions,
|
||||||
|
sequence? : SequenceState,
|
||||||
|
exposure? : number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
cmd? : string;
|
cmd? : string;
|
||||||
state? : State;
|
state? : State;
|
||||||
sequence? : string;
|
|
||||||
}
|
}
|
121
browser/index.ts
121
browser/index.ts
|
@ -1,4 +1,58 @@
|
||||||
|
enum SequenceStatus {
|
||||||
|
IDLE,
|
||||||
|
RUNNING,
|
||||||
|
PAUSED
|
||||||
|
}
|
||||||
|
|
||||||
|
class Display {
|
||||||
|
private parentElement : HTMLUListElement;
|
||||||
|
private canvas : HTMLCanvasElement;
|
||||||
|
private ctx : CanvasRenderingContext2D;
|
||||||
|
private screen : any;
|
||||||
|
constructor () {
|
||||||
|
this.parentElement = document.getElementById('display') as HTMLUListElement;
|
||||||
|
this.create();
|
||||||
|
}
|
||||||
|
private create () {
|
||||||
|
this.canvas = this.parentElement.getElementsByTagName('canvas')[0];
|
||||||
|
this.ctx = this.canvas.getContext('2d');
|
||||||
|
this.screen = {
|
||||||
|
width : parseInt((document.getElementById('width') as HTMLInputElement).value),
|
||||||
|
height : parseInt((document.getElementById('height') as HTMLInputElement).value)
|
||||||
|
}
|
||||||
|
this.updateSize();
|
||||||
|
}
|
||||||
|
private updateSize () {
|
||||||
|
const w : number = this.parentElement.clientWidth - 12;
|
||||||
|
const h : number = this.parentElement.clientHeight - 12;
|
||||||
|
const clientRatio : number = w / h;
|
||||||
|
const screenRatio : number = this.screen.width / this.screen.height;
|
||||||
|
let val : number;
|
||||||
|
let offset : number;
|
||||||
|
console.log(`${w},${h}`);
|
||||||
|
this.canvas.width = w;
|
||||||
|
this.canvas.height = h;
|
||||||
|
this.ctx.strokeStyle = "rgb(0, 0, 255)";
|
||||||
|
|
||||||
|
if (screenRatio > clientRatio) {
|
||||||
|
val = Math.floor(w / screenRatio);
|
||||||
|
offset = Math.round((h - val) / 2);
|
||||||
|
this.ctx.rect(0, offset + 1, w, val);
|
||||||
|
} else {
|
||||||
|
val = Math.round(h * screenRatio);
|
||||||
|
offset = Math.round((w - val) / 2);
|
||||||
|
this.ctx.rect(offset, 1, val, h - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ctx.stroke();
|
||||||
|
}
|
||||||
|
public update (msg : Message) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class Client {
|
class Client {
|
||||||
|
private display : Display;
|
||||||
private client : WebSocket;
|
private client : WebSocket;
|
||||||
private connected : boolean = false;
|
private connected : boolean = false;
|
||||||
private progress : HTMLProgressElement;
|
private progress : HTMLProgressElement;
|
||||||
|
@ -7,16 +61,20 @@ class Client {
|
||||||
let uri : string = 'ws://localhost:8082';
|
let uri : string = 'ws://localhost:8082';
|
||||||
this.progress = document.getElementById('progress') as HTMLProgressElement;
|
this.progress = document.getElementById('progress') as HTMLProgressElement;
|
||||||
this.client = new WebSocket(uri);
|
this.client = new WebSocket(uri);
|
||||||
|
this.display = new Display();
|
||||||
this.client.onopen = this.onOpen.bind(this);
|
this.client.onopen = this.onOpen.bind(this);
|
||||||
this.client.onclose = this.onClose.bind(this);
|
this.client.onclose = this.onClose.bind(this);
|
||||||
this.client.onmessage = this.onMessage.bind(this);
|
this.client.onmessage = this.onMessage.bind(this);
|
||||||
|
(document.getElementById('sequenceForm') as HTMLFormElement ).reset();
|
||||||
|
(document.getElementById('sequenceCtrlForm') as HTMLFormElement ).reset();
|
||||||
|
(document.getElementById('manualCtrlForm') as HTMLFormElement ).reset();
|
||||||
|
this.disableClass('sequenceCtrl');
|
||||||
|
this.disableClass('manualCtrl');
|
||||||
}
|
}
|
||||||
|
|
||||||
private onMessage (event : any) {
|
private onMessage (event : any) {
|
||||||
const msg : Message = JSON.parse(event.data) as Message;
|
const msg : Message = JSON.parse(event.data) as Message;
|
||||||
if (typeof msg.state !== 'undefined' && msg.state.sequence !== null) {
|
if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) {
|
||||||
this.setSequence(msg.state.sequence);
|
|
||||||
} else if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) {
|
|
||||||
this.cmd(msg);
|
this.cmd(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +83,7 @@ class Client {
|
||||||
console.log('Connected');
|
console.log('Connected');
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
this.active();
|
this.active();
|
||||||
|
this.enableClass('manualCtrl');
|
||||||
}
|
}
|
||||||
|
|
||||||
private onClose (event : any) {
|
private onClose (event : any) {
|
||||||
|
@ -33,10 +92,44 @@ class Client {
|
||||||
this.inactive();
|
this.inactive();
|
||||||
}
|
}
|
||||||
|
|
||||||
private setSequence(sequence : SequenceState) {
|
private setSequence(state : State) {
|
||||||
|
this.setProgress(state.sequence);
|
||||||
|
this.setStatus(state.sequence);
|
||||||
|
this.setDisplay(state);
|
||||||
|
(document.getElementById('sequence') as HTMLSelectElement ).value = state.sequence.hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setStatus (sequence : SequenceState) {
|
||||||
|
let status : string;
|
||||||
|
switch (sequence.status) {
|
||||||
|
case SequenceStatus.IDLE :
|
||||||
|
status = 'Idle';
|
||||||
|
break;
|
||||||
|
case SequenceStatus.RUNNING :
|
||||||
|
status = 'Running';
|
||||||
|
break;
|
||||||
|
case SequenceStatus.PAUSED :
|
||||||
|
status = 'Paused';
|
||||||
|
break;
|
||||||
|
default :
|
||||||
|
status = 'Unknown State';
|
||||||
|
}
|
||||||
|
document.getElementById('sequenceStatus').innerText = status;
|
||||||
|
document.getElementById('sequenceName').innerText = sequence.name;
|
||||||
|
document.getElementById('sequenceLength').innerText = `Sequence Length: ${sequence.frames}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setProgress (sequence : SequenceState) {
|
||||||
const percent : number = sequence.progress * 100.0;
|
const percent : number = sequence.progress * 100.0;
|
||||||
this.progress.value = percent;
|
if (this.progress !== null) {
|
||||||
this.progress.innerText = `${Math.floor(percent)}%`;
|
this.progress.value = percent;
|
||||||
|
this.progress.innerText = `${Math.floor(percent)}%`;
|
||||||
|
}
|
||||||
|
document.getElementById('sequenceProgress').innerText = `Progress: ${Math.round(sequence.progress)}%`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private setDisplay (state : State) {
|
||||||
|
console.dir(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private cmd (msg : Message) {
|
private cmd (msg : Message) {
|
||||||
|
@ -93,22 +186,26 @@ class Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
public sendSelect () {
|
public sendSelect () {
|
||||||
const sequence : string = (document.getElementById('sequence') as HTMLSelectElement ).value;
|
const hash : string = (document.getElementById('sequence') as HTMLSelectElement ).value;
|
||||||
let msg : Message;
|
let msg : Message;
|
||||||
if (sequence === '- Select Image Sequence -') {
|
if (hash === '- Select Image Sequence -') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
msg = { cmd : 'select', sequence };
|
msg = { cmd : 'select', state : { sequence : { hash } } };
|
||||||
console.log('send select');
|
console.log('send select');
|
||||||
console.log(sequence)
|
console.log(hash)
|
||||||
this.client.send(JSON.stringify(msg));
|
this.client.send(JSON.stringify(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
private receiveSelect (msg : Message) {
|
private receiveSelect (msg : Message) {
|
||||||
console.log('got select');
|
console.log('got select');
|
||||||
console.dir(msg);
|
console.dir(msg);
|
||||||
(document.getElementById('sequence') as HTMLSelectElement ).value = msg.sequence;
|
this.enableClass('sequenceCtrl');
|
||||||
//this.enableClass('sequenceCtrl');
|
this.setSequence(msg.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
private receiveUpdate (msg : Message) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fullscreen () {
|
public fullscreen () {
|
||||||
|
|
|
@ -16,5 +16,6 @@ export declare class Display {
|
||||||
setSource(width: number, height: number): void;
|
setSource(width: number, height: number): void;
|
||||||
getDimensions(): fdOutgoingPosition;
|
getDimensions(): fdOutgoingPosition;
|
||||||
getScreen(): Dimensions;
|
getScreen(): Dimensions;
|
||||||
|
getSource(): Dimensions;
|
||||||
}
|
}
|
||||||
export type { Dimensions };
|
export type { Dimensions };
|
||||||
|
|
|
@ -46,6 +46,9 @@ class Display {
|
||||||
getScreen() {
|
getScreen() {
|
||||||
return this.screen;
|
return this.screen;
|
||||||
}
|
}
|
||||||
|
getSource() {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.Display = Display;
|
exports.Display = Display;
|
||||||
module.exports = { Display };
|
module.exports = { Display };
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":";;;AAEA,MAAM,UAAU;IAIf,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;CACD;AAOD,MAAa,OAAO;IAQnB,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAE,CAAA;IAC9B,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,SAAS,CAAE,KAAc,EAAE,MAAe;QAChD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACzG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAClD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3G,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YAChD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAG,CAAC,EAAG,CAAC,EAAE,CAAC;QACrD,CAAC;IACF,CAAC;IAEM,aAAa;QACnB,OAAO;YACN,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YACtB,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,MAAM;YACvB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;SACjB,CAAA;IACF,CAAC;IAEM,SAAS;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;CACD;AA/CD,0BA+CC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC"}
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/display/index.ts"],"names":[],"mappings":";;;AAEA,MAAM,UAAU;IAIf,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAEM,QAAQ;QACd,OAAO,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,CAAC;CACD;AAOD,MAAa,OAAO;IAQnB,YAAa,KAAc,EAAE,MAAe;QAC3C,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAE,CAAA;IAC9B,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,UAAU,CAAE,CAAU;QAC5B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAEM,SAAS,CAAE,KAAc,EAAE,MAAe;QAChD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;YACrD,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YACzG,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;YAClD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAG,CAAC,EAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;aAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC3G,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YAChD,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAG,CAAC,EAAG,CAAC,EAAE,CAAC;QACrD,CAAC;IACF,CAAC;IAEM,aAAa;QACnB,OAAO;YACN,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,KAAK;YACtB,CAAC,EAAG,IAAI,CAAC,OAAO,CAAC,MAAM;YACvB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC,EAAG,IAAI,CAAC,MAAM,CAAC,CAAC;SACjB,CAAA;IACF,CAAC;IAEM,SAAS;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;IAEM,SAAS;QACf,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;CACD;AAnDD,0BAmDC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,CAAC"}
|
|
@ -0,0 +1,6 @@
|
||||||
|
declare enum SequenceStatus {
|
||||||
|
IDLE = 0,
|
||||||
|
RUNNING = 1,
|
||||||
|
PAUSED = 2
|
||||||
|
}
|
||||||
|
export type { SequenceStatus };
|
|
@ -0,0 +1,9 @@
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
var SequenceStatus;
|
||||||
|
(function (SequenceStatus) {
|
||||||
|
SequenceStatus[SequenceStatus["IDLE"] = 0] = "IDLE";
|
||||||
|
SequenceStatus[SequenceStatus["RUNNING"] = 1] = "RUNNING";
|
||||||
|
SequenceStatus[SequenceStatus["PAUSED"] = 2] = "PAUSED";
|
||||||
|
})(SequenceStatus || (SequenceStatus = {}));
|
||||||
|
//# sourceMappingURL=globals.js.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":";;AAAA,IAAK,cAIJ;AAJD,WAAK,cAAc;IACjB,mDAAI,CAAA;IACJ,yDAAO,CAAA;IACP,uDAAM,CAAA;AACR,CAAC,EAJI,cAAc,KAAd,cAAc,QAIlB"}
|
|
@ -173,6 +173,7 @@ function onWssConnection(ws, req) {
|
||||||
ws.ip = ip;
|
ws.ip = ip;
|
||||||
ws.session = (0, uuid_1.v4)();
|
ws.session = (0, uuid_1.v4)();
|
||||||
ws.on('message', function (data) { onClientMessage(data, ws); });
|
ws.on('message', function (data) { onClientMessage(data, ws); });
|
||||||
|
sequence.updateClients();
|
||||||
}
|
}
|
||||||
async function onClientMessage(data, ws) {
|
async function onClientMessage(data, ws) {
|
||||||
let msg = null;
|
let msg = null;
|
||||||
|
@ -196,7 +197,7 @@ async function cmd(msg) {
|
||||||
await cameraClose();
|
await cameraClose();
|
||||||
break;
|
break;
|
||||||
case 'select':
|
case 'select':
|
||||||
await select(msg.sequence);
|
await select(msg.state.sequence.hash);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
log.warn(`No matching command: ${msg.cmd}`);
|
log.warn(`No matching command: ${msg.cmd}`);
|
||||||
|
@ -232,6 +233,8 @@ app.get('/', async (req, res, next) => {
|
||||||
const html = index({ sequences: sequencesArr, width, height });
|
const html = index({ sequences: sequencesArr, width, height });
|
||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
|
app.get('/image.jpg', async (req, res, next) => {
|
||||||
|
});
|
||||||
async function main() {
|
async function main() {
|
||||||
await settings();
|
await settings();
|
||||||
index = await createTemplate('./views/index.hbs');
|
index = await createTemplate('./views/index.hbs');
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -3,6 +3,11 @@ import type { FD } from '../fd';
|
||||||
import type { Camera } from '../camera';
|
import type { Camera } from '../camera';
|
||||||
import type { Display } from '../display';
|
import type { Display } from '../display';
|
||||||
import type { FFPROBE } from '../ffprobe';
|
import type { FFPROBE } from '../ffprobe';
|
||||||
|
declare enum SequenceStatus {
|
||||||
|
IDLE = 0,
|
||||||
|
RUNNING = 1,
|
||||||
|
PAUSED = 2
|
||||||
|
}
|
||||||
export declare class Sequence {
|
export declare class Sequence {
|
||||||
private log;
|
private log;
|
||||||
private current;
|
private current;
|
||||||
|
@ -12,16 +17,25 @@ export declare class Sequence {
|
||||||
private display;
|
private display;
|
||||||
private ffprobe;
|
private ffprobe;
|
||||||
private fd;
|
private fd;
|
||||||
private running;
|
|
||||||
private progress;
|
|
||||||
private frames;
|
|
||||||
private send;
|
private send;
|
||||||
|
private running;
|
||||||
|
private paused;
|
||||||
|
private progress;
|
||||||
|
private frame;
|
||||||
|
private frames;
|
||||||
|
private exposure;
|
||||||
constructor(camera: Camera, fd: FD, display: Display, ffprobe: FFPROBE, send: Function);
|
constructor(camera: Camera, fd: FD, display: Display, ffprobe: FFPROBE, send: Function);
|
||||||
start(): void;
|
start(): void;
|
||||||
stop(): void;
|
stop(): void;
|
||||||
isRunning(): boolean;
|
isRunning(): boolean;
|
||||||
load(seq: SequenceObject): void;
|
load(seq: SequenceObject): Promise<void>;
|
||||||
|
updateClients(): void;
|
||||||
private enumerate;
|
private enumerate;
|
||||||
unload(): void;
|
unload(): void;
|
||||||
getState(): SequenceState;
|
getState(): State;
|
||||||
|
getSequenceState(): SequenceState;
|
||||||
|
setExposure(ms: number): void;
|
||||||
|
getStatus(): SequenceStatus;
|
||||||
|
getCurrent(): string;
|
||||||
}
|
}
|
||||||
|
export {};
|
||||||
|
|
|
@ -3,11 +3,23 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
exports.Sequence = void 0;
|
exports.Sequence = void 0;
|
||||||
const files_1 = require("../files");
|
const files_1 = require("../files");
|
||||||
const log_1 = require("../log");
|
const log_1 = require("../log");
|
||||||
|
var SequenceStatus;
|
||||||
|
(function (SequenceStatus) {
|
||||||
|
SequenceStatus[SequenceStatus["IDLE"] = 0] = "IDLE";
|
||||||
|
SequenceStatus[SequenceStatus["RUNNING"] = 1] = "RUNNING";
|
||||||
|
SequenceStatus[SequenceStatus["PAUSED"] = 2] = "PAUSED";
|
||||||
|
})(SequenceStatus || (SequenceStatus = {}));
|
||||||
class Sequence {
|
class Sequence {
|
||||||
constructor(camera, fd, display, ffprobe, send) {
|
constructor(camera, fd, display, ffprobe, send) {
|
||||||
this.current = null;
|
this.current = null;
|
||||||
this.info = null;
|
this.info = null;
|
||||||
this.images = [];
|
this.images = [];
|
||||||
|
this.running = false;
|
||||||
|
this.paused = false;
|
||||||
|
this.progress = 0;
|
||||||
|
this.frame = 0;
|
||||||
|
this.frames = 0;
|
||||||
|
this.exposure = 1000;
|
||||||
this.log = (0, log_1.createLog)('seq');
|
this.log = (0, log_1.createLog)('seq');
|
||||||
this.camera = camera;
|
this.camera = camera;
|
||||||
this.fd = fd;
|
this.fd = fd;
|
||||||
|
@ -24,10 +36,17 @@ class Sequence {
|
||||||
isRunning() {
|
isRunning() {
|
||||||
return this.running;
|
return this.running;
|
||||||
}
|
}
|
||||||
load(seq) {
|
async load(seq) {
|
||||||
this.current = seq;
|
this.current = seq;
|
||||||
this.enumerate();
|
this.frame = 0;
|
||||||
this.send({ cmd: 'select', sequence: seq.hash });
|
this.progress = 0;
|
||||||
|
await this.enumerate();
|
||||||
|
this.updateClients();
|
||||||
|
}
|
||||||
|
updateClients() {
|
||||||
|
if (this.current !== null) {
|
||||||
|
this.send({ cmd: 'select', state: this.getState() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
async enumerate() {
|
async enumerate() {
|
||||||
let screen;
|
let screen;
|
||||||
|
@ -42,8 +61,9 @@ class Sequence {
|
||||||
this.log.error(`Error enumerating images in sequence: ${this.current.name}`, err);
|
this.log.error(`Error enumerating images in sequence: ${this.current.name}`, err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.frames = this.images.length;
|
||||||
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
||||||
if (this.images.length > 0) {
|
if (this.frames > 0) {
|
||||||
this.info = await this.ffprobe.info(this.images[0].path);
|
this.info = await this.ffprobe.info(this.images[0].path);
|
||||||
}
|
}
|
||||||
if (this.info !== null) {
|
if (this.info !== null) {
|
||||||
|
@ -60,12 +80,56 @@ class Sequence {
|
||||||
this.images = [];
|
this.images = [];
|
||||||
}
|
}
|
||||||
getState() {
|
getState() {
|
||||||
|
const dimensions = this.display.getDimensions();
|
||||||
|
const source = this.display.getSource();
|
||||||
|
const screen = this.display.getScreen();
|
||||||
|
return {
|
||||||
|
display: {
|
||||||
|
width: dimensions.w,
|
||||||
|
height: dimensions.h
|
||||||
|
},
|
||||||
|
offset: {
|
||||||
|
x: dimensions.x,
|
||||||
|
y: dimensions.y
|
||||||
|
},
|
||||||
|
screen,
|
||||||
|
source,
|
||||||
|
sequence: {
|
||||||
|
hash: this.current.hash,
|
||||||
|
name: this.current.name,
|
||||||
|
progress: this.progress,
|
||||||
|
current: this.frame,
|
||||||
|
frames: this.frames,
|
||||||
|
status: this.getStatus()
|
||||||
|
},
|
||||||
|
exposure: this.exposure
|
||||||
|
};
|
||||||
|
}
|
||||||
|
getSequenceState() {
|
||||||
return {
|
return {
|
||||||
hash: this.current.hash,
|
hash: this.current.hash,
|
||||||
name: this.current.name,
|
name: this.current.name,
|
||||||
progress: this.progress
|
progress: this.progress
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
setExposure(ms) {
|
||||||
|
this.exposure = ms;
|
||||||
|
}
|
||||||
|
getStatus() {
|
||||||
|
if (this.running && this.paused) {
|
||||||
|
return SequenceStatus.PAUSED;
|
||||||
|
}
|
||||||
|
else if (this.running && !this.paused) {
|
||||||
|
return SequenceStatus.RUNNING;
|
||||||
|
}
|
||||||
|
return SequenceStatus.IDLE;
|
||||||
|
}
|
||||||
|
getCurrent() {
|
||||||
|
if (this.current !== null && this.images.length > 0 && typeof this.images[this.frame] !== 'undefined') {
|
||||||
|
this.images[this.frame];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.Sequence = Sequence;
|
exports.Sequence = Sequence;
|
||||||
//# sourceMappingURL=index.js.map
|
//# sourceMappingURL=index.js.map
|
|
@ -1 +1 @@
|
||||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sequence/index.ts"],"names":[],"mappings":"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"}
|
|
@ -66,6 +66,10 @@ export class Display {
|
||||||
public getScreen () : Dimensions {
|
public getScreen () : Dimensions {
|
||||||
return this.screen;
|
return this.screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getSource () : Dimensions {
|
||||||
|
return this.source;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { Display };
|
module.exports = { Display };
|
||||||
|
|
|
@ -1,18 +1,33 @@
|
||||||
|
|
||||||
|
interface StateDimensions {
|
||||||
|
width? : number,
|
||||||
|
height? : number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface StateOffset {
|
||||||
|
x? : number,
|
||||||
|
y? : number
|
||||||
|
}
|
||||||
|
|
||||||
interface SequenceState {
|
interface SequenceState {
|
||||||
hash : string,
|
hash : string,
|
||||||
name : string,
|
name? : string,
|
||||||
progress : number,
|
progress? : number,
|
||||||
current? : number
|
current? : number,
|
||||||
|
frames? : number,
|
||||||
|
status? : any
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
width? : number,
|
display? : StateDimensions,
|
||||||
height? : number,
|
offset? : StateOffset,
|
||||||
sequence? : SequenceState
|
source? : StateDimensions,
|
||||||
|
screen? : StateDimensions,
|
||||||
|
sequence? : SequenceState,
|
||||||
|
exposure? : number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
cmd? : string;
|
cmd? : string;
|
||||||
state? : State;
|
state? : State;
|
||||||
sequence? : string;
|
|
||||||
}
|
}
|
|
@ -162,6 +162,7 @@ function onWssConnection (ws : WebSocketExtended, req : Request) {
|
||||||
ws.ip = ip;
|
ws.ip = ip;
|
||||||
ws.session = uuid();
|
ws.session = uuid();
|
||||||
ws.on('message', function (data) { onClientMessage(data, ws) });
|
ws.on('message', function (data) { onClientMessage(data, ws) });
|
||||||
|
sequence.updateClients();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onClientMessage (data : any, ws : WebSocket) {
|
async function onClientMessage (data : any, ws : WebSocket) {
|
||||||
|
@ -186,7 +187,7 @@ async function cmd (msg : Message) {
|
||||||
await cameraClose();
|
await cameraClose();
|
||||||
break;
|
break;
|
||||||
case 'select' :
|
case 'select' :
|
||||||
await select(msg.sequence);
|
await select(msg.state.sequence.hash);
|
||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
log.warn(`No matching command: ${msg.cmd}`);
|
log.warn(`No matching command: ${msg.cmd}`);
|
||||||
|
@ -228,6 +229,10 @@ app.get('/', async (req : Request, res : Response, next : NextFunction) => {
|
||||||
res.send(html);
|
res.send(html);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
app.get('/image.jpg', async (req : Request, res : Response, next : NextFunction) => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
async function main () {
|
async function main () {
|
||||||
await settings();
|
await settings();
|
||||||
index = await createTemplate('./views/index.hbs');
|
index = await createTemplate('./views/index.hbs');
|
||||||
|
|
|
@ -2,11 +2,17 @@ import { Files } from '../files';
|
||||||
import { createLog } from '../log'
|
import { createLog } from '../log'
|
||||||
import type { Logger } from 'winston';
|
import type { Logger } from 'winston';
|
||||||
import type { SequenceObject, ImageObject } from '../files';
|
import type { SequenceObject, ImageObject } from '../files';
|
||||||
import type { FD } from '../fd';
|
import type { FD, fdOutgoingPosition } from '../fd';
|
||||||
import type { Camera } from '../camera';
|
import type { Camera } from '../camera';
|
||||||
import type { Display, Dimensions } from '../display';
|
import type { Display, Dimensions } from '../display';
|
||||||
import type { FFPROBE, VideoInfo } from '../ffprobe';
|
import type { FFPROBE, VideoInfo } from '../ffprobe';
|
||||||
|
|
||||||
|
enum SequenceStatus {
|
||||||
|
IDLE,
|
||||||
|
RUNNING,
|
||||||
|
PAUSED
|
||||||
|
}
|
||||||
|
|
||||||
export class Sequence {
|
export class Sequence {
|
||||||
private log : Logger;
|
private log : Logger;
|
||||||
private current : SequenceObject = null;
|
private current : SequenceObject = null;
|
||||||
|
@ -16,10 +22,15 @@ export class Sequence {
|
||||||
private display : Display;
|
private display : Display;
|
||||||
private ffprobe : FFPROBE;
|
private ffprobe : FFPROBE;
|
||||||
private fd : FD;
|
private fd : FD;
|
||||||
private running : boolean;
|
|
||||||
private progress : number;
|
|
||||||
private frames : number;
|
|
||||||
private send : Function;
|
private send : Function;
|
||||||
|
private running : boolean = false;
|
||||||
|
private paused : boolean = false;
|
||||||
|
|
||||||
|
private progress : number = 0;
|
||||||
|
private frame : number = 0;
|
||||||
|
private frames : number = 0;
|
||||||
|
|
||||||
|
private exposure : number = 1000;
|
||||||
|
|
||||||
constructor (camera : Camera, fd : FD, display: Display, ffprobe : FFPROBE, send : Function) {
|
constructor (camera : Camera, fd : FD, display: Display, ffprobe : FFPROBE, send : Function) {
|
||||||
this.log = createLog('seq');
|
this.log = createLog('seq');
|
||||||
|
@ -42,14 +53,23 @@ export class Sequence {
|
||||||
return this.running;
|
return this.running;
|
||||||
}
|
}
|
||||||
|
|
||||||
public load (seq : SequenceObject) {
|
public async load (seq : SequenceObject) {
|
||||||
this.current = seq;
|
this.current = seq;
|
||||||
this.enumerate();
|
this.frame = 0;
|
||||||
this.send({ cmd : 'select', sequence : seq.hash });
|
this.progress = 0;
|
||||||
|
await this.enumerate();
|
||||||
|
this.updateClients();
|
||||||
|
}
|
||||||
|
|
||||||
|
public updateClients () {
|
||||||
|
if (this.current !== null) {
|
||||||
|
this.send({ cmd : 'select', state : this.getState() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async enumerate () {
|
private async enumerate () {
|
||||||
let screen : Dimensions;
|
let screen : Dimensions;
|
||||||
|
|
||||||
if (this.current === null) {
|
if (this.current === null) {
|
||||||
this.log.error('Cannot enumerate sequence because it is not set');
|
this.log.error('Cannot enumerate sequence because it is not set');
|
||||||
return;
|
return;
|
||||||
|
@ -62,9 +82,11 @@ export class Sequence {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.frames = this.images.length;
|
||||||
|
|
||||||
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
||||||
|
|
||||||
if (this.images.length > 0) {
|
if (this.frames > 0) {
|
||||||
this.info = await this.ffprobe.info(this.images[0].path);
|
this.info = await this.ffprobe.info(this.images[0].path);
|
||||||
}
|
}
|
||||||
if (this.info !== null) {
|
if (this.info !== null) {
|
||||||
|
@ -82,11 +104,58 @@ export class Sequence {
|
||||||
this.images = [];
|
this.images = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public getState () : SequenceState {
|
public getState () : State {
|
||||||
|
const dimensions : fdOutgoingPosition = this.display.getDimensions();
|
||||||
|
const source : Dimensions = this.display.getSource();
|
||||||
|
const screen : Dimensions = this.display.getScreen();
|
||||||
|
return {
|
||||||
|
display : {
|
||||||
|
width : dimensions.w,
|
||||||
|
height : dimensions.h
|
||||||
|
},
|
||||||
|
offset : {
|
||||||
|
x : dimensions.x,
|
||||||
|
y : dimensions.y
|
||||||
|
},
|
||||||
|
screen,
|
||||||
|
source,
|
||||||
|
sequence : {
|
||||||
|
hash : this.current.hash,
|
||||||
|
name : this.current.name,
|
||||||
|
progress : this.progress,
|
||||||
|
current : this.frame,
|
||||||
|
frames : this.frames,
|
||||||
|
status : this.getStatus() as SequenceStatus
|
||||||
|
},
|
||||||
|
exposure : this.exposure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSequenceState () : SequenceState {
|
||||||
return {
|
return {
|
||||||
hash : this.current.hash,
|
hash : this.current.hash,
|
||||||
name : this.current.name,
|
name : this.current.name,
|
||||||
progress : this.progress
|
progress : this.progress
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setExposure (ms : number) {
|
||||||
|
this.exposure = ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getStatus () : SequenceStatus {
|
||||||
|
if (this.running && this.paused) {
|
||||||
|
return SequenceStatus.PAUSED;
|
||||||
|
} else if (this.running && !this.paused) {
|
||||||
|
return SequenceStatus.RUNNING;
|
||||||
|
}
|
||||||
|
return SequenceStatus.IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCurrent () : string {
|
||||||
|
if (this.current !== null && this.images.length > 0 && typeof this.images[this.frame] !== 'undefined') {
|
||||||
|
this.images[this.frame]
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -27,4 +27,18 @@ html, body{
|
||||||
|
|
||||||
#overlay.active{
|
#overlay.active{
|
||||||
display: none;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#display{
|
||||||
|
background: black;
|
||||||
|
min-height: 50vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screen .field-row{
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#screen .field-row input {
|
||||||
|
max-width: 50px;
|
||||||
}
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
declare enum SequenceStatus {
|
||||||
|
IDLE = 0,
|
||||||
|
RUNNING = 1,
|
||||||
|
PAUSED = 2
|
||||||
|
}
|
||||||
|
export type { SequenceStatus };
|
|
@ -0,0 +1,11 @@
|
||||||
|
define(["require", "exports"], function (require, exports) {
|
||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
var SequenceStatus;
|
||||||
|
(function (SequenceStatus) {
|
||||||
|
SequenceStatus[SequenceStatus["IDLE"] = 0] = "IDLE";
|
||||||
|
SequenceStatus[SequenceStatus["RUNNING"] = 1] = "RUNNING";
|
||||||
|
SequenceStatus[SequenceStatus["PAUSED"] = 2] = "PAUSED";
|
||||||
|
})(SequenceStatus || (SequenceStatus = {}));
|
||||||
|
});
|
||||||
|
//# sourceMappingURL=globals.js.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"globals.js","sourceRoot":"","sources":["../../browser/globals.ts"],"names":[],"mappings":";;;IAAA,IAAK,cAIJ;IAJD,WAAK,cAAc;QACjB,mDAAI,CAAA;QACJ,yDAAO,CAAA;QACP,uDAAM,CAAA;IACR,CAAC,EAJI,cAAc,KAAd,cAAc,QAIlB"}
|
|
@ -1,4 +1,20 @@
|
||||||
|
declare enum SequenceStatus {
|
||||||
|
IDLE = 0,
|
||||||
|
RUNNING = 1,
|
||||||
|
PAUSED = 2
|
||||||
|
}
|
||||||
|
declare class Display {
|
||||||
|
private parentElement;
|
||||||
|
private canvas;
|
||||||
|
private ctx;
|
||||||
|
private screen;
|
||||||
|
constructor();
|
||||||
|
private create;
|
||||||
|
private updateSize;
|
||||||
|
update(msg: Message): void;
|
||||||
|
}
|
||||||
declare class Client {
|
declare class Client {
|
||||||
|
private display;
|
||||||
private client;
|
private client;
|
||||||
private connected;
|
private connected;
|
||||||
private progress;
|
private progress;
|
||||||
|
@ -7,6 +23,9 @@ declare class Client {
|
||||||
private onOpen;
|
private onOpen;
|
||||||
private onClose;
|
private onClose;
|
||||||
private setSequence;
|
private setSequence;
|
||||||
|
private setStatus;
|
||||||
|
private setProgress;
|
||||||
|
private setDisplay;
|
||||||
private cmd;
|
private cmd;
|
||||||
disableClass(className: string): void;
|
disableClass(className: string): void;
|
||||||
enableClass(className: string): void;
|
enableClass(className: string): void;
|
||||||
|
@ -16,6 +35,7 @@ declare class Client {
|
||||||
private receiveCameraClose;
|
private receiveCameraClose;
|
||||||
sendSelect(): void;
|
sendSelect(): void;
|
||||||
private receiveSelect;
|
private receiveSelect;
|
||||||
|
private receiveUpdate;
|
||||||
fullscreen(): void;
|
fullscreen(): void;
|
||||||
exitFullscreen(): void;
|
exitFullscreen(): void;
|
||||||
private active;
|
private active;
|
||||||
|
|
|
@ -1,19 +1,68 @@
|
||||||
|
var SequenceStatus;
|
||||||
|
(function (SequenceStatus) {
|
||||||
|
SequenceStatus[SequenceStatus["IDLE"] = 0] = "IDLE";
|
||||||
|
SequenceStatus[SequenceStatus["RUNNING"] = 1] = "RUNNING";
|
||||||
|
SequenceStatus[SequenceStatus["PAUSED"] = 2] = "PAUSED";
|
||||||
|
})(SequenceStatus || (SequenceStatus = {}));
|
||||||
|
class Display {
|
||||||
|
constructor() {
|
||||||
|
this.parentElement = document.getElementById('display');
|
||||||
|
this.create();
|
||||||
|
}
|
||||||
|
create() {
|
||||||
|
this.canvas = this.parentElement.getElementsByTagName('canvas')[0];
|
||||||
|
this.ctx = this.canvas.getContext('2d');
|
||||||
|
this.screen = {
|
||||||
|
width: parseInt(document.getElementById('width').value),
|
||||||
|
height: parseInt(document.getElementById('height').value)
|
||||||
|
};
|
||||||
|
this.updateSize();
|
||||||
|
}
|
||||||
|
updateSize() {
|
||||||
|
const w = this.parentElement.clientWidth - 12;
|
||||||
|
const h = this.parentElement.clientHeight - 12;
|
||||||
|
const clientRatio = w / h;
|
||||||
|
const screenRatio = this.screen.width / this.screen.height;
|
||||||
|
let val;
|
||||||
|
let offset;
|
||||||
|
console.log(`${w},${h}`);
|
||||||
|
this.canvas.width = w;
|
||||||
|
this.canvas.height = h;
|
||||||
|
this.ctx.strokeStyle = "rgb(0, 0, 255)";
|
||||||
|
if (screenRatio > clientRatio) {
|
||||||
|
val = Math.floor(w / screenRatio);
|
||||||
|
offset = Math.round((h - val) / 2);
|
||||||
|
this.ctx.rect(0, offset + 1, w, val);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val = Math.round(h * screenRatio);
|
||||||
|
offset = Math.round((w - val) / 2);
|
||||||
|
this.ctx.rect(offset, 1, val, h - 1);
|
||||||
|
}
|
||||||
|
this.ctx.stroke();
|
||||||
|
}
|
||||||
|
update(msg) {
|
||||||
|
}
|
||||||
|
}
|
||||||
class Client {
|
class Client {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
let uri = 'ws://localhost:8082';
|
let uri = 'ws://localhost:8082';
|
||||||
this.progress = document.getElementById('progress');
|
this.progress = document.getElementById('progress');
|
||||||
this.client = new WebSocket(uri);
|
this.client = new WebSocket(uri);
|
||||||
|
this.display = new Display();
|
||||||
this.client.onopen = this.onOpen.bind(this);
|
this.client.onopen = this.onOpen.bind(this);
|
||||||
this.client.onclose = this.onClose.bind(this);
|
this.client.onclose = this.onClose.bind(this);
|
||||||
this.client.onmessage = this.onMessage.bind(this);
|
this.client.onmessage = this.onMessage.bind(this);
|
||||||
|
document.getElementById('sequenceForm').reset();
|
||||||
|
document.getElementById('sequenceCtrlForm').reset();
|
||||||
|
document.getElementById('manualCtrlForm').reset();
|
||||||
|
this.disableClass('sequenceCtrl');
|
||||||
|
this.disableClass('manualCtrl');
|
||||||
}
|
}
|
||||||
onMessage(event) {
|
onMessage(event) {
|
||||||
const msg = JSON.parse(event.data);
|
const msg = JSON.parse(event.data);
|
||||||
if (typeof msg.state !== 'undefined' && msg.state.sequence !== null) {
|
if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) {
|
||||||
this.setSequence(msg.state.sequence);
|
|
||||||
}
|
|
||||||
else if (typeof msg.cmd !== 'undefined' && msg.cmd !== null) {
|
|
||||||
this.cmd(msg);
|
this.cmd(msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,16 +70,48 @@ class Client {
|
||||||
console.log('Connected');
|
console.log('Connected');
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
this.active();
|
this.active();
|
||||||
|
this.enableClass('manualCtrl');
|
||||||
}
|
}
|
||||||
onClose(event) {
|
onClose(event) {
|
||||||
console.log('Disconnected');
|
console.log('Disconnected');
|
||||||
this.connected = false;
|
this.connected = false;
|
||||||
this.inactive();
|
this.inactive();
|
||||||
}
|
}
|
||||||
setSequence(sequence) {
|
setSequence(state) {
|
||||||
|
this.setProgress(state.sequence);
|
||||||
|
this.setStatus(state.sequence);
|
||||||
|
this.setDisplay(state);
|
||||||
|
document.getElementById('sequence').value = state.sequence.hash;
|
||||||
|
}
|
||||||
|
setStatus(sequence) {
|
||||||
|
let status;
|
||||||
|
switch (sequence.status) {
|
||||||
|
case SequenceStatus.IDLE:
|
||||||
|
status = 'Idle';
|
||||||
|
break;
|
||||||
|
case SequenceStatus.RUNNING:
|
||||||
|
status = 'Running';
|
||||||
|
break;
|
||||||
|
case SequenceStatus.PAUSED:
|
||||||
|
status = 'Paused';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = 'Unknown State';
|
||||||
|
}
|
||||||
|
document.getElementById('sequenceStatus').innerText = status;
|
||||||
|
document.getElementById('sequenceName').innerText = sequence.name;
|
||||||
|
document.getElementById('sequenceLength').innerText = `Sequence Length: ${sequence.frames}`;
|
||||||
|
}
|
||||||
|
setProgress(sequence) {
|
||||||
const percent = sequence.progress * 100.0;
|
const percent = sequence.progress * 100.0;
|
||||||
this.progress.value = percent;
|
if (this.progress !== null) {
|
||||||
this.progress.innerText = `${Math.floor(percent)}%`;
|
this.progress.value = percent;
|
||||||
|
this.progress.innerText = `${Math.floor(percent)}%`;
|
||||||
|
}
|
||||||
|
document.getElementById('sequenceProgress').innerText = `Progress: ${Math.round(sequence.progress)}%`;
|
||||||
|
}
|
||||||
|
setDisplay(state) {
|
||||||
|
console.dir(state);
|
||||||
}
|
}
|
||||||
cmd(msg) {
|
cmd(msg) {
|
||||||
switch (msg.cmd) {
|
switch (msg.cmd) {
|
||||||
|
@ -79,20 +160,23 @@ class Client {
|
||||||
this.enableClass('manualCtrl');
|
this.enableClass('manualCtrl');
|
||||||
}
|
}
|
||||||
sendSelect() {
|
sendSelect() {
|
||||||
const sequence = document.getElementById('sequence').value;
|
const hash = document.getElementById('sequence').value;
|
||||||
let msg;
|
let msg;
|
||||||
if (sequence === '- Select Image Sequence -') {
|
if (hash === '- Select Image Sequence -') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
msg = { cmd: 'select', sequence };
|
msg = { cmd: 'select', state: { sequence: { hash } } };
|
||||||
console.log('send select');
|
console.log('send select');
|
||||||
console.log(sequence);
|
console.log(hash);
|
||||||
this.client.send(JSON.stringify(msg));
|
this.client.send(JSON.stringify(msg));
|
||||||
}
|
}
|
||||||
receiveSelect(msg) {
|
receiveSelect(msg) {
|
||||||
console.log('got select');
|
console.log('got select');
|
||||||
console.dir(msg);
|
console.dir(msg);
|
||||||
document.getElementById('sequence').value = msg.sequence;
|
this.enableClass('sequenceCtrl');
|
||||||
|
this.setSequence(msg.state);
|
||||||
|
}
|
||||||
|
receiveUpdate(msg) {
|
||||||
}
|
}
|
||||||
fullscreen() {
|
fullscreen() {
|
||||||
if (!document.fullscreenElement) {
|
if (!document.fullscreenElement) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -18,14 +18,17 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="window-body">
|
<div class="window-body">
|
||||||
<div>Screen Resolution :
|
<div>
|
||||||
<div class="field-row">
|
<ul class="tree-view" id="display"><canvas></canvas></ul>
|
||||||
<label for="width">Width</label>
|
<div id="screen">Screen Resolution :
|
||||||
<input id="width" type="text" value="{{width}}" readonly />
|
<span class="field-row">
|
||||||
</div>
|
<label for="width">Width</label>
|
||||||
<div class="field-row">
|
<input id="width" type="text" value="{{width}}" readonly />
|
||||||
<label for="height">Height</label>
|
</span>
|
||||||
<input id="height" type="text" value="{{height}}" readonly />
|
<span class="field-row">
|
||||||
|
<label for="height">Height</label>
|
||||||
|
<input id="height" type="text" value="{{height}}" readonly />
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--
|
<!--
|
||||||
|
@ -37,29 +40,42 @@
|
||||||
</select>
|
</select>
|
||||||
-->
|
-->
|
||||||
<div>
|
<div>
|
||||||
<select name="sequence" id="sequence">
|
<form id="sequenceForm" onsubmit="return false;">
|
||||||
<option> - Select Image Sequence - </option>
|
<select name="sequence" id="sequence">
|
||||||
{{#each sequences}}
|
<option> - Select Image Sequence - </option>
|
||||||
<option value="{{this.hash}}">{{this.name}}</option>
|
{{#each sequences}}
|
||||||
{{/each}}
|
<option value="{{this.hash}}">{{this.name}}</option>
|
||||||
</select>
|
{{/each}}
|
||||||
<button id="select" onclick="client.sendSelect();">Select</button>
|
</select>
|
||||||
|
<button id="select" onclick="client.sendSelect();">Select</button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="start" class="sequenceCtrl" disabled>Start</button>
|
<form id="sequenceCtrlForm" onsubmit="return false;">
|
||||||
<button id="stop" class="sequenceCtrl" disabled>Stop</button>
|
<button id="start" class="sequenceCtrl" disabled>Start</button>
|
||||||
<button id="pause" class="sequenceCtrl" disabled>Pause</button>
|
<button id="stop" class="sequenceCtrl" disabled>Stop</button>
|
||||||
|
<button id="pause" class="sequenceCtrl" disabled>Pause</button>
|
||||||
|
<button id="rewind" class="sequenceCtrl" disabled><< Frame</button>
|
||||||
|
<input id="frame" value="0" class="sequenceCtrl" readonly />
|
||||||
|
<button id="forward" class="sequenceCtrl" disabled>Frame >></button>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button id="open" class="manualCtrl" onclick="client.sendCameraOpen()">Open Gate</button>
|
<form id="manualCtrlForm" onsubmit="return false;" >
|
||||||
<button id="close" class="manualCtrl" onclick="client.sendCameraClose()">Close Gate</button>
|
<button id="open" class="manualCtrl" onclick="client.sendCameraOpen()">Open Gate</button>
|
||||||
<button id="focus" class="manualCtrl" onclick="">Focus</button>
|
<button id="close" class="manualCtrl" onclick="client.sendCameraClose()">Close Gate</button>
|
||||||
<button id="framing" class="manualCtrl" onclick="">Framing</button>
|
<button id="focus" class="manualCtrl" onclick="">Focus</button>
|
||||||
|
<button id="framing" class="manualCtrl" onclick="">Framing</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<progress id="progress"></progress>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-bar" id="status">
|
<div class="status-bar" id="status">
|
||||||
<p class="status-bar-field">Idle</p>
|
<p class="status-bar-field" id="sequenceStatus">Idle</p>
|
||||||
<p class="status-bar-field">Progress: 0%</p>
|
<p class="status-bar-field" id="sequenceName">Not Set</p>
|
||||||
<p class="status-bar-field">Sequence Length: 0</p>
|
<p class="status-bar-field" id="sequenceProgress">Progress: 0%</p>
|
||||||
|
<p class="status-bar-field" id="sequenceLength">Sequence Length: 0</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue