Panel content is shaking when Panel is resized

Hello,

  • Fuse version 1.4.0 (build 14778)
  • macOS

We have a very big project and it doesn’t make sense to send it, lots of files and code. So I spent some time to made repository, as small as possible to reproduce issue. There can be panels inside panels, but this is exact layout we have in our big project. We have a panel which should be resizable: expanded, half size, collapsed. This panel is supposed to have scroll view with chat messages. When I resize panel, it’s content is shaking, due to relayout or some other kind issue. I don’t know how to fix this. I’ve spent several days, trying different approaches, changing panel height, changing panel margin, etc. Nothing works. I can move panel down, but then I’m not able to scroll to the very bottom, as 50% of panel will be outside of the screen, so moving panel is not an option, we need to change it’s size. Do I have to disable/enable some properties to stop re-layout process or something?

YouTube Video with issue:

https://youtu.be/qnRVJGxbH3I - when I change size of the panel, it’s content is shaking creating bad UX

How to reproduce:

  • git clone git@github.com:poul-kg/scroll-view-content-shaking.git
  • cd scroll-view-content-shaking
  • git checkout content-shaking
  • fuse preview
  • try to drag down grey rectangle with rounded corners (at the top of the screen)
  • panel height will be reduced

Issue:

  • panel content is shaking when panel size height changes

Expected behavior:

  • panel content should not shake

The code you’ve shared is a bit too complex to suggest a solution without digging much deeper into it.

However, I suspect that the root cause of the problem lies in the fact that you’re executing some JavaScript callbacks that, in turn, do some changes to your UX. Since the UI and JS run on separate threads, such approach is prone to result in visual jitter.

As explained on Slack, you should leave all UI-work to UX code and not involve JS in it. Here’s a little proof-of-concept code that you can copy-paste in your MainView.ux while on that content-shaking branch, which does not suffer from any jitter:

<App>
    <DockPanel>
        <JavaScript File="MainView.js" />

        <!-- Status Bar Config -->
        <iOS.StatusBarConfig Style="Dark" IsVisible="true" />
        <Android.StatusBarConfig Color="#052845" IsVisible="false" />

        <DockPanel>
            <DockPanel ux:Name="chatCanvas" Background="#18f" Height="100%" Alignment="Bottom">
                <LayoutAnimation>
                    <Move Vector="1" RelativeTo="PositionChange" Duration="0.3" />
                    <Resize Vector="1" RelativeTo="SizeChange" Duration="0.3" />
                </LayoutAnimation>

                <Panel Dock="Top" Height="96" Color="#f81">
                    <SwipeGesture ux:Name="swipeDown" Direction="Down" />
                    <SwipeGesture ux:Name="swipeUp" Direction="Up" />
                    <Swiped Source="swipeDown">
                        <DebugAction Message="swiped down" />
                        <Set chatCardStates.Active="Half" />
                    </Swiped>
                    <Swiped Source="swipeUp">
                        <DebugAction Message="swiped up" />
                        <Set chatCardStates.Active="Expanded" />
                    </Swiped>
                </Panel>
                
                <ScrollView LayoutMode="PreserveVisual">
                    <StackPanel ItemSpacing="2" Alignment="Bottom">
                        <Each Count="20">
                            <Panel Height="56">
                                <Text Value="{index()}" Alignment="Center" />
                                <Rectangle Color="#fff" CornerRadius="2" />
                            </Panel>
                        </Each>
                    </StackPanel>
                </ScrollView>

                <StateGroup ux:Name="chatCardStates" Active="Expanded">
                    <State ux:Name="Expanded">
                        <Change chatCanvas.Height="100%" />
                    </State>
                    <State ux:Name="Half">
                        <Change chatCanvas.Height="55%" />
                    </State>
                    <State ux:Name="Collapsed">
                        <Change chatCanvas.Height="20%" Delay="0.3" />
                    </State>
                </StateGroup>
            </DockPanel>
        </DockPanel>
    </DockPanel>
</App>