How do you keep draggable objects inside the bounds of a pop-up window?

How can I revise the following code so the circle cannot be dragged outside of the bounds of the pop-up window:

//Create pane
const pane = new Pane({
width: 1000,
height: 500,
backgroundColor: "white",
draggable: true,
close: true,
}).center(topContainer);

//Create button to close pane
const closeButton = new Button(41, 41, "X", "purple", "orange", "white", "2", 5).center(pane).mov(480,-230);

// Event handler to close pane
closeButton.tap(() => {
pane.removeFrom();
S.update();
});

//Test content to drag within window
let circle = new Circle(25, yellow);
circle.center(pane).drag(pane);

Hi @Jac - good question. It works fine if you are not dragging the pane. If you drag the pane then you need to set localBounds:true in the drag.

But... sigh... if you give a DisplayObject as the boundary then it assume top left corner is the registration point. But the Pane content has its registration point in the middle so things can easily be centered in it - just by addTo(). So we need to make a custom Boundary object as follows:

circle.center(pane).drag({
    boundary:new Boundary(
        // x, y relative to 0,0 in the middle of the pane
        -pane.width/2+circle.radius, -pane.height/2+circle.radius, 
        // width and height
        pane.width-circle.width, pane.height-circle.height
    ), 
    localBoundary:true
});
1 Like

Thanks for the clarification, Dr. Abstract. Rather than have the circles I am adding be draggable in the pop window, I've shifted approaches. I am now adding them to tile called firstframe. Adding them individually using a stepper was no problem:

const stepper = new Stepper().center(pane).mov(-225, 150).sca(0.8).change(() => {
let clickIndex = stepper.currentValue-1;
loop(firstframe, (rectangle, index) => {
if (index === stepper.selectedIndex - 1) { // index starts from 0
let circles = new Circle(15, black).center(rectangle);
S.update();
}
});
});

However, removing a circle each time the stepper decrements has got me stumped. Thanks for your help.

Not sure what you are making but perhaps a Stepper is not the best thing to use as you can enter numbers - so jump to 8 then to 2. But here is an example with tabs having a + and - sign. We removed randomly but there is commented code to remove in reverse order.

One thing to watch for although we do not do it here, is that if you ever loop through a container or array and remove inside the loop function then make sure to loop backwards by using the true in the parameter after the function.

container.loop(child=>{
   if (child.hitTestPoint(W/2, H/2)) {
      child.removeFrom();
      S.update();
   }
}, true); // true for loop backwards
1 Like

Thank you very much for the example code and advice on looping backwards.

2 Likes