I'm trying to mock up a turn based strategy, civ like game in the browser. I want to have a css grid that can load/unload content as the user scrolls the board/world.
My current method is to render a css grid 50x50, detect how many rows and columns are visible, then render the grid again based on that size. I'm having a hell of a time getting this to work perfectly.
The parent component doesn't seem to wait for child component to finish. The parent component being the board frame and the child being all the rows and columns. Using afterUpdate() show many consoles logs when I think I want just one? onMount/afterUpdate console logs in parent trigger before console logs in children.
I'm using svelte inview: https://www.npmjs.com/package/svelte-inview
The inview_enter() seems to detect tiles entering viewport in random order. Every refresh is a different order. Putting async await on everything doesn't help. I must be misunderstanding something basic.
Another issue is that the initial render has a scrollDirection of down and right so I can't simply use those in logic on invew_enter() to detect scroll changes because it also triggers on initial render. I can't figure out a way to ignore initial render
Basically, is this approx the correct way to do it? Some other way I'm not considering?
Here is a code example. // pagelet visibleRows = []let visibleColumns = []afterUpdate(() => { console.log("this runs before child component <GameBoard/> is done running") })<GameBoard visibleRows={visibleRows} visibleColumns={visibleColumns}/>// GameBoard<script lang="ts"> afterUpdate(async () => { // tick() await tick() console.log("afterUpdate") console.log($$props.visibleRows) console.log($$props.visibleColumns) console.log("This runs many times after the parent page component console logs") }) async function onHandleEnterRow(row:number) { console.log("add row") console.log(row) await tick() $$props.visibleRows = [...$$props.visibleRows, row]; console.log($$props.visibleRows) } async function onHandleEnterColumn(column:number) { console.log("add column") console.log(column) await tick() $$props.visibleColumns = [...$$props.visibleColumns, column]; console.log($$props.visibleColumns) }</script><div id="gameBoard" class="gameBoardContainer" style={`display:grid; grid-template-columns: repeat(${initialGameState.gameSettings.initialSizeX+2}, 1fr); `} ><div style="border:1px solid black; position:sticky; background-color:pink; top:0; left:0; z-index: 4;"/> {#each range(1, initialGameState.gameSettings.initialSizeX) as column (column)}<CoordinateRow columnNumber={column} location="top:0;"/> {/each}<div style="border:1px solid black; position:sticky; background-color:pink; top:0; right:0; z-index: 4;"/> {#each range(1, initialGameState.gameSettings.initialSizeY) as row (row)} {#each range(1, initialGameState.gameSettings.initialSizeX) as column (column)} {#if column == 1}<div style="background-color: white; border:1px solid black; position:sticky; left:0; z-index:3;"> {row}</div> {/if}<div id={`${row}:${column}`} style="border:1px solid black; background-color:lightgreen; padding:3px;" use:inview={options} on:inview_enter={async (event) => { const { inView, entry, scrollDirection, observer, node} = event.detail; isInView = inView; if(!$$props.visibleRows.includes(row) && column === 2) { await onHandleEnterRow(row) } if(!$$props.visibleColumns.includes(column) && row === 2) { await onHandleEnterColumn(column) } // console.log($$props.visibleRows) // console.log($$props.visibleColumns) // await tick() }}><BoardTileContents row={row} column={column}/></div> {#if column == initialGameState.gameSettings.initialSizeX}<div style="background-color: white; border:1px solid black; position:sticky; right:0; z-index:3;">{row}</div> {/if} {/each} {/each}<div style="border:1px solid black; position:sticky; background-color:pink; bottom: 0; left:0; z-index: 4;"></div> {#each range(1, initialGameState.gameSettings.initialSizeX) as column (column)}<CoordinateRow columnNumber={column} location="bottom:0;"/> {/each}<div style="border:1px solid black; position:sticky; background-color:pink; bottom:0; right:0; z-index: 4;"></div></div>