mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-08 06:01:22 +00:00
Initial implementation of magnifier.
This commit is contained in:
@@ -40,6 +40,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- On-screen magnifier -->
|
||||||
|
<div id="magnifier">
|
||||||
|
<textarea id="eventTarget"></textarea>
|
||||||
|
<canvas id="magnifier-display"></canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- On-screen keyboard -->
|
<!-- On-screen keyboard -->
|
||||||
<div id="keyboardContainer"></div>
|
<div id="keyboardContainer"></div>
|
||||||
|
|
||||||
|
@@ -22,29 +22,36 @@ var GuacamoleUI = {
|
|||||||
|
|
||||||
/* Constants */
|
/* Constants */
|
||||||
|
|
||||||
|
"LONG_PRESS_DETECT_TIMEOUT" : 800, /* milliseconds */
|
||||||
|
"LONG_PRESS_MOVEMENT_THRESHOLD" : 10, /* pixels */
|
||||||
"KEYBOARD_AUTO_RESIZE_INTERVAL" : 30, /* milliseconds */
|
"KEYBOARD_AUTO_RESIZE_INTERVAL" : 30, /* milliseconds */
|
||||||
|
|
||||||
/* UI Components */
|
/* UI Components */
|
||||||
|
|
||||||
"viewport" : document.getElementById("viewportClone"),
|
"viewport" : document.getElementById("viewportClone"),
|
||||||
"display" : document.getElementById("display"),
|
"display" : document.getElementById("display"),
|
||||||
"logo" : document.getElementById("status-logo"),
|
"logo" : document.getElementById("status-logo"),
|
||||||
|
"eventTarget" : document.getElementById("eventTarget"),
|
||||||
|
|
||||||
"buttons": {
|
"buttons": {
|
||||||
"reconnect" : document.getElementById("reconnect")
|
"reconnect" : document.getElementById("reconnect")
|
||||||
},
|
},
|
||||||
|
|
||||||
"containers": {
|
"containers": {
|
||||||
"state" : document.getElementById("statusDialog"),
|
"state" : document.getElementById("statusDialog"),
|
||||||
"keyboard" : document.getElementById("keyboardContainer")
|
"keyboard" : document.getElementById("keyboardContainer"),
|
||||||
|
"magnifier" : document.getElementById("magnifier")
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"magnifier" : document.getElementById("magnifier-display"),
|
||||||
"state" : document.getElementById("statusText"),
|
"state" : document.getElementById("statusText"),
|
||||||
"client" : null,
|
"client" : null,
|
||||||
"sessionState" : new GuacamoleSessionState()
|
"sessionState" : new GuacamoleSessionState()
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GuacamoleUI.magnifierContext = GuacamoleUI.magnifier.getContext("2d");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Array of all supported audio mimetypes, populated when this script is
|
* Array of all supported audio mimetypes, populated when this script is
|
||||||
* loaded.
|
* loaded.
|
||||||
@@ -107,6 +114,124 @@ GuacamoleUI.toggleKeyboard = function() {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GuacamoleUI.Magnifier = new (function() {
|
||||||
|
|
||||||
|
var guac_magnifier = this;
|
||||||
|
|
||||||
|
var position_x = 0;
|
||||||
|
var position_y = 0;
|
||||||
|
|
||||||
|
var start_x = 0;
|
||||||
|
var start_y = 0;
|
||||||
|
|
||||||
|
GuacamoleUI.containers.magnifier.addEventListener("touchstart", function(e) {
|
||||||
|
|
||||||
|
if (e.touches.length == 1) {
|
||||||
|
|
||||||
|
start_x = e.touches[0].screenX;
|
||||||
|
start_y = e.touches[0].screenY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
GuacamoleUI.containers.magnifier.addEventListener("touchmove", function(e) {
|
||||||
|
|
||||||
|
if (e.touches.length == 1) {
|
||||||
|
|
||||||
|
var width = GuacamoleUI.containers.magnifier.offsetWidth;
|
||||||
|
var height = GuacamoleUI.containers.magnifier.offsetHeight;
|
||||||
|
|
||||||
|
var new_x = e.touches[0].screenX;
|
||||||
|
var new_y = e.touches[0].screenY;
|
||||||
|
|
||||||
|
position_x += new_x - start_x;
|
||||||
|
position_y += new_y - start_y;
|
||||||
|
|
||||||
|
if (position_x < 0) position_x = 0;
|
||||||
|
else if (position_x > window.innerWidth - width)
|
||||||
|
position_x = window.innerWidth - width;
|
||||||
|
|
||||||
|
if (position_y < 0) position_y = 0;
|
||||||
|
else if (position_y > window.innerHeight - height)
|
||||||
|
position_y = window.innerHeight - height;
|
||||||
|
|
||||||
|
start_x = new_x;
|
||||||
|
start_y = new_y;
|
||||||
|
|
||||||
|
// Move magnifier to new position
|
||||||
|
guac_magnifier.move(position_x, position_y);
|
||||||
|
|
||||||
|
// Update contents relative to new position
|
||||||
|
var clip_x = position_x
|
||||||
|
/ (window.innerWidth - width) * (GuacamoleUI.client.getWidth() - width);
|
||||||
|
var clip_y = position_y
|
||||||
|
/ (window.innerHeight - height) * (GuacamoleUI.client.getHeight() - height);
|
||||||
|
|
||||||
|
GuacamoleUI.magnifier.style.WebkitTransform =
|
||||||
|
GuacamoleUI.magnifier.style.MozTransform =
|
||||||
|
GuacamoleUI.magnifier.style.OTransform =
|
||||||
|
GuacamoleUI.magnifier.style.msTransform =
|
||||||
|
GuacamoleUI.magnifier.style.transform = "translate("
|
||||||
|
+ (-clip_x) + "px, " + (-clip_y) + "px)";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
GuacamoleUI.containers.magnifier.addEventListener("click", function(e) {
|
||||||
|
GuacamoleUI.eventTarget.focus();
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
this.move = function(x, y) {
|
||||||
|
|
||||||
|
GuacamoleUI.containers.magnifier.style.WebkitTransform =
|
||||||
|
GuacamoleUI.containers.magnifier.style.MozTransform =
|
||||||
|
GuacamoleUI.containers.magnifier.style.OTransform =
|
||||||
|
GuacamoleUI.containers.magnifier.style.msTransform =
|
||||||
|
GuacamoleUI.containers.magnifier.style.transform = "translate("
|
||||||
|
+ x + "px, " + y + "px)";
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.update = function() {
|
||||||
|
|
||||||
|
GuacamoleUI.magnifierContext.drawImage(GuacamoleUI.client.flatten(),
|
||||||
|
0, 0);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.show = function(x, y) {
|
||||||
|
|
||||||
|
// Get client dimensions
|
||||||
|
var width = GuacamoleUI.client.getWidth();
|
||||||
|
var height = GuacamoleUI.client.getHeight();
|
||||||
|
|
||||||
|
// Resize to fit client
|
||||||
|
GuacamoleUI.magnifier.width = width;
|
||||||
|
GuacamoleUI.magnifier.height = height;
|
||||||
|
|
||||||
|
// Ensure transformations on display originate at 0,0
|
||||||
|
GuacamoleUI.containers.magnifier.style.transformOrigin =
|
||||||
|
GuacamoleUI.containers.magnifier.style.webkitTransformOrigin =
|
||||||
|
GuacamoleUI.containers.magnifier.style.MozTransformOrigin =
|
||||||
|
GuacamoleUI.containers.magnifier.style.OTransformOrigin =
|
||||||
|
GuacamoleUI.containers.magnifier.style.msTransformOrigin =
|
||||||
|
"0 0";
|
||||||
|
|
||||||
|
// Show magnifier
|
||||||
|
GuacamoleUI.containers.magnifier.style.display = "block";
|
||||||
|
guac_magnifier.update();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.hide = function() {
|
||||||
|
GuacamoleUI.containers.magnifier.style.display = "none";
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
// If Node.classList is supported, implement addClass/removeClass using that
|
// If Node.classList is supported, implement addClass/removeClass using that
|
||||||
if (Node.classList) {
|
if (Node.classList) {
|
||||||
|
|
||||||
@@ -540,4 +665,57 @@ GuacamoleUI.attach = function(guac) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var long_press_start_x = 0;
|
||||||
|
var long_press_start_y = 0;
|
||||||
|
var longPressTimeout = null;
|
||||||
|
|
||||||
|
GuacamoleUI.startLongPressDetect = function() {
|
||||||
|
|
||||||
|
if (!longPressTimeout) {
|
||||||
|
|
||||||
|
longPressTimeout = window.setTimeout(function() {
|
||||||
|
longPressTimeout = null;
|
||||||
|
GuacamoleUI.Magnifier.show();
|
||||||
|
}, GuacamoleUI.LONG_PRESS_DETECT_TIMEOUT);
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GuacamoleUI.stopLongPressDetect = function() {
|
||||||
|
window.clearTimeout(longPressTimeout);
|
||||||
|
longPressTimeout = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Detect long-press at bottom of screen
|
||||||
|
GuacamoleUI.display.addEventListener('touchstart', function(e) {
|
||||||
|
|
||||||
|
// Close magnifier
|
||||||
|
GuacamoleUI.Magnifier.hide();
|
||||||
|
|
||||||
|
// Record touch location
|
||||||
|
if (e.touches.length == 1) {
|
||||||
|
var touch = e.touches[0];
|
||||||
|
long_press_start_x = touch.screenX;
|
||||||
|
long_press_start_y = touch.screenY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start detection
|
||||||
|
GuacamoleUI.startLongPressDetect();
|
||||||
|
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
// Stop detection if touch moves significantly
|
||||||
|
GuacamoleUI.display.addEventListener('touchmove', function(e) {
|
||||||
|
|
||||||
|
// If touch distance from start exceeds threshold, cancel long press
|
||||||
|
var touch = e.touches[0];
|
||||||
|
if (Math.abs(touch.screenX - long_press_start_x) >= GuacamoleUI.LONG_PRESS_MOVEMENT_THRESHOLD
|
||||||
|
|| Math.abs(touch.screenY - long_press_start_y) >= GuacamoleUI.LONG_PRESS_MOVEMENT_THRESHOLD)
|
||||||
|
GuacamoleUI.stopLongPressDetect();
|
||||||
|
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
// Stop detection if press stops
|
||||||
|
GuacamoleUI.display.addEventListener('touchend', GuacamoleUI.stopLongPressDetect, true);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@@ -41,6 +41,13 @@ img {
|
|||||||
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
-webkit-tap-highlight-color: rgba(0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#eventTarget {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Dialogs */
|
/* Dialogs */
|
||||||
|
|
||||||
div.dialogOuter {
|
div.dialogOuter {
|
||||||
@@ -163,6 +170,21 @@ div#display > * {
|
|||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#magnifier {
|
||||||
|
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
box-shadow: 2px 2px 10px rgba(0, 0, 0, 0.75);
|
||||||
|
width: 50%;
|
||||||
|
height: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Viewport Clone */
|
/* Viewport Clone */
|
||||||
|
|
||||||
div#viewportClone {
|
div#viewportClone {
|
||||||
|
Reference in New Issue
Block a user