orlikraf / flutter-hexagon

MIT License
31 stars 17 forks source link

HexagonOffsetGrid doesn't respect width/height constraints properly #10

Open sshipman opened 3 years ago

sshipman commented 3 years ago

If both the width and height are finite, it does not use the smaller of the two to constrain the hexagon size so that the grid fits in the given space. See attached screenshot of a 1x1 flat grid (green) in a very wide and short container (red). hexoffsetgrid_constraints_bug

orlikraf commented 3 years ago

@sshipman I've changed the code a bit before release. I would appreciate if you could confirm that is compatible with your case.

sshipman commented 3 years ago

Unfortunately, there is a subtle difference from my desired behavior, but I can totally understand that as implemented this might be the intended behavior. I've attached 2 screenshots of a 1 column, 2 row flat grid constrained to 400 height. In the sshipman screenshot, you can see that the hexes are each 200 tall (they are horizontally centered as well, since there is no surrounding Row, but that's less important). In the "master" screenshot, the hexes are sized to allow a third half-height hex that does not exist because there are no other columns to actually trigger the offsets. This happens because _hexSizeHeightConstrained uses _displaceRows which is still 1 to calculate the size of the hexes, resulting in a grid that does not fill its container in the constrained direction. 1_col_x_2_row_sshipman 1_col_x_2_row_master

Here's a the demo build method for the screenshots:

  Widget build(BuildContext context) {
    return Container(
        color: Colors.blue,
        alignment: Alignment.center,
        child: Container(
            alignment: Alignment.center,
            height: 400,
            color: Colors.red.shade900,
            child: HexOffsetGridOddFlat(1, 2)));
  }

  Widget HexOffsetGridOddFlat(int cols, int rows) {
    return Container(
        decoration: BoxDecoration(
          border: Border.all(),
        ),
        child: HexagonOffsetGrid.oddFlat(
          columns: cols,
          rows: rows,
          buildTile: (int col, int row) => HexagonWidgetBuilder(
            elevation: 2,
            color: Colors.lightGreen,
            child: Text(
              "${col} ${row}",
              style: TextStyle(
                  fontSize: 20,
                  decoration: TextDecoration.none,
                  color: Colors.black,
                  backgroundColor: Colors.transparent),
            ),
          ),
        ));
  }

Incidentally, this doesn't actually directly affect the app I'm building, so fixing it is lower priority for me. I do have 1 row, many column grids, but they are Flat, so the general offset and sizing logics apply.

orlikraf commented 3 years ago

I will look into your example but currently I'm a bit occupied with other work. You have a point about alignment as it should be possible to control it. Yet I'm thinking if single column/row cases should be approached in grid at all. After all it is easy enough to create single column of flat hexagons or row of pointy one's. In case where you have dynamic number of rows that would change from 1 to more it would be strange to see resized hexagons.

sshipman commented 3 years ago

I think the argument about sizing changing is a good one and was what I meant by "might be intended behavior". I accept that reasoning.

For the alignment, I suggest allowing the main and cross axis configuration parameters and passing them to the outer Row/Column. I'd be happy to discuss that further in another issue or offline.

mdbill commented 9 months ago

The pointy length of a hex is 1.1547005 more than the flat. So, in hexagon_offset_grid.dart, in the _hexsize function, change:

      if (hexType.isFlat) {
        gridWidth = 1 + (0.75 * (columns - 1));
        gridHeight = rows + (_displaceRows / 2);
      } else {
        gridWidth = columns + (_displaceColumns / 2);
        gridHeight = 1 + (0.75 * (rows - 1));
      }

to

 if (hexType.isFlat) {
        gridWidth = 1.1547005 * (1 + (0.75 * (columns - 1)));
        gridHeight = rows + (_displaceRows / 2);
      } else {
        gridWidth = columns + (_displaceColumns / 2);
        gridHeight = 1.1547005 * (1 + (0.75 * (rows - 1)));
      }

@orlikraf : are you still actively maintaining?

orlikraf commented 9 months ago

@mdbill You can say so but only on holidays when I'm off my regular work :)

Where did this number came from? How did you found it? can you explain it some details?

mdbill commented 9 months ago

Sure, if you think about it, from point to point, a hex is longer than flat side to flat side. I googled "hexagon height to width ratio"... "The height-to-width ratio of a regular hexagon is 1:1.1547005. This means that a hexagon with a long diagonal of 1.0000000 will have a distance of 0.8660254 between parallel sides." My code works perfectly with this edit. (I'm resizing the window, so it changes from height-limited to width-limited.) btw, Thanks for the work on this package! (and yes, I would like to have a 'border' property too. It was mentioned in another issue)