Bigger "Hit Slop" or capture area for GUI ellipse

Hello,

I am trying to make a custom joystick.
I’ve checked the documentation and implemented it as I want but with one exception.
I want to “puck” to still move on the thumb container, even when you move outside it.
so, I will try to explain the desired behaviour:

  1. You press down on the thumContainer -> it sets a flag to true (isPointerDown)
  2. You move your thumb (while it’s still down) -> it changes the position of the puck -< EVEN if you are moving it outside
  3. You press up anywhere -> it sets the flag to false.

I hope it’s clear enough.
You can see this demo (which is basically what’s in the documentation with clipContent = false and clipChildren = false):
https://www.babylonjs-playground.com/#C6V6UY#5

It does everything I mentioned above but the part that it also captures the pointer move outside and effects the puck.

Would like to have some help here.

Thanks!

Maybe @PolygonalSun will be able to help on that one.

Hey @Chubby,

First of all, welcome to the forums! Second, let me take a look and see what’s going on.

So here’s what I’ve got. On both lines 10 and 177, you have the line:

camera.attachControl(canvas, true);

This adds keyboard and mouse controls to the camera. This is why you still have movement, even when you click outside of the puck areas. If you remove those two lines, it should remove those extra pointer captures.

Hi @PolygonalSun, thanks for trying to solve my issue.
I think you failed to understand what I want to achieve.
It’s ok that you can move the camera even without the joysticks.

I will try to explain it with something else.
If you use GUI.ColorPicker, it has circle wrapping a rectangle.
If you move the pointer inside the rectangle and the mouse is outside, it still moves the cursor there. that’s what I want to achieve with my joystick and puck.

I have uploaded a video with the above (ColorPicker)
https://photos.app.goo.gl/r8uY91TsEiNA8na5A

It’s been a while but I haven’t found a solution yet, I would appreciate your help, this became a priority for me.

@PolygonalSun (tagging you again in case you missed my previous comment)

Hey, sorry I missed your comment. Lemme take a look at things and make sure I get on the same page

So here’s what I’m thinking. Making the puck still move when you exit the thumb area will not work with the current code, as is, because the observable that is handling movement only cares about pointermove events that are inside of it. If your pointer moves outside of the thumb areas, you’ll stop getting data and no more events will be handled. To preserve the pointer’s control on the puck, even outside of the boundary, you’ll need to change it so that you’re actually triggering things for the whole window but only updating the puck’s location to values that can only exist within the thumb area. While this explanation may be a bit odd, here’s a code example:

leftThumbContainer.onPointerMoveObservable.add(function(coordinates) {
          if (leftPuck.isDown) {
              xAddPos = coordinates.x-(leftThumbContainer._currentMeasure.width*.5)-sideJoystickOffset;
              yAddPos = adt._canvas.height - coordinates.y-(leftThumbContainer._currentMeasure.height*.5)+bottomJoystickOffset;
              leftPuck.floatLeft = xAddPos;
              leftPuck.floatTop = yAddPos*-1;
              leftPuck.left = leftPuck.floatLeft;
              leftPuck.top = leftPuck.floatTop;
              }
      });

In this part, we move the puck when we’re overtop of the leftThumbContainer but when we’re outside of it, that’s outside of the jurisdiction of the control so we ignore any other input.

Let’s make a few changes and add a couple of things:

// First let's use the whole UI container as our observer area
// Note that this replaces leftThumbContainer.onPointerMoveObservable.add(function(coordinates) 
adt.rootContainer.onPointerMoveObservable.add(function(coordinates) {
          if (leftPuck.isDown) {
              xAddPos = coordinates.x-(leftThumbContainer._currentMeasure.width*.5)-sideJoystickOffset;
              yAddPos = adt._canvas.height - coordinates.y-(leftThumbContainer._currentMeasure.height*.5)+bottomJoystickOffset;
              // Let's the abosulte coordinates and make them relative to the leftThumbContainer
              var localToContainer = leftThumbContainer.getLocalCoordinates(coordinates);
              // Move puck if mouse coords are within x ranges of container
              if (localToContainer.x > 0 && localToContainer.x < leftThumbContainer.widthInPixels) {
              leftPuck.floatLeft = xAddPos;
              leftPuck.left = leftPuck.floatLeft;
              }
              // Move puck if mouse coords are within y ranges of container
              if (localToContainer.y > 0 && localToContainer.y < leftThumbContainer.heightInPixels) {
              leftPuck.floatTop = yAddPos*-1;
              leftPuck.top = leftPuck.floatTop;
              }
            }
      });

While this is a rudimentary way to do it, it does provide functionality that is closer to what the video was providing. The next step would be to check for params with respect to the circle shape of the container rather than treating it as a square. Is this closer to what you were thinking?

This is very close to what I need and I will take it from here and modify it to achieve what I need. thank you very much!.