Skip to content

Commit edbef63

Browse files
author
Tobias
committed
Fix control bar handle for horizontal modes
1 parent c172d87 commit edbef63

2 files changed

Lines changed: 154 additions & 53 deletions

File tree

app/styles/base.css

Lines changed: 102 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -344,79 +344,150 @@ html {
344344

345345
#noVNC_control_bar_handle {
346346
position: absolute;
347-
left: -15px;
348-
top: 0;
349-
transform: translateY(35px);
350-
width: calc(100% + 30px);
351-
height: 50px;
352347
z-index: -1;
353348
cursor: pointer;
354349
border-radius: 6px;
355350
background-color: var(--novnc-darkblue);
356-
background-image: url("../images/handle_bg.svg");
357-
background-repeat: no-repeat;
358351
box-shadow: 3px 3px 0px rgba(0, 0, 0, 0.5);
359352
}
353+
:root:not(.noVNC_connected) #noVNC_control_bar_handle {
354+
display: none;
355+
}
356+
.noVNC_left #noVNC_control_bar_handle {
357+
transform: translateY(35px);
358+
top: 0;
359+
left: -15px;
360+
width: calc(100% + 30px);
361+
height: 50px;
362+
}
363+
.noVNC_right #noVNC_control_bar_handle {
364+
transform: translateY(35px);
365+
top: 0;
366+
left: -15px;
367+
width: calc(100% + 30px);
368+
height: 50px;
369+
}
370+
.noVNC_top #noVNC_control_bar_handle {
371+
transform: translateX(35px);
372+
top: -15px;
373+
left: 0;
374+
width: 50px;
375+
height: calc(100% + 30px);
376+
}
377+
.noVNC_bottom #noVNC_control_bar_handle {
378+
transform: translateX(35px);
379+
bottom: -15px;
380+
left: 0;
381+
width: 50px;
382+
height: calc(100% + 30px);
383+
}
384+
385+
#noVNC_control_bar_handle:before {
386+
content: "";
387+
background: url("../images/handle_bg.svg");
388+
background-repeat: no-repeat;
389+
position: absolute;
390+
top: 0;
391+
width: 15px;
392+
height: 50px;
393+
}
394+
.noVNC_left #noVNC_control_bar_handle:before {
395+
right: 0px;
396+
}
397+
.noVNC_right #noVNC_control_bar_handle:before {
398+
left: 0;
399+
}
400+
.noVNC_top #noVNC_control_bar_handle:before {
401+
transform-origin: bottom left;
402+
left: 0;
403+
transform: rotate(90deg) translateX(20px);
404+
}
405+
.noVNC_bottom #noVNC_control_bar_handle:before {
406+
transform-origin: bottom left;
407+
left: 0;
408+
transform: rotate(90deg) translateX(-50px);
409+
}
410+
360411
#noVNC_control_bar_handle:after {
361412
content: "";
362413
transition: transform 0.5s ease-in-out;
363414
background: url("../images/handle.svg");
364415
position: absolute;
365-
top: 22px; /* (50px-6px)/2 */
366416
width: 5px;
367417
height: 6px;
368418
}
369-
#noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
370-
transform: translateX(1px) rotate(180deg);
371-
}
372-
:root:not(.noVNC_connected) #noVNC_control_bar_handle {
373-
display: none;
374-
}
375-
/* left */
376-
.noVNC_left #noVNC_control_bar_handle {
377-
background-position: right;
378-
}
379419
.noVNC_left #noVNC_control_bar_handle:after {
420+
top: 22px; /* (50px-6px)/2 */
380421
right: 5px;
381422
transform: none;
382423
}
383-
.noVNC_left #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
384-
transform: translateX(1px) rotate(180deg);
385-
}
386-
/* right */
387-
.noVNC_right #noVNC_control_bar_handle {
388-
background-position: left;
389-
}
390424
.noVNC_right #noVNC_control_bar_handle:after {
425+
top: 22px; /* (50px-6px)/2 */
391426
left: 5px;
427+
transform: rotate(180deg);
428+
}
429+
.noVNC_top #noVNC_control_bar_handle:after {
430+
left: 22px;
431+
bottom: 5px;
432+
transform: translateY(1px) rotate(90deg);
433+
}
434+
.noVNC_bottom #noVNC_control_bar_handle:after {
435+
left: 22px;
436+
top: 5px;
437+
transform: rotate(-90deg);
438+
}
439+
440+
.noVNC_left #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
392441
transform: translateX(1px) rotate(180deg);
393442
}
394443
.noVNC_right #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
395-
transform: none;
444+
transform: translateX(-1px);
445+
}
446+
.noVNC_top #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
447+
transform: translateY(2px) rotate(-90deg);
396448
}
449+
.noVNC_bottom #noVNC_control_bar.noVNC_open #noVNC_control_bar_handle:after {
450+
transform: translateY(-1px) rotate(90deg);
451+
}
452+
397453
/* Larger touch area for the handle, used when a touch screen is available */
398454
#noVNC_control_bar_handle div {
399455
position: absolute;
400-
top: 0;
401-
width: 50px;
402-
height: 100%;
403456
display: none;
404457
}
405458
@media (any-pointer: coarse) {
406459
#noVNC_control_bar_handle div {
407460
display: initial;
408461
}
409462
}
410-
/* left */
411463
.noVNC_left #noVNC_control_bar_handle div {
464+
top: 0;
465+
width: 50px;
466+
height: 100%;
412467
left: auto;
413468
right: -35px;
414469
}
415-
/* right */
416470
.noVNC_right #noVNC_control_bar_handle div {
471+
top: 0;
472+
width: 50px;
473+
height: 100%;
417474
left: -35px;
418475
right: auto;
419476
}
477+
.noVNC_top #noVNC_control_bar_handle div {
478+
left: 0;
479+
width: 100%;
480+
height: 50px;
481+
top: auto;
482+
bottom: -35px;
483+
}
484+
.noVNC_bottom #noVNC_control_bar_handle div {
485+
left: 0;
486+
width: 100%;
487+
height: 50px;
488+
top: -35px;
489+
bottom: auto;
490+
}
420491

