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

Animating background-color does not animate #290

Closed DrClick closed 9 years ago

DrClick commented 9 years ago

I am having trouble getting this animation to work, when I mouse over the transform animation works fine, but the color does not animate, it sets it to some random point in the transition

...
 Controller.prototype.mouseInteract = function(index, mouseOver) {

        var scale = mouseOver ? 1.2 : 1;
        var color = mouseOver ? [195, 100, 60] : [0, 0, 20.4];
        var scaleTransition = {duration: 300, curve: Easing.easeIn};
        this.pageScale[index].halt();
        this.pageScale[index].set([scale, scale], scaleTransition);
        this.pageColor[index].halt();
        this.pageColor[index].set(color, {duration: 100});
    };

    Controller.prototype.getBackgroundColor = function(index) {
        var color = this.pageColor[index].get();
        var returnVal = 'hsl(@1, @2%, @3%)'.replace('@1', color[0]).replace('@2', color[1]).replace('@3', color[2]);
        return returnVal;
    };
...

and the template

<fa-modifer fa-size="[500,500]" fa-origin="[.5,.5]" fa-align="[.5,.5]" fa-translate="[0,0]">
        <fa-grid-layout fa-options="gridOptions">
            <fa-modifier ng-repeat="(index, page) in pages"
                         fa-origin="[.5,.5]"
                         fa-align="[.5,.5]"
                         fa-scale="pageScale[index].get()"
                         fa-size="[80, 80]" fa-translate="gridTransitions[index].get()">

                <fa-surface class="subpopPane"
                            fa-background-color="getBackgroundColor(index)"
                            ng-click="showSubPop(index)"
                            ng-mouseover="mouseInteract(index, true)"
                            ng-mouseleave="mouseInteract(index, false)">
                    <label class="tile">{{page}}</label>
                </fa-surface>

            </fa-modifier>
        </fa-grid-layout>
    </fa-modifer>

Any thoughts would be appreciated!

SuPenguin commented 9 years ago

Hello, I don't think you should animate color because it causes too much DOM repaint, it's better to play with opacity instead. But you still can do it by setting the new background color every tick of the engine as in this fiddle (in famo.us vanilla) : http://jsfiddle.net/mcr85/6fx9jo9e/. As for angular, you'll have to get the node via $famous.find().

zackbrown commented 9 years ago

I agree with @SuPenguin — animating bgcolor will not be as performant as animating opacity. Good news is for transitions between any two colors, you can achieve a "color tween" pretty easily by stacking two surfaces and transitioning the opacity of the top surface from 1 to 0.

As for why fa-background-color="getBackgroundColor(index)" isn't working for you, it looks like because you're relying on Angular's digest cycle in this case to propagate your color changes. I.e. fa-background-color won't be reevaluated and rebound to the surface until Angular's next digest. I would guess when you're seeing the 'flash,' what you're seeing is the resolution of that digest. Contrast this with fa-modifier's properties like fa-translate, which are able to bind changes immediately because expressions are $parsed and passed directly (functionally) through to Famo.us—only fa-modifier's properties work that way, and background-color simply does not support the same approach.

Then for solutions, I agree with @SuPenguin — First choice is to use opacity, as you will get optimal browser performance. Secondarily, look at the solution that @SuPenguin put up in that jsfiddle, which would be the with-the-grain way to handle this in Famo.us (i.e. relying on Famo.us's tick rather than Angular's digest.)

DrClick commented 9 years ago

thanks guys, I indeed went with opacity.

On Dec 18, 2014, at 11:57 AM, Zack Brown notifications@github.com wrote:

I agree with @SuPenguin https://github.com/SuPenguin — animating bgcolor will not be as performant as animating opacity. Good news is for transitions between any two colors, you can achieve a "color tween" pretty easily by stacking two surfaces and transitioning the opacity of the top surface from 1 to 0.

As for why fa-background-color="getBackgroundColor(index)" isn't working for you, it looks like because you're relying on Angular's digest cycle in this case to propagate your color changes. I.e. fa-background-color won't be reevaluated and rebound to the surface until Angular's next digest. I would guess when you're seeing the 'flash,' what you're seeing is the resolution of that digest. Contrast this with fa-modifier's properties like fa-translate, which are able to bind changes immediately because expressions are $parsed and passed directly (functionally) through to Famo.us—only fa-modifier's properties work that way, and background-color simply does not support the same approach.

Then for solutions, I agree with @SuPenguin https://github.com/SuPenguin — First choice is to use opacity, as you will get optimal browser performance. Secondarily, look at the solution that @SuPenguin https://github.com/SuPenguin put up in that jsfiddle, which would be the with-the-grain way to handle this in Famo.us (i.e. relying on Famo.us's tick rather than Angular's digest.)

— Reply to this email directly or view it on GitHub https://github.com/Famous/famous-angular/issues/290#issuecomment-67546813.