tiberiuzuld/angular-gridster2

More issues with enableBoundaryControl (with suggested fixes)

AndeYashwanth opened this issue · 0 comments

To reproduce below issues, set enableBoundaryControl to true in home.component.ts.

  1. Keep the grid item touching right or bottom boundary, start dragging away from the boundary. It will be smooth. But if we now start dragging from a point between the boundary and the initial drag point then the widget suddenly moves to different place and then comes back loking like stutter.
    probable cause:

    • lastmouse x and y values of previous drag is being considered to calculate which direction the mouse is going. It should be reset to 0 whenever drag starts. So if grid item is on right, lastmouse.clientX = 1000(ie, previous mouse x-axis position) and initial mouse x-axis position=1100 when drag has started, then direction is being considered as right. But at the instant drag starts there should be no direction.

    • https://github.com/tiberiuzuld/angular-gridster2/blob/master/projects/angular-gridster2/src/lib/gridsterDraggable.service.ts#L208

      this.gridsterItem.el.getBoundingClientRect().bottom, this.gridster.el.getBoundingClientRect().bottom - this.margin
      this.gridsterItem.el.getBoundingClientRect().right, this.gridster.el.getBoundingClientRect().right - this.margin

      Both sides of these values should be equal when the widget touches bottom boundary or right boundary respectively. But they are off by few milli pixels. example values below. There is no such issue with top and left.

      (position) gridsterItem gridster-margin
      bottom 721.8000183105469 722
      right 980.6499938964844 980.4000396728516

      I couldn't figure out why thats happening.

    suggested fix: Above both points are issues, but fixing anyone should solve the issue.

    1. Set this.lastMouse.clientX and clientY to 0 when dragStart to resolve first issue. I think this option is better.
    2. Maybe remove decimal places when comparing to resolve second issue?
  2. When a widget is dragged and quickly moved into any one of the boundaries i gets stuck partly outside boundary.
    probable cause: widget position is set by lastMouse.clientX or clientY during drag based on direction. So when the item is quickly moved out of bounds then the lastMouse position is not updated quickly enough making the griditem move out of bounds.
    suggested fix: Instead of using lastMouse values to set bounds, calculate the bounds for the mouse cursor when the drag starts and use min and max when creating new mouse event. Also remove the filtering of directions ex: directions = directions.filter(direction => direction != Direction.DOWN); Even after making these changes if we slide the widget along one direction and pushed into a corner it still goes out of bounds as below if conditions misses 4 corners.
    https://github.com/tiberiuzuld/angular-gridster2/blob/master/projects/angular-gridster2/src/lib/gridsterDraggable.service.ts#L186

    dragStart() {
        ...
        // yande: Added mousebundaries property and initialise during dragstart.
         this.mouseBoundaries = {
            top: this.gridster.el.getBoundingClientRect().top + this.margin + (e.clientY - e.movementY - this.gridsterItem.el.getBoundingClientRect().top) - 1,
            left: this.gridster.el.getBoundingClientRect().left + this.margin + (e.clientX - e.movementX - this.gridsterItem.el.getBoundingClientRect().left) - 1,
            right: this.gridster.el.getBoundingClientRect().right - this.margin - (this.gridsterItem.el.getBoundingClientRect().right - e.clientX + e.movementX) + 1,
            bottom: this.gridster.el.getBoundingClientRect().bottom - this.margin - (e.clientY-e.movementY - this.gridsterItem.el.getBoundingClientRect().bottom) + 1,
        }
        ...
    }
    dragMove() {
        ...
        if (this.gridster.options.enableBoundaryControl) {
            // prevent moving up at the top of gridster
            if ( directions.includes(Direction.UP) && this.gridsterItem.el.getBoundingClientRect().top < this.gridster.el.getBoundingClientRect().top + this.margin) {
                // yande: Removed direction filters as it's not necessary
                e = new MouseEvent(e.type, {
                    clientX: e.clientX,
                    clientY: Math.max(this.lastMouse.clientY, this.mouseBoundaries.top)
                });
            }
            // prevent moving left at the leftmost column of gridster
            if (directions.includes(Direction.LEFT) && this.gridsterItem.el.getBoundingClientRect().left < this.gridster.el.getBoundingClientRect().left + this.margin) {
                e = new MouseEvent(e.type, {
                    clientX: Math.max(this.lastMouse.clientX, this.mouseBoundaries.left),
                    clientY: e.clientY
                });
            }
            // prevent moving right at the rightmost column of gridster
            if (directions.includes(Direction.RIGHT) && this.gridsterItem.el.getBoundingClientRect().right > this.gridster.el.getBoundingClientRect().right - this.margin) {
                e = new MouseEvent(e.type, {
                    clientX: Math.min(this.lastMouse.clientX, this.mouseBoundaries.right),
                    clientY: e.clientY
                });
            }
            // prevent moving down at the bottom of gridster
            if (directions.includes(Direction.DOWN) && this.gridsterItem.el.getBoundingClientRect().bottom > this.gridster.el.getBoundingClientRect().bottom - this.margin) {
                e = new MouseEvent(e.type, {
                    clientX: e.clientX,
                    clientY: Math.min(this.lastMouse.clientY, this.mouseBoundaries.bottom)
                });
            }
          }
          // yande: removed if condition so that it is calcualted everytime irrespective of allowed directions
          this.offsetLeft = this.gridster.el.scrollLeft - this.gridster.el.offsetLeft;
          this.offsetTop = this.gridster.el.scrollTop - this.gridster.el.offsetTop;
          scroll(
          this.gridster,
          this.left,
          this.top,
          this.width,
          this.height,
          e,
          this.lastMouse,
          this.calculateItemPositionFromMousePosition
          );
          this.calculateItemPositionFromMousePosition(e);
    }
  3. An tem can be resized out of bounds even after setting boundarycontrol. But this issue is only for top and left sides. Item cant be resized outside of right and bottom boundary. Though I didnt see any code to handle boundary control for resizing.
    I didn't investigate this so have no idea why it's working only for right and bottom boundary.
    Fixed in #861

  4. An tem can be pushed out of bounds by other item even after setting boundarycontrol.