421492
:is(.noVNC_left, .noVNC_right) > #noVNC_control_bar > .noVNC_scroll {
422493
max-height: 100vh; /* Chrome is buggy with 100% */

app/ui.js

Lines changed: 52 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ const UI = {
3737

3838
controlbarGrabbed: false,
3939
controlbarDrag: false,
40+
controlbarMouseDownClientX: 0,
41+
controlbarMouseDownOffsetX: 0,
4042
controlbarMouseDownClientY: 0,
4143
controlbarMouseDownOffsetY: 0,
4244

@@ -741,9 +743,14 @@ const UI = {
741743
UI.controlbarDrag = true;
742744
}
743745

744-
const eventY = ptr.clientY - UI.controlbarMouseDownOffsetY;
745-
746-
UI.moveControlbarHandle(eventY);
746+
const pos = WebUtil.readSetting('controlbar_pos');
747+
if (pos === 'left' || pos === 'right') {
748+
const eventY = ptr.clientY - UI.controlbarMouseDownOffsetY;
749+
UI.moveControlbarHandle(eventY, true);
750+
} else if (pos === 'top' || pos === 'bottom') {
751+
const eventX = ptr.clientX - UI.controlbarMouseDownOffsetX;
752+
UI.moveControlbarHandle(eventX, false);
753+
}
747754

748755
e.preventDefault();
749756
e.stopPropagation();
@@ -752,49 +759,70 @@ const UI = {
752759
},
753760

754761
// Move the handle but don't allow any position outside the bounds
755-
moveControlbarHandle(viewportRelativeY) {
762+
moveControlbarHandle(viewportRelativeCoord, isVertical) {
756763
const handle = document.getElementById("noVNC_control_bar_handle");
757-
const handleHeight = handle.getBoundingClientRect().height;
764+
765+
const handleSpan = isVertical
766+
? handle.getBoundingClientRect().height
767+
: handle.getBoundingClientRect().width;
768+
758769
const controlbarBounds = document.getElementById("noVNC_control_bar")
759-
.getBoundingClientRect();
770+
.getBoundingClientRect();
771+
const controlbarBoundsStart = isVertical
772+
? controlbarBounds.top
773+
: controlbarBounds.left;
774+
const controlbarBoundsSpan = isVertical
775+
? controlbarBounds.height
776+
: controlbarBounds.width;
777+
760778
const margin = 10;
761779

762780
// These heights need to be non-zero for the below logic to work
763-
if (handleHeight === 0 || controlbarBounds.height === 0) {
781+
if (handleSpan === 0 || controlbarBoundsSpan === 0) {
764782
return;
765783
}
766784

767-
let newY = viewportRelativeY;
785+
let newCoord = viewportRelativeCoord;
768786

769787
// Check if the coordinates are outside the control bar
770-
if (newY < controlbarBounds.top + margin) {
771-
// Force coordinates to be below the top of the control bar
772-
newY = controlbarBounds.top + margin;
788+
if (newCoord < controlbarBoundsStart + margin) {
789+
// Force coordinates to be below the start of the control bar
790+
newCoord = controlbarBoundsStart + margin;
773791

774-
} else if (newY > controlbarBounds.top +
775-
controlbarBounds.height - handleHeight - margin) {
776-
// Force coordinates to be above the bottom of the control bar
777-
newY = controlbarBounds.top +
778-
controlbarBounds.height - handleHeight - margin;
792+
} else if (newCoord > controlbarBoundsStart +
793+
controlbarBoundsSpan - handleSpan - margin) {
794+
// Force coordinates to be before the end of the control bar
795+
newCoord = controlbarBoundsStart +
796+
controlbarBoundsSpan - handleSpan - margin;
779797
}
780798

781799
// Corner case: control bar too small for stable position
782-
if (controlbarBounds.height < (handleHeight + margin * 2)) {
783-
newY = controlbarBounds.top +
784-
(controlbarBounds.height - handleHeight) / 2;
800+
if (controlbarBoundsSpan < (handleSpan + margin * 2)) {
801+
newCoord = controlbarBoundsStart +
802+
(controlbarBoundsSpan - handleSpan) / 2;
785803
}
786804

787805
// The transform needs coordinates that are relative to the parent
788-
const parentRelativeY = newY - controlbarBounds.top;
789-
handle.style.transform = "translateY(" + parentRelativeY + "px)";
806+
const parentRelativeCoord = newCoord - controlbarBoundsStart;
807+
if (isVertical) {
808+
handle.style.transform = "translateY(" + parentRelativeCoord + "px)";
809+
} else {
810+
handle.style.transform = "translateX(" + parentRelativeCoord + "px)";
811+
}
790812
},
791813

792814
updateControlbarHandle() {
793815
// Since the control bar is fixed on the viewport and not the page,
794816
// the move function expects coordinates relative the the viewport.
795817
const handle = document.getElementById("noVNC_control_bar_handle");
796818
const handleBounds = handle.getBoundingClientRect();
797-
UI.moveControlbarHandle(handleBounds.top);
819+
820+
const pos = WebUtil.readSetting('controlbar_pos');
821+
if (pos === 'left' || pos === 'right') {
822+
UI.moveControlbarHandle(handleBounds.top, true);
823+
} else if (pos === 'top' || pos === 'bottom') {
824+
UI.moveControlbarHandle(handleBounds.left, false);
825+
}
798826
},
799827

800828
controlbarHandleMouseUp(e) {
@@ -832,6 +860,8 @@ const UI = {
832860

833861
UI.controlbarMouseDownClientY = ptr.clientY;
834862
UI.controlbarMouseDownOffsetY = ptr.clientY - bounds.top;
863+
UI.controlbarMouseDownClientX = ptr.clientX;
864+
UI.controlbarMouseDownOffsetX = ptr.clientX - bounds.left;
835865
e.preventDefault();
836866
e.stopPropagation();
837867
UI.keepControlbar();

0 commit comments

Comments
 (0)