Closed nimmolo closed 2 years ago
I'm reading trough MasonryInfiniteGrid
options again. I'm noticing it seems like maybe i can set column={0}
so it will calculate columns from width of first element.
@daybrush - Can MasonryInfiniteGrid use a percentage value for width of first element? If so i could just use Bootstrap responsive column classes on the first element.
Using those Bootstrap column classes, my item elements have
flex: 0 0 auto;
width: 100%;
@(min-width: 768px) width: 50%;
@(min-width: 992px) width: 33.3333333%;
@(min-width: 1400px) width: 25%;
But this is still giving "incorrect" column with calculations, even if I make the gap={0}
- MIG is calculating 3 columns instead of 4, 2 instead of 3, etc., with large gaps. The elements do have the correct widths, but the inline positions for the three columns are left: 0%;
left: 37.4844%;
and left: 74.9689%;
which leaves big gaps, where it seems it should be left: 0;
left: 25%
left:50%;
left:75%
Hmm - what is the difference between isEqualSize
and isConstantSize
? In the documentation it sounds the same. But when I use in a layout,isEqualSize
seems to mean width and height of all items is the same. Maybe isConstantSize
means only the width is the same?
If i use isConstantSize={true}
, the first batch of items still 3-column position as above, but the second batch of added elements comes in with the desired 4-column position. Very unexpected!
Like this:
@nimmolo
Since the column
can be changed dynamically, it must be changed programmatically according to its size.
isConstantSize
does not change the size of the item anymore even if it is resized.
isEqualSize
means that all items have the same size.
The above problem will be fixed in the next version.
@daybrush - I see, Ok, no problem. Maybe should I wait for next version, and work on other things.
But IG does calculate column size (or container size?) correctly for the second load π€, in last image above. Why do you think IG can correctly calculate column size on the reload load of data, but incorrect on first load? Is there a way I can help pass that calculation of column size (or container size) programatically to IG so it can calculate first column correctly?
@nimmolo
The reason is not well understood, but I think it is a decimal point issue. Here is the code to fix this problem in the next version
@nimmolo
Test @egjs/svelte-infinitegrid@4.1.2-beta.4 (beta) version. Thank you :)
Thanks @daybrush - I updated to @egjs/svelte-infinitegrid@4.1.2-beta.4.
Issue is still present, at first. But π if I resize the window, the columns are now correctly calculated. So something is getting better. Responsive changing number of columns at different container size is also correctly calculated, when window is resized.
If window is not resized: It seems that the first calculation of column width is maybe a little narrower, but... still wrong number of columns on load. On reload, the number of columns is again suddenly correct, but position is unpredictable. First load does not re-layout, so there are two areas with different columns.
To help with troubleshooting i can include my most recent code. Let me know if there is anything else I can do to help.
Here is the Svelte template currently:
<MasonryInfiniteGrid
class="row ig"
useLoading={true}
useFirstRender={true}
gap={0}
percentage={true}
column={0}
items={newItems}
itemBy={(item) => item.cursor}
bind:this={ig}
on:requestAppend={({ detail: e }) => {
e.wait();
handleNext();
e.ready();
if (newItems.length && pageInfo.hasPreviousPage) {
items = [...items, ...newItems];
}
}}
let:visibleItems
>
{#each visibleItems as item (item.key)}
<Item edge={item.data} />
{/each}
</MasonryInfiniteGrid>
{/if}
If i useLoading
, there's a separate issue with both beta.3 and beta.4 -- I did not mention before, but maybe relevant. When I scroll to the loading
div, the screen and scroll bar "flickers" very fast, and nothing loads. I must scroll backwards and forwards to loading
several times to load the new batch.
If I don't useLoading
, it doesn't flicker, and mostly does load new batch. However, not always. (For UX i would like to useLoading, but it's not necessary to troubleshoot now.)
Here is the CSS, standard Bootstrap 5.1 row and column layout, nothing special.
.row {
--bs-gutter-x: 1.25rem;
--bs-gutter-y: 0;
display: flex;
flex-wrap: wrap;
margin-top: calc(-1 * var(--bs-gutter-y));
margin-right: calc(-0.5 * var(--bs-gutter-x));
margin-left: calc(-0.5 * var(--bs-gutter-x));
}
.row > * {
flex-shrink: 0;
width: 100%;
max-width: 100%;
padding-right: calc(var(--bs-gutter-x) * 0.5);
padding-left: calc(var(--bs-gutter-x) * 0.5);
margin-top: var(--bs-gutter-y);
}
.col-12 {
flex: 0 0 auto;
width: 100%;
}
@(min-width: 768px) {
.col-md-6 {
flex: 0 0 auto;
width: 50%;
}
}
@(min-width: 992px) {
.col-lg-4 {
flex: 0 0 auto;
width: 33.33333333%;
}
}
@(min-width: 1400px) {
.col-xxl-3 {
flex: 0 0 auto;
width: 25%;
}
}
.ig {
height: 600px; // initial height, gets overwritten
}
@nimmolo
useLoading is a property to use the loading bar. You don't need to use it here.
How to add :global(...)
to use InfiniteGrid class in Svelte?
:global(:ig)
.global(.row)
.global(.row) > *
@daybrush β Thanks for the info on useLoading
- I do want to use it eventually.
The columns are still incorrectly calculated on load β only when the browser window is resized, they are recalculated correctly.
My CSS is loaded OK and applied to the container and items, there's no problem there. I included the CSS above so you could reproduce the problem for testing, maybe it can help with troubleshooting. Maybe easier to just include the Bootstrap stylesheet from the repository. Let me know if there's anything i can do to help, or if you need me to make a demo or REPL.
Also, please let me know if you want me to play around with the beta4 code locally, i haven't been able to figure out where it calculates the column size yet. Do you believe the bug is in the core IG code, or only the Svelte part? If you can maybe point me to the place in the code where this calculation done, i'm happy to try to help find a fix. I appreciate all the work you guys are doing.
(I have all my global styles in a global.scss file, and they are imported by the __layout.svelte
at the top level of the app. I don't have any of them in the component.)
@nimmolo
What I can think of is that the InfiniteGrid makes position: absolute, so the width may be different when it is not absolute. Why don't you check this part out?
@daybrush Thanks - i'm checking it out in FF, Chrome, Safari:
Each item width is defined in item CSS class as width: 25%
, but on first render, IG is positioning every item in the second column at left: 37.3894%
, not left: 25%
. Note that gap={0}
.
When window is resized, layout is "corrected", but second item is positioned left: 25.0053%
, third item at left: 50.0106%
, fourth item at left: 75.0159%
. I think this is the problem, the fractional difference is small, but maybe it's too much on first render. What do you think?
In any case, position: absolute
means IG is calculating one of the widths incorrectly, either for the grid container or the first item, because every item is positioned according to the ratio between these two calculations. is that right?
I want to help find where it's getting that calculation "wrong". Is there a place in IG code i can console.log IG's caclucated width for the grid container and the first item? this should tell me what it's calculating. I've noticed cssRect
and rect
properties, but i don't see the central place where I should log these to examine.
update: I tried transform
instead of position: absolute
- same. Columns are incorrect, then when window is resized, they are "correct". However, transform
uses px
instead of %
@nimmolo
center = item.cssRect.left + item.cssRect.width / 2
It seems that the width has changed strangely as it is changed to position:absolute.
How about removing display:flex?
Do you have an address where I can test?
@daybrush thanks - I removed display:flex
and negative margin on grid container, no change. I also tried disabling lazy-load image, but still no change.
I don't have a staging site set up yet. π Only local dev site. Maybe i can make a simpler REPL for you to check out? Using bootstrap style...
It still seems that item.cssRect.width
is being incorrectly calculated. How is this being calculated? element.outerWidth
?
@nimmolo
oh sorry It is item.rect.width. However, this may also be calculated incorrectly. rect is the position and size obtained from the element. cssRect is the position and size registered in style.
It is calculated as item.offsetWidth. It would be nice if you could make a repl.
@daybrush Ok thank you. I will make a repl, it may take a couple days. I have never made before.
I can upload the beta4 version to the repl?
@nimmolo
yes. beta.4 Thank you :)
@daybrush
~~I just realized I don't know. How do i include the files for infinitegrid to the repl?
Or do i just put import { MasonryInfiniteGrid } from "@egjs/svelte-infinitegrid";
and it will work~~
Yes. I got it. Nevermind!
@daybrush Repl was easy! :) Here it is
Be sure to make the window wider before the repl loads, to see incorrect columns.
If you resize after load, columns will be always correct, also for me locally. It's first load that is the problem.
Thank you for checking it out, i appreciate it. π Edit: Just realized maybe you can't easily examine the CSS this way. I made a comment referencing only the rules that are used, so you can override more easily.
@nimmolo
oh thank you The reason was confirmed.
The container size was obtained incorrectly. The reason is that the container size was obtained before the bootstrap.css load was completed.
margin-right: calc(-.5 * var(--bs-gutter-x));
margin-left: calc(-.5 * var(--bs-gutter-x));
I'll try to solve this way.
I am trying to use ResizeObserver.
https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
Will you have any problems?
@daybrush Sounds good. Thank you for figuring that out, it makes sense.
ResizeObserver seems great, and I don't need to support IE...i'm also using IntersectionObserver for lazy loading, similar api.
@daybrush did you mean i should try ResizeObserver in my code? (or maybe you're going to try to implement in Infinite Grid...)
Let me know if i can help experiment, i'm happy to try a PR, or test anything.
@nimmolo
Today or tomorrow we will add the option.
π Awesome
@nimmolo
Try @egjs/svelte-infinitegrid@4.2.0-beta.2 version
And use prop useResizeObserver={true}
@daybrush - thank you π
EDIT - columns are working on my local app, now - they are calculated correctly on first load. (There seems to be a difference in infinite loading - infinite works but threshold is acting differently. I had to increase the threshold to 200, but this may be related to something in my CSS, I will test some more.)
However, I am not sure if useResizeObserver
quite fixed it π―. See repl here - if you open the right side of the REPL window wide before everything loads, columns are still computed incorrectly. I updated the repl with the new version and the param useResizeObserver
. If you resize the window after load, columns are recomputed ok, but this was also true before β with version 4.1.2.beta4, columns were correct after resize.
It's during the first render on the repl, container width is miscalculated, maybe again before bootstrap CSS loads. I can't tell why it's different on the REPL.
Try @egjs/svelte-infinitegrid@4.2.0-beta.5 version
In repl, only latest is applied, so it seems that the beta version cannot be used. It seems to work fine when I test it locally.
Thank you @daybrush - Layout seems to work correctly on my local install, columns are correct in the first render. I understood what you said about Repl using only latest released version.
I believe the @egjs/svelte-infinitegrid@4.2.0-beta.5
version solves the issue. Thanks!
This issue/PR has been automatically marked as stale because it has not had any update (including commits, comments, labels, milestones, etc) for 30 days. It will be closed automatically if no further update occurs in 7 day. Thank you for your contributions! νκΈ
μ΄ μ΄μ/PRμ commits, comments, labels, milestones λ± 30μΌκ° νλμ΄ μμ΄ μλμΌλ‘ stale μνλ‘ μ νλμμ΅λλ€. μ΄ν 7μΌκ° νλμ΄ μλ€λ©΄ μλμΌλ‘ λ«ν μμ μ
λλ€. νλ‘μ νΈ κ°μ μ κΈ°μ¬ν΄μ£Όμ
μ κ°μ¬ν©λλ€.
I know it is possible to define column size in px, and then there will be as many columns as possible will fit in container.
But is it possible to define column size in % and set a different number of columns for different screen width?
I'm thinking of the way bootstrap flex columns (the layout effect, not the CSS). MasonryIG uses absolute position so implementation is different, but i'd like to get responsive percentage based column effect. (something like
col-12 col-md-6 col-lg-4 col-xxl-3
)Currently i'm using something like
percentage={true}
andcolumn={3}
. Maybe param would becolumn={{0: 1, 460: 2, 998: 3, 1200: 4}}