Faster list reordering

I was using this example (https://www.fusetools.com/examples/list-reordering) and it works well thanks Fuse team!

I had the pretty niche requirement of manually reordering a long list - up to 100 items but the smoothness of the animations started to lag so as an exercise in my early fuse learning I tried to speed the javascript up.

Since I’ve done it, thought I’d share it! The full code for a minimal implementation is below. Unlike the original it does not copy the observable list to a tmp array to do the reordering. It also does not use a “selected” property in the item. Hope someone finds it useful.

-Paul

(As I’m a fuse newbie, feel free to pick it to pieces, I won’t be offended)

<App>
    <JavaScript>
        const Observable = require("FuseJS/Observable");
        var items = Observable();
        var itemsArray = [];
        var selectedItem = null;
        var selectedId = Observable();
        var reordering = Observable(false);
        var distance = Observable();

        for (let i=0; i<100; i++) {
            itemsArray.push({id: i, item: "Item " + (i+1)});
        }
        items.replaceAll(itemsArray);

        function select(args) {
            selectedItem = args.data;
            selectedId.value = selectedItem.id;
            reordering.value = true;
        }

        function deselect() {
            selectedId.value=null;
            selectedItem = null;
            reordering.value = false;
        }

        function hover(args) {
            if (reordering.value === true && selectedItem !== null) {
                var to = items.indexOf(args.data);
                var from = items.indexOf(selectedItem);
                if (to !== from && to !== undefined) {
                    distance.value = from-to;
                    var tmp = selectedItem;
                    items.removeAt(from);
                    items.insertAt(to, tmp);
                }
            }
        }

        module.exports = {
            items:items,
            reordering: reordering,
            select: select,
            deselect: deselect,
            hover: hover,
            selectedId:selectedId,
            distance:distance
        }
    </JavaScript>
    <ScrollView ux:Name="scrollView">
        <WhileTrue Value="{reordering}">
            <Change scrollView.UserScroll="false" />
        </WhileTrue>
        <Released>
            <Callback Handler="{deselect}" />
        </Released>
        <StackPanel>
            <Each Items="{items}" IdentityKey="id">
                <Panel Margin="0,8" ux:Name="thisItem">
                    <Panel>
                        <Pressed>
                            <Callback Handler="{select}" />
                        </Pressed>
                        <Text Value="{item}" Margin="10"/>
                    </Panel>
                    <LayoutAnimation>
                        <!-- Animates the remove -->
                        <Move RelativeTo="PositionChange" Vector="1" Duration="0.24" />
                    </LayoutAnimation>
                    <AddingAnimation>
                        <Move RelativeTo="Size" Y="{distance}" Duration="0.24" />
                    </AddingAnimation>
                    <WhileHovering>
                        <Callback Handler="{hover}" />
                    </WhileHovering>
                    <WhileTrue Value="{selectedId == id}">
                        <BringToFront Target="thisItem"/>
                        <Change underlay.Opacity="1" Duration="0.24" />
                    </WhileTrue>
                    <Rectangle StrokeWidth="1" ux:Name="underlay" Color="Yellow" Opacity="0" Layer="Background" >
                        <Shadow Distance="4" Size="4" />
                    </Rectangle>
                </Panel>
            </Each>
        </StackPanel>
    </ScrollView>
</App>