Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphics layer does not render items offset outside of it #2198

Closed
ejektaflex opened this issue Jul 22, 2022 · 7 comments
Closed

Graphics layer does not render items offset outside of it #2198

ejektaflex opened this issue Jul 22, 2022 · 7 comments
Labels
bug Something isn't working desktop

Comments

@ejektaflex
Copy link

This seems to be intentional (since normally the graphics layer's contents are confined within the layer). However, there is a use case for why one might want a graphics layer the renders regardless of it's position/size:

For my application I am using the layer as a sort of cartesian graph where the user can pan/zoom/etc, and all of the contents can exist at any (X,Y) value in space. Each of those elements is offset with .offset { their x, y pos }. The problem is that when you pan up above the origin and drag an element above the origin, it disappears because it is no longer within the graphics layer, which is set to only be the max size of it's container box.

The ability to be able to render items outside of the bounds of the graphics layer is what I would need to get around this - it might require a new type of graphics layer that does not do bounds checking when deciding whether to render or not - since the entire "graph" is an infinite cartesian plane, items should be able to be rendered anywhere, even outside of the bounds of the graphics layer.

I have tried another method to get around this limitation, which is by choosing not to pan the graphics layer at all and place all elements at .offset { their x, y pos + graph pan x, y }, but this causes an enormous amount of lag when panning and there are a lot of elements in the graph, because whenever the pan amount changes it will cause every single element in the graph to update their position at once. The more performant option is just to stuff all elements inside of the graphics layer that gets panned, eliminating the cascading updates occurring to each element, but that's impossible if panning the graph makes it all disappear when the main graph goes offscreen.

I'm not sure if there are any methods that I am unaware of that would solve this problem. Thanks!

@Antimonit
Copy link

I've run into the same issue. This issue manifests even with high-level composables, such as Modifier.offset.

Example:

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        var offset by remember { mutableStateOf(IntOffset.Zero) }

        LaunchedEffect(Unit) {
            repeat(200) {
                delay(10)
                offset -= IntOffset(10, 0)
            }
        }

        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Red)
                .offset { offset }
                .background(Color.Blue)
        ) {
            repeat(20) {
                Text(
                    text = "$it",
                    modifier = Modifier
                        .size(50.dp)
                        .offset(100.dp * it, 0.dp)
                        .background(Color.Green),
                )
            }
        }
    }
}

We add enough Text composables so that some of them extend beyond the boundaries of the parent Box. Then, if we .offset { offset } the Box enough that the blue background is no longer visible, it will also hide all Texts, although some of them should still be visible.

Not sure what to do about this.

@Antimonit
Copy link

Oh wow. This happens only with the pixel-based offset. Once replaced with the DP-based offset, the issue disappears.

fun main() = application {
    Window(onCloseRequest = ::exitApplication) {
        var offset by remember { mutableStateOf(DpOffset.Zero) }

        LaunchedEffect(Unit) {
            repeat(200) {
                delay(10)
                offset -= DpOffset(10.dp, 0.dp)
            }
        }

        Box(
            modifier = Modifier
                .fillMaxSize()
                .background(Color.Red)
                .offset(offset.x, offset.y)
                .background(Color.Blue)
        ) {
            repeat(20) {
                Text(
                    text = "$it",
                    modifier = Modifier
                        .size(50.dp)
                        .offset(100.dp * it, 0.dp)
                        .background(Color.Green),
                )
            }
        }
    }
}

@dima-avdeev-jb dima-avdeev-jb added bug Something isn't working desktop labels Nov 28, 2022
@dima-avdeev-jb
Copy link
Contributor

Made minimal reproduction sample, that work's good on Android, and work's bad on Desktop:
https://github.com/dima-avdeev-jb/reproduce-bug-with-offset

@ejektaflex
Copy link
Author

I just checked this out again in 2023, and it is still present a year later in Jetbrains Compose 1.4.3 on Desktop.

@ejektaflex
Copy link
Author

ejektaflex commented Aug 19, 2023

Seems to also be related to #2807 (and by extension perhaps #1559)

@igordmn
Copy link
Collaborator

igordmn commented Nov 21, 2023

The core issue is the same as in #2807, let's keep only 2807.

@okushnikov
Copy link
Collaborator

Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working desktop
Projects
None yet
Development

No branches or pull requests

5 participants