mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-10-31 00:53:21 +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,6 +22,8 @@ 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 */ | ||||||
| @@ -29,6 +31,7 @@ var GuacamoleUI = { | |||||||
|     "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") | ||||||
| @@ -36,15 +39,19 @@ var GuacamoleUI = { | |||||||
|  |  | ||||||
|     "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