Famous / famous-angular

Bring structure to your Famo.us apps with the power of AngularJS. Famo.us/Angular integrates seamlessly with existing Angular and Famo.us apps.
https://famo.us/angular
Mozilla Public License 2.0
1.92k stars 275 forks source link

No Simple solution to setSize of a ScrollView Surface to pixel size of content within. #271

Closed CharlesVoita closed 9 years ago

CharlesVoita commented 9 years ago

Could not find a simple way to setSize of ScrollView fa-surface to pixel size of content within. The solution I came up with is dirty/hacky but may help others in the future. Not only that, but I am using $timeline and transitionables to animate each fa-surface. I tried to minimize the amount of unneeded code as much as possible this example.

<fa-scroll-view fa-pipe-from="scrollHandler" fa-options="scrollViewOptions">
    <fa-modifier ng-repeat="content in contents"
        fa-animate-enter="linkEnter(content.t, $index, $done)"
        fa-animate-leave="linkLeave(content.t, $index, $done)">
        <fa-modifier fa-size="[500, getIndexHeight($index)]">
            <fa-surface fa-pipe-to="scrollHandler">
                <div id="content-{{$index}}">
                   {{content.text}}
                </div>
            </fa-surface>
        </fa-modifier>
    </fa-modifier>
</fa-scroll-view>

Note getIndexHeight($index), which will be getting the dynamic height. In my controller I have the following (note the object can just as easily be an array).

var elHeight = {};
$scope.getIndexHeight = function($index){
    return elHeight[$index];

}
$scope.setIndexHeight = function($index){
    var el = angular.element( document.querySelector( '#content-'+$index ) );
    var h = el[0].clientHeight;
    elHeight[$index] = h;
    return false;

}

Then for my fa-animate-enter, I have the following:

$scope.linkEnter = function(t, $index, $done){
    t.set(1, {duration: 333, curve: 'easeOut'}, function(){
        $done;

    })
    setTimeout(function(){
        $scope.setIndexHeight($index);
    }, 1)

} // linkEnter

Note that I am using a function to animate a transitionable. The reason I have the $scope.setIndexHeight($index); not within the callback function is because it will not be called until the animation is over. This will cause an unintended delay (in my actual code I am using a t.delay()). Without setTimeout, setIndexHeight will not find the element. The animation will not start until the height is set, so it is good that height will initially return undefined.

ForestMars commented 9 years ago

+1

Found this very useful, but would like to hear from famo.us team if there's a better way to do this.

steveblue commented 9 years ago

I made a temp solution to this until F/A supports true sizing of elements inside a ScrollView. http://stackoverflow.com/questions/26445552/scroll-view-not-scrolling-with-surface-fa-size-undefined-true/26534407?noredirect=1#comment41718130_26534407

jordanpapaleo commented 9 years ago

Hi @CharlesVoita

Could you please create a codepen for this issue?

Thanks,

Jordan

jordanpapaleo commented 9 years ago

I am going to close this. Please reopen it if it is still an issue. Thanks - Jordan