BTMorton / angular2-grid

A drag/drop/resize grid-based plugin directive for angular2
https://bmorton.co.uk/angular/
MIT License
354 stars 159 forks source link

limit_to_screen: true freezes browsers #237

Open Ketec opened 7 years ago

Ketec commented 7 years ago

If the widget inside the container needs to be rearranged because the container is smaller on initial page load or component - something causes infinite loop until browser asks to kill the script.

For example a container the size of a full screen viewport and item positioned to the right side. Make the browser windows narrow and refresh the page or navigate to a diff route then back.

It seems like it cant handle repositioning or tries to do it too early before view is ready.

BTMorton commented 7 years ago

I have made a change to how limit_to_grid works. Can you try it on the demo site and see if you still get the issue? https://bmorton.co.uk/angular/

Ketec commented 7 years ago

cannot try it on the demo site because the limit to screen setting resets when you reload the page and there is no router based navigation to trigger the same problem. I updated my package to the latest version, installed - the issue remains.

My config is like this:

    public gridConfig: NgGridConfig = <NgGridConfig>{
        margins: [5],            //  The size of the margins of each item. Supports up to four values in the same way as CSS margins. Can be updated using setMargins()
        draggable: true,          //  Whether the items can be dragged. Can be updated using enableDrag()/disableDrag()
        resizable: true,          //  Whether the items can be resized. Can be updated using enableResize()/disableResize()
        max_cols: 48,              //  The maximum number of columns allowed. Set to 0 for infinite. Cannot be used with max_rows
        max_rows: 0,              //  The maximum number of rows allowed. Set to 0 for infinite. Cannot be used with max_cols
        visible_cols: 0,          //  The number of columns shown on screen when auto_resize is set to true. Set to 0 to not auto_resize. Will be overriden by max_cols
        visible_rows: 0,          //  The number of rows shown on screen when auto_resize is set to true. Set to 0 to not auto_resize. Will be overriden by max_rows
        min_cols: 0,              //  The minimum number of columns allowed. Can be any number greater than or equal to 1.
        min_rows: 0,              //  The minimum number of rows allowed. Can be any number greater than or equal to 1.
        col_width: 25,           //  The width of each column
        row_height: 25,          //  The height of each row
        cascade: 'up',            //  The direction to cascade primeng items ('up', 'right', 'down', 'left')
        min_width: 25,           //  The minimum width of an item. If greater than col_width, this will update the value of min_cols
        min_height: 25,          //  The minimum height of an item. If greater than row_height, this will update the value of min_rows
        fix_to_grid: false,       //  Fix all item movements to the primeng
        auto_style: true,         //  Automatically add required element styles at run-time
        auto_resize: false,       //  Automatically set col_width/row_height so that max_cols/max_rows fills the screen. Only has effect is max_cols or max_rows is set
        maintain_ratio: false,    //  Attempts to maintain aspect ratio based on the colWidth/rowHeight values set in the config
        prefer_new: false,        //  When adding new items, will use that items position ahead of existing items
        limit_to_screen: true   //  When resizing the screen, with this true and auto_resize false, the primeng will re-arrange to fit the screen size. Please note, at present this only works with cascade direction up.
    };

I currently go one item configured like this: <NgGridItemConfig>{minWidth: 350, minHeight: 300, resizable: false, col: 37, row: 1, dragHandle: '.handle', fixed: true}

BTMorton commented 7 years ago

Can you verify this in the latest version? Demo site should be updated

Ketec commented 7 years ago

While it does not seem to freeze - the cards do not rearrange anymore back to original on window resize.

Ketec commented 7 years ago

Back from vacation, checked again - while freeze is gone - the cards default to the left side - likely 0 0 position - when the container is smaller than nr of cols * width. (lets say w500px container, 10x 50px columns, card is on the right side, container resized to 499px, the card is reset to 0x0 position) .

rufreakde commented 7 years ago

I still have freezes in some situations.

This function loops forever:

private _getCollisions(pos: NgGridItemPosition, dims: NgGridItemSize): Array<NgGridItem> {
        const returns: Array<NgGridItem> = [];

        if (!pos.col) {
            pos.col = 1;
        }
        if (!pos.row) {
            pos.row = 1;
        }

        for (let j: number = 0; j < dims.y; j++) {
            if (this._itemGrid[pos.row + j] != null) {
                for (let i: number = 0; i < dims.x; i++) {
                    if (this._itemGrid[pos.row + j][pos.col + i] != null) {
                        const item: NgGridItem = this._itemGrid[pos.row + j][pos.col + i];

                        if (returns.indexOf(item) < 0)
                            returns.push(item);

                        const itemPos: NgGridItemPosition = item.getGridPosition();
                        const itemDims: NgGridItemSize = item.getSize();

                        i = itemPos.col + itemDims.x - pos.col;
                    }
                }
            }
        }

        return returns;
    }

I try to understand what it is doing in its steps to find a solution. ( I know that its a collision detection )