From d7ae0d9d235bcc9459bf619a4f84ee985e1ccb31 Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 12:56:14 +0300 Subject: [PATCH 1/8] Feat: Mouse moving an enlarged video frame during live viewing Added mouse movement tracking functions. --- web/js/MonitorStream.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/web/js/MonitorStream.js b/web/js/MonitorStream.js index 22a7082bf..a4e33b0fc 100644 --- a/web/js/MonitorStream.js +++ b/web/js/MonitorStream.js @@ -339,6 +339,10 @@ function MonitorStream(monitorData) { console.log('onclick'); }; + this.onmove = function(evt) { + console.log('onmove'); + }; + this.setup_onclick = function(func) { if (func) { this.onclick = func; @@ -350,6 +354,17 @@ function MonitorStream(monitorData) { } }; + this.setup_onmove = function(func) { + if (func) { + this.onmove = func; + } + if (this.onmove) { + const el = this.getFrame(); + if (!el) return; + el.addEventListener('mousemove', this.onmove, false); + } + }; + this.disable_onclick = function() { const el = this.getElement(); if (!el) return; From 309809ff9c5da9d749df2f7d57ed319938a00a4a Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 13:22:43 +0300 Subject: [PATCH 2/8] Feat: Added functions for moving an enlarged video frame during live viewing --- web/skins/classic/views/js/watch.js | 144 ++++++++++++++++++++++------ 1 file changed, 116 insertions(+), 28 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index cd4403b4d..66a056303 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -16,6 +16,14 @@ var classMonitorW_SB_L = 'col-sm-9'; /* id="wrapperMonitor" ONLY WITH LEFT */ var classMonitorW_SB_R = 'col-sm-10'; /* id="wrapperMonitor" ONLY WITH RIGHT */ var classMonitorWO_SB = 'col-sm-12'; /* id="wrapperMonitor" MAXIMUM width */ +var PrevCoordinatFrame = {x: null, y: null}; +var coordinateMouse = { + start_x: null, start_y: null, + shiftMouse_x: null, shiftMouse_y: null, + shiftMouseForTrigger_x: null, shiftMouseForTrigger_y: null +}; +var leftBtnStatus = {Down: false, UpAfterDown: false}; + /* This is the format of the json object sent by bootstrap-table @@ -593,27 +601,106 @@ function fetchImage(streamImage) { } function handleClick(event) { + if (!(event.ctrlKey && (event.shift || event.shiftKey))) { // target should be the img tag - const target = $j(event.target); - const width = target.width(); - const height = target.height(); + const target = $j(event.target); + const width = target.width(); + const height = target.height(); - const scaleX = parseFloat(monitorWidth / width); - const scaleY = parseFloat(monitorHeight / height); - const pos = target.offset(); - const x = parseInt((event.pageX - pos.left) * scaleX); - const y = parseInt((event.pageY - pos.top) * scaleY); + const scaleX = parseFloat(monitorWidth / width); + const scaleY = parseFloat(monitorHeight / height); + const pos = target.offset(); + const x = parseInt((event.pageX - pos.left) * scaleX); + const y = parseInt((event.pageY - pos.top) * scaleY); - if (showMode == 'events' || !imageControlMode) { - if ( event.shift || event.shiftKey ) { - streamCmdPan(x, y); - } else if (event.ctrlKey) { - streamCmdZoomOut(); + updatePrevCoordinatFrame(x, y); //Fixing current coordinates after scaling or shifting + + if (showMode == 'events' || !imageControlMode) { + if (event.shift || event.shiftKey) { + streamCmdPan(x, y); + } else if (event.ctrlKey) { + streamCmdZoomOut(); + } else { + streamCmdZoomIn(x, y); + } } else { - streamCmdZoomIn(x, y); + controlCmdImage(x, y); } + } +} + +function shiftImgFrame() { //We calculate the coordinates of the image displacement and shift the image + let newPosX = parseInt((PrevCoordinatFrame.x - coordinateMouse.shiftMouse_x) * 1); + let newPosY = parseInt((PrevCoordinatFrame.y - coordinateMouse.shiftMouse_y) * 1); + + if (newPosX < 0) newPosX = 0; + if (newPosX > monitorWidth) newPosX = monitorWidth; + if (newPosY < 0) newPosY = 0; + if (newPosY > monitorHeight) newPosY = monitorHeight; + + streamCmdPan(newPosX, newPosY); + updatePrevCoordinatFrame(newPosX, newPosY); + coordinateMouse.shiftMouseForTrigger_x = coordinateMouse.shiftMouseForTrigger_y = 0; +} + +function updateCoordinateMouse(x, y) { //We fix the coordinates when pressing the left mouse button + coordinateMouse.start_x = x; + coordinateMouse.start_y = y; +} + +function updatePrevCoordinatFrame(x, y) { //Update the Frame's current coordinates + PrevCoordinatFrame.x = x; + PrevCoordinatFrame.y = y; +} + +function getCoordinateMouse(event) { //We get the current cursor coordinates taking into account the scale relative to the frame size. + const target = $j(event.target); + + const scaleX = parseFloat(monitorWidth / target.width()); + const scaleY = parseFloat(monitorHeight / target.height()); + const pos = target.offset(); + + return {x: parseInt((event.pageX - pos.left) * scaleX), y: parseInt((event.pageY - pos.top) * scaleY)}; //The point of the mouse click relative to the dimensions of the real frame. +} + +function handleMove(event) { + + if (event.ctrlKey && event.shiftKey) { + document.ondragstart = function() {return false}; //Allow drag and drop } else { - controlCmdImage(x, y); + document.ondragstart = function() {}; //Prevent drag and drop + return false; + } + + if (leftBtnStatus.Down) { //The left button was previously pressed and is now being held. Processing movement with a pressed button. + var {x, y} = getCoordinateMouse(event); + const k = Math.log(2.72) / Math.log(parseFloat($j('#zoomValue'+monitorId).html())) - 0.3; //Necessary for correctly shifting the image in accordance with the scaling proportions + + coordinateMouse.shiftMouse_x = parseInt((x - coordinateMouse.start_x) * k); + coordinateMouse.shiftMouse_y = parseInt((y - coordinateMouse.start_y) * k); + + coordinateMouse.shiftMouseForTrigger_x = Math.abs(parseInt(x - coordinateMouse.start_x)); + coordinateMouse.shiftMouseForTrigger_y = Math.abs(parseInt(y - coordinateMouse.start_y)); + } + if (event.buttons == 1 && leftBtnStatus.Down != true) { //Start of pressing left button + const {x, y} = getCoordinateMouse(event); + + updateCoordinateMouse(x, y); + leftBtnStatus.Down = true; + } else if (event.buttons == 0 && leftBtnStatus.Down == true) { //Up left button after pressed + leftBtnStatus.Down = false; + leftBtnStatus.UpAfterDown = true; + } + + if ((leftBtnStatus.UpAfterDown) //The left button was raised or the cursor was moved more than 30 pixels relative to the actual size of the image + || ((coordinateMouse.shiftMouseForTrigger_x > 30) && leftBtnStatus.Down) + || ((coordinateMouse.shiftMouseForTrigger_y > 30) && leftBtnStatus.Down) + ) + { + //We perform frame shift + shiftImgFrame(); + updateCoordinateMouse(x, y); + leftBtnStatus.UpAfterDown = false; } } @@ -754,19 +841,19 @@ function controlSetClicked() { console.log('loading'); // Load the PTZ Preset modal into the DOM $j.getJSON(monitorUrl + '?request=modal&modal=controlpreset&mid=' + monitorId+'&'+auth_relay) - .done(function(data) { - insertModalHtml('ctrlPresetModal', data.html); - updatePresetLabels(); - // Manage the Preset Select box - $j('#preset').change(updatePresetLabels); - // Manage the Save button - $j('#cPresetSubmitModal').click(function(evt) { - evt.preventDefault(); - $j('#ctrlPresetForm').submit(); - }); - $j('#ctrlPresetModal').modal('show'); - }) - .fail(logAjaxFail); + .done(function(data) { + insertModalHtml('ctrlPresetModal', data.html); + updatePresetLabels(); + // Manage the Preset Select box + $j('#preset').change(updatePresetLabels); + // Manage the Save button + $j('#cPresetSubmitModal').click(function(evt) { + evt.preventDefault(); + $j('#ctrlPresetForm').submit(); + }); + $j('#ctrlPresetModal').modal('show'); + }) + .fail(logAjaxFail); } else { console.log('not loading'); modal.modal('show'); @@ -800,6 +887,7 @@ function initPage() { monitorStream.setup_onclick(fetchImage); } else { monitorStream.setup_onclick(handleClick); + monitorStream.setup_onmove(handleMove); } monitorStream.setup_onpause(onPause); monitorStream.setup_onplay(onPlay); From ec807a70a40b4b3a78d360a2c8ea92519bbd612c Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 13:34:52 +0300 Subject: [PATCH 3/8] Fix: Previous code formatting was mistakenly removed. --- web/skins/classic/views/js/watch.js | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 66a056303..fdce581cb 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -841,19 +841,19 @@ function controlSetClicked() { console.log('loading'); // Load the PTZ Preset modal into the DOM $j.getJSON(monitorUrl + '?request=modal&modal=controlpreset&mid=' + monitorId+'&'+auth_relay) - .done(function(data) { - insertModalHtml('ctrlPresetModal', data.html); - updatePresetLabels(); - // Manage the Preset Select box - $j('#preset').change(updatePresetLabels); - // Manage the Save button - $j('#cPresetSubmitModal').click(function(evt) { - evt.preventDefault(); - $j('#ctrlPresetForm').submit(); - }); - $j('#ctrlPresetModal').modal('show'); - }) - .fail(logAjaxFail); + .done(function(data) { + insertModalHtml('ctrlPresetModal', data.html); + updatePresetLabels(); + // Manage the Preset Select box + $j('#preset').change(updatePresetLabels); + // Manage the Save button + $j('#cPresetSubmitModal').click(function(evt) { + evt.preventDefault(); + $j('#ctrlPresetForm').submit(); + }); + $j('#ctrlPresetModal').modal('show'); + }) + .fail(logAjaxFail); } else { console.log('not loading'); modal.modal('show'); From 289f7cbe43efdad9c7d5638c163cc49781baef37 Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 13:45:39 +0300 Subject: [PATCH 4/8] Chore: eslint format --- web/skins/classic/views/js/watch.js | 42 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index fdce581cb..4921595be 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -648,7 +648,7 @@ function updateCoordinateMouse(x, y) { //We fix the coordinates when pressing th coordinateMouse.start_y = y; } -function updatePrevCoordinatFrame(x, y) { //Update the Frame's current coordinates +function updatePrevCoordinatFrame(x, y) { //Update the Frame's current coordinates PrevCoordinatFrame.x = x; PrevCoordinatFrame.y = y; } @@ -664,7 +664,6 @@ function getCoordinateMouse(event) { //We get the current cursor coordinates tak } function handleMove(event) { - if (event.ctrlKey && event.shiftKey) { document.ondragstart = function() {return false}; //Allow drag and drop } else { @@ -676,8 +675,8 @@ function handleMove(event) { var {x, y} = getCoordinateMouse(event); const k = Math.log(2.72) / Math.log(parseFloat($j('#zoomValue'+monitorId).html())) - 0.3; //Necessary for correctly shifting the image in accordance with the scaling proportions - coordinateMouse.shiftMouse_x = parseInt((x - coordinateMouse.start_x) * k); - coordinateMouse.shiftMouse_y = parseInt((y - coordinateMouse.start_y) * k); + coordinateMouse.shiftMouse_x = parseInt((x - coordinateMouse.start_x) * k); + coordinateMouse.shiftMouse_y = parseInt((y - coordinateMouse.start_y) * k); coordinateMouse.shiftMouseForTrigger_x = Math.abs(parseInt(x - coordinateMouse.start_x)); coordinateMouse.shiftMouseForTrigger_y = Math.abs(parseInt(y - coordinateMouse.start_y)); @@ -692,11 +691,10 @@ function handleMove(event) { leftBtnStatus.UpAfterDown = true; } - if ((leftBtnStatus.UpAfterDown) //The left button was raised or the cursor was moved more than 30 pixels relative to the actual size of the image - || ((coordinateMouse.shiftMouseForTrigger_x > 30) && leftBtnStatus.Down) - || ((coordinateMouse.shiftMouseForTrigger_y > 30) && leftBtnStatus.Down) - ) - { + if ((leftBtnStatus.UpAfterDown) || //The left button was raised or the cursor was moved more than 30 pixels relative to the actual size of the image + ((coordinateMouse.shiftMouseForTrigger_x > 30) && leftBtnStatus.Down) || + ((coordinateMouse.shiftMouseForTrigger_y > 30) && leftBtnStatus.Down)) { + //We perform frame shift shiftImgFrame(); updateCoordinateMouse(x, y); @@ -841,19 +839,19 @@ function controlSetClicked() { console.log('loading'); // Load the PTZ Preset modal into the DOM $j.getJSON(monitorUrl + '?request=modal&modal=controlpreset&mid=' + monitorId+'&'+auth_relay) - .done(function(data) { - insertModalHtml('ctrlPresetModal', data.html); - updatePresetLabels(); - // Manage the Preset Select box - $j('#preset').change(updatePresetLabels); - // Manage the Save button - $j('#cPresetSubmitModal').click(function(evt) { - evt.preventDefault(); - $j('#ctrlPresetForm').submit(); - }); - $j('#ctrlPresetModal').modal('show'); - }) - .fail(logAjaxFail); + .done(function(data) { + insertModalHtml('ctrlPresetModal', data.html); + updatePresetLabels(); + // Manage the Preset Select box + $j('#preset').change(updatePresetLabels); + // Manage the Save button + $j('#cPresetSubmitModal').click(function(evt) { + evt.preventDefault(); + $j('#ctrlPresetForm').submit(); + }); + $j('#ctrlPresetModal').modal('show'); + }) + .fail(logAjaxFail); } else { console.log('not loading'); modal.modal('show'); From 0c2713e53a41adfd299598dc68e87fdff6657876 Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 13:50:31 +0300 Subject: [PATCH 5/8] Update watch.js --- web/skins/classic/views/js/watch.js | 30 +++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index 4921595be..c0b3b61c6 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -665,7 +665,9 @@ function getCoordinateMouse(event) { //We get the current cursor coordinates tak function handleMove(event) { if (event.ctrlKey && event.shiftKey) { - document.ondragstart = function() {return false}; //Allow drag and drop + document.ondragstart = function() { + return false; + }; //Allow drag and drop } else { document.ondragstart = function() {}; //Prevent drag and drop return false; @@ -839,19 +841,19 @@ function controlSetClicked() { console.log('loading'); // Load the PTZ Preset modal into the DOM $j.getJSON(monitorUrl + '?request=modal&modal=controlpreset&mid=' + monitorId+'&'+auth_relay) - .done(function(data) { - insertModalHtml('ctrlPresetModal', data.html); - updatePresetLabels(); - // Manage the Preset Select box - $j('#preset').change(updatePresetLabels); - // Manage the Save button - $j('#cPresetSubmitModal').click(function(evt) { - evt.preventDefault(); - $j('#ctrlPresetForm').submit(); - }); - $j('#ctrlPresetModal').modal('show'); - }) - .fail(logAjaxFail); + .done(function(data) { + insertModalHtml('ctrlPresetModal', data.html); + updatePresetLabels(); + // Manage the Preset Select box + $j('#preset').change(updatePresetLabels); + // Manage the Save button + $j('#cPresetSubmitModal').click(function(evt) { + evt.preventDefault(); + $j('#ctrlPresetForm').submit(); + }); + $j('#ctrlPresetModal').modal('show'); + }) + .fail(logAjaxFail); } else { console.log('not loading'); modal.modal('show'); From dcc0ff071ad49f6b3906a17c75fef9badbba4f3c Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 13:53:10 +0300 Subject: [PATCH 6/8] Chore: eslint format --- web/skins/classic/views/js/watch.js | 1 - 1 file changed, 1 deletion(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index c0b3b61c6..f8608f3f8 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -696,7 +696,6 @@ function handleMove(event) { if ((leftBtnStatus.UpAfterDown) || //The left button was raised or the cursor was moved more than 30 pixels relative to the actual size of the image ((coordinateMouse.shiftMouseForTrigger_x > 30) && leftBtnStatus.Down) || ((coordinateMouse.shiftMouseForTrigger_y > 30) && leftBtnStatus.Down)) { - //We perform frame shift shiftImgFrame(); updateCoordinateMouse(x, y); From 131a33ef38acaec0b27e30993c919004b1dc6fbd Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Mon, 1 Apr 2024 14:04:57 +0300 Subject: [PATCH 7/8] Chore: Code Cleanup --- web/skins/classic/views/js/watch.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index f8608f3f8..bbcb6649b 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -630,8 +630,8 @@ function handleClick(event) { } function shiftImgFrame() { //We calculate the coordinates of the image displacement and shift the image - let newPosX = parseInt((PrevCoordinatFrame.x - coordinateMouse.shiftMouse_x) * 1); - let newPosY = parseInt((PrevCoordinatFrame.y - coordinateMouse.shiftMouse_y) * 1); + let newPosX = parseInt(PrevCoordinatFrame.x - coordinateMouse.shiftMouse_x); + let newPosY = parseInt(PrevCoordinatFrame.y - coordinateMouse.shiftMouse_y); if (newPosX < 0) newPosX = 0; if (newPosX > monitorWidth) newPosX = monitorWidth; From da62c5b65a8e865918871a476edd3f2b50d005be Mon Sep 17 00:00:00 2001 From: IgorA100 Date: Tue, 2 Apr 2024 14:37:29 +0300 Subject: [PATCH 8/8] Fix: When Zooming out of a video frame, do not apply updatePrevCoordinatFrame() --- web/skins/classic/views/js/watch.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/skins/classic/views/js/watch.js b/web/skins/classic/views/js/watch.js index bbcb6649b..071694a64 100644 --- a/web/skins/classic/views/js/watch.js +++ b/web/skins/classic/views/js/watch.js @@ -613,15 +613,15 @@ function handleClick(event) { const x = parseInt((event.pageX - pos.left) * scaleX); const y = parseInt((event.pageY - pos.top) * scaleY); - updatePrevCoordinatFrame(x, y); //Fixing current coordinates after scaling or shifting - if (showMode == 'events' || !imageControlMode) { if (event.shift || event.shiftKey) { streamCmdPan(x, y); + updatePrevCoordinatFrame(x, y); //Fixing current coordinates after scaling or shifting } else if (event.ctrlKey) { streamCmdZoomOut(); } else { streamCmdZoomIn(x, y); + updatePrevCoordinatFrame(x, y); //Fixing current coordinates after scaling or shifting } } else { controlCmdImage(x, y);