I’m dynamically creating a fullscreen overlay for the user to enter a name.
The overlay does however not block mouse events on the canvas. I can still rotate my Orbit Camera.
If i enable the profiler i can’t click through that. I would like to achieve the same behaviour with my overlay.
Here is how i create the overlay:
LoginMask.prototype.addUI = function() {
// Add css
let style = document.createElement('style');
document.head.appendChild(style);
style.innerHTML = this.css.resource || '';
// Add HTML
let frag = document.createRange().createContextualFragment(this.html.resource || '');
document.body.appendChild(frag);
let self = this;
document.getElementById('login').addEventListener('click', function() {
let username = document.getElementById('username').value;
let payload = { username: username };
self.app.fire("login", payload);
document.getElementById('login-mask').remove();
},{once: true});
};
HTML:
<div id="login-mask" class="container-login">
<div>
<label for="username">USERNAME</label>
<input id="username" type="text" name="username">
<button id="login" type="button">Ready</button>
</div>
</div>
CSS:
.container-login{
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
background-color: #000000E1;
color: white;
z-index: 1000;
}
label{
display: block;
margin-bottom: .5rem;
}
input{
display: block;
margin-bottom: 1rem;
outline: 0;
border: 0;
background-color: #646464;
color: white;
padding: .5rem .5rem;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active
{
-webkit-box-shadow: 0 0 0px 1000px #646464 inset;
-webkit-text-fill-color: white;
transition: background-color 5000s ease-in-out 0s;
caret-color: white;
}
button{
border: 2px solid #C00222;
border-radius: 10px;
}
#login{
display: block;
margin: 0 auto;
padding: .4rem 1.333rem;
background-color: transparent;
color: white;
font-size: 16px;
cursor: pointer;
}
#login:hover{
background-color: #C00222;
}
1 Like
yaustar
September 17, 2021, 9:32am
2
Try adding pointer events none to the overlay: pointer-events | CSS-Tricks
pointer-events does the opposite of what i want.
I want my overlay to catch all pointer-events. (Prevent clicking through)
EDIT: I want it to behave like the profiler. I tried event.stopPropagation() which doesn’t work, because for some reason the playcanvas event gets executed before the event on the html element.
yaustar
September 17, 2021, 9:44am
4
Ah yes, I forgot you need pointer events on the overlay to use for the login.
I’m surprised that the PlayCanvas mouse event gets executed before the overlay as it’s listening to the canvas events
In the absolute worse case, you could detach the mouse from the canvas and attach afterwards: https://developer.playcanvas.com/en/api/pc.Mouse.html#attach
You can also create a global variable in your overlay script that is set to true
when there is a click event on it.
Then use that global variable in your regular input scripts (e.g. camera) to bypass input if the overlay has received input.
Leonidas:
You can also create a global variable in your overlay script that is set to true
when there is a click event on it.
Then use that global variable in your regular input scripts (e.g. camera) to bypass input if the overlay has received input.
That would work but is quite a ugly workaround.
Hmm that looks promising.
But I’m still sure that I’m doing something wrong here, because this behaviour does not happen with the profiler. Somehow the profiler blocks the mouse events.
yaustar
September 17, 2021, 10:36am
7
Looking at the code, all the profiler does is use stopPropagation like you have done as well:
root.addEventListener('mousemove', function (evt) {
evt.stopPropagation();
var rect = root.getBoundingClientRect();
mouse.x = evt.clientX - (rect.left + 300);
mouse.y = evt.clientY - rect.top;
mouse.hover = mouse.x > 0;
if (mouse.y < 23) {
timeHover = Math.floor((mouse.x / (width - 300)) * timeNow);
} else {
timeHover = Math.floor(mouse.x / scale + scroll.time);
}
}, false);
root.addEventListener('mousedown', function (evt) {
evt.stopPropagation();
evt.preventDefault();
if (evt.button !== 0 || mouse.click || mouse.down || ! mouse.hover)
return;
mouse.click = true;
}, false);
root.addEventListener('mouseup', function (evt) {
evt.stopPropagation();
if (evt.button !== 0 || ! mouse.down)
return;
mouse.down = false;
mouse.up = true;
}, false);
root.addEventListener('mouseleave', function (evt) {
mouse.hover = false;
timeHover = 0;
if (! mouse.down)
return;
mouse.down = false;
mouse.up = true;
}, false);
root.addEventListener('mousewheel', function (evt) {
evt.stopPropagation();
if (! mouse.hover)
return;
scroll.time = Math.max(0, Math.min(timeNow - capacity, Math.floor(scroll.time + evt.deltaX / scale)));
if (evt.deltaX < 0) {
scroll.auto = false;
} else if (Math.abs((scroll.time + capacity) - timeNow) < 16) {
scroll.auto = true;
}
}, false);
2 Likes
Thanks for leading me in the right direction!
I only tested preventing the click
event, which didn’t work.
But mousedown
and mouseup
work as expected!
2 Likes
yaustar
September 17, 2021, 11:24am
9
FYI, the Editor and launch page JS code is not minimised so you can inspect via devtools and poke around a bit if you need to
1 Like