I gave this a try and got pretty close to the desired effect, however, my limited experience with Uno doesn’t allow for fiddling around with Visual
s and their position.
The main problem is that there is no point of reference in JS, which would tell us exactly how far the ScrollView has travelled - a relative ScrollPosition in % would be the closest to what we need.
In addition to that, I can see how having this point of reference would have the potential to have a negative impact on app performance - having a realtime-updated variable as one scrolls must be expensive.
Here’s to hoping @mortoray is getting ready with ScrollView-related positioning features
UX:
<App>
<JavaScript>
var Observable = require('FuseJS/Observable');
var position = Observable(0);
function scrolled(args) {
console.log('scrolling motion done');
};
module.exports = {
'position': position,
'scrolled': scrolled
};
</JavaScript>
<ClientPanel Background="#eee">
<StackPanel Alignment="VerticalCenter" Margin="10,0,10,0">
<WhileFalse ux:Name="IsScrolling" Value="false">
<Callback Handler="{scrolled}" />
</WhileFalse>
<Text Value="{position}" FontSize="22" TextColor="#333" Alignment="Center" Margin="20" />
<ScrollView ux:Name="_scrollView" AllowedScrollDirections="Horizontal">
<ScrollingAnimation>
<Move X="0.95" RelativeNode="_scrollView" RelativeTo="Size" Target="_scrollIndicator" />
</ScrollingAnimation>
<WhileScrolling>
<Change IsScrolling.Value="true" />
</WhileScrolling>
<StackPanel Orientation="Horizontal">
<Each Count="30">
<StackPanel Orientation="Horizontal" Height="100">
<Panel Background="#aaa" Width="2" Height="80" Alignment="Bottom" Margin="5,0,5,0" />
<StackPanel Orientation="Horizontal">
<Each Count="4">
<Panel Background="#ddd" Width="2" Height="50" Alignment="Bottom" Margin="5,0,5,10" />
</Each>
</StackPanel>
</StackPanel>
</Each>
</StackPanel>
</ScrollView>
<Panel>
<Rectangle Width="5%" Height="8" Margin="0,2,0,2" CornerRadius="10" Alignment="TopLeft" ux:Name="_scrollIndicator">
<SolidColor Color="#44444488" />
</Rectangle>
</Panel>
</StackPanel>
</ClientPanel>
</App>
.unoproj:
{
"Packages": [
"Fuse",
"FuseJS",
"Fuse.Scripting"
],
"Includes": [
"*"
]
}
and WhileScrolling.uno (taken from here: https://www.fusetools.com/community/forums/permalink/e2c6d45a-d8b7-4e74-beed-7dc4e5ab4e46):
using Uno;
using Fuse;
using Fuse.Triggers;
using Fuse.Controls;
public class WhileScrolling : WhileTrigger
{
ScrollView _scrollView;
protected override void OnRooted()
{
//base.OnRooted(Parent);
if (Parent is ScrollView)
{
_scrollView = (ScrollView)Parent;
_scrollView.ScrollPositionChanged += OnScrollPositionChanged;
}
}
protected override void OnUnrooted()
{
//base.OnUnrooted(Parent);
if (_scrollView != null)
{
_scrollView.ScrollPositionChanged -= OnScrollPositionChanged;
_scrollView = null;
}
}
bool _isActive = false;
int _prevFrameIndex = 0;
void OnScrollPositionChanged(object sender, EventArgs args)
{
if (!_isActive)
{
_isActive = true;
SetActive(true);
UpdateManager.AddAction(OnUpdate);
}
_prevFrameIndex = UpdateManager.FrameIndex;
}
void OnUpdate()
{
if (_prevFrameIndex < UpdateManager.FrameIndex)
{
SetActive(false);
_isActive = false;
UpdateManager.RemoveAction(OnUpdate);
}
}
}