Vaadin Animations, Fade out and hide with Valo theme
Asked Answered
R

2

9

I'm trying to fade away something from the screen, using:

comp.addStyleName("fade-out");
.fade-out {
    @include valo-animate-out-fade(2500ms, 1000ms);
}

But as soon as the animation ends, it's back on screen as before. Is there any way to get a callback when the animation is done, so I call remove it. Or maybe there is a way to do it in pure SCSS?

I also see that once the animation ran a can't run it again (by removing and adding back style). Is this expected behavior?

EDIT: The second issue was because I remove and add the styles in a listener one after the other. The client will not notice that anything changed, so will not animate. This is corrected by using server pushing, so the removal and new apply is in separate communications.

EDIT 2: Using push I can remove it by spawning a thread, sleeping for the time of the animation and removing. It works, but sounds really ugly. Any better way?

Red answered 25/12, 2017 at 23:14 Comment(7)
Can you paste the code how you actually use this style? By addStyleName() or so?Kaminsky
Yes, addStyleName("fade-out").Red
Does it have to be exactly "Valo animation" set with style? I've struggled with quite similar problem earlier and ended up with a different solution.Kaminsky
@Kaminsky Was it the Animator add-on? I know it works, but once I called an animation, the component couldn't animate anymore with something else. (or maybe I didn't use it correctly? Might be.) In any case, this is built into the theme and should work like expected, no?Red
Maybe it should but I could not get it working either with addStyleName() without reset & lock. But I have something else that I have working already. Not sure if I can add a callback to it. If iI remeber correct it involved jQuery also...Kaminsky
What abhout Animator add-on?Moquette
@Moquette 2 comments above.Red
H
4

But as soon as the animation ends, it's back on screen as before

.fade-out {
    @include animation(valo-animate-out-fade 2500ms 500ms forwards);
}

forwards specifies that the target will retain the computed values set by the last keyframe encountered during execution [1]. Note also that I'm not including valo-animate-out-fade directly, because the latter is defined as:

@mixin valo-animate-out-fade ($duration: 180ms, $delay: null){
  @include animation(valo-animate-out-fade $duration $delay backwards);
}

I also see that once the animation ran a can't run it again (by removing and adding back style). Is this expected behavior?

Yes. Remember that Vaadin only communicate changes to the client-side. Since you are removing and adding the style in the same listener call, there are no changes to communicate (i.e. the browser won't be told that the style was removed and added again, then it won't reset the animation).

Is there any way to get a callback when the animation is done, so I call remove it. Or maybe there is a way to do it in pure SCSS?

You cannot remove the component from the DOM by using CSS only (although it will remain hidden if you specify that the animation fills forwards). There is also an approach in [2] by using a Javascript extension, which is similar to the answey by @pirho.

Hibiscus answered 3/1, 2018 at 19:57 Comment(0)
K
5

My answer will not deal much about animations in Valo theme but presents a more generic way to deal with JavaScript stuff in Vaadin and includes an option to callback functions in the server side. It requires jQuery but possibly this can be done without it also.

See below example class having callback function on the server side

@SuppressWarnings("serial")
public class AfterFadeCallback implements com.vaadin.ui.JavaScriptFunction {
   @Override
   public void call(JsonArray arguments) {
      Notification.show("Faded!");                  
   }
}

Below is a simple example how to add jQuery library to Vaadin UI and howto call above callback function from client side JavaScript after animation is completed

// jsquery.js is copied to resource directory
// "VAADIN/scripts" (Maven Eclipse project src/main/webapp/VAADIN/scripts )
@com.vaadin.annotations.JavaScript({"vaadin://scripts/jquery.js"})
public class TestUI extends UI {

   @Override
   protected void init(VaadinRequest vaadinRequest) {
      com.vaadin.ui.JavaScript cjs = com.vaadin.ui.JavaScript.getCurrent();
      Button fadeButton = new Button("FADE");
      // need an id for js to find
      fadeButton.setId("fadeButton");
      // add Vaadin JavaScriptFunction to document 
      cjs.addFunction("org.example.javascript.AfterFadeCallback"
                           ,new AfterFadeCallback());
      fadeButton.addClickListener( click -> {
         // complete defines the callback function after animation
         // which is the one we added above
         // of course it can be any js stuff
         cjs.execute("$('#fadeButton').animate({opacity: '0.1'},"
                    +" {duration: 1500, complete: function() { "
                         +" org.example.javascript.AfterFadeCallback() } } );");
      });      
      setContent(fadeButton);
   }

...

}
Kaminsky answered 28/12, 2017 at 21:53 Comment(2)
Works like a charm! The notification in the callback will not show unless push is used.Red
@MouseEvent Nice to know. I think I had no @Push added but guess it will not harm if used (need to check & update answer for that part)Kaminsky
H
4

But as soon as the animation ends, it's back on screen as before

.fade-out {
    @include animation(valo-animate-out-fade 2500ms 500ms forwards);
}

forwards specifies that the target will retain the computed values set by the last keyframe encountered during execution [1]. Note also that I'm not including valo-animate-out-fade directly, because the latter is defined as:

@mixin valo-animate-out-fade ($duration: 180ms, $delay: null){
  @include animation(valo-animate-out-fade $duration $delay backwards);
}

I also see that once the animation ran a can't run it again (by removing and adding back style). Is this expected behavior?

Yes. Remember that Vaadin only communicate changes to the client-side. Since you are removing and adding the style in the same listener call, there are no changes to communicate (i.e. the browser won't be told that the style was removed and added again, then it won't reset the animation).

Is there any way to get a callback when the animation is done, so I call remove it. Or maybe there is a way to do it in pure SCSS?

You cannot remove the component from the DOM by using CSS only (although it will remain hidden if you specify that the animation fills forwards). There is also an approach in [2] by using a Javascript extension, which is similar to the answey by @pirho.

Hibiscus answered 3/1, 2018 at 19:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.