Detect hover events on elements to use in callbacks

I’d like for a Lottie Animation Loop to switch to True when a dbc.Button (containing the Lottie) is hovered over and switch back to False when the cursor is off the lottie/button. I have set hoverData to button id and lottie id but it is not animating. What is a good way to capture the hover-off action? This probably makes it two questions in one, sorry…

Lottie

    settings_lottie_url = 'https://assets9.lottiefiles.com/packages/lf20_zp7xw196.json'
    options = dict(loop=False, autoplay=True, rendererSettings=dict(preserveAspectRatio='xMidYMid slice'))
    settings_lottie = de.Lottie(options=options, width="2rem", height="2rem", url=settings_lottie_url, id='update_lottie_activity')

Button Setup

    user_timeline_options_btn = dbc.Button(settings_lottie,
                   id="open-activity_options",
                   n_clicks=0,color='primary',
                   className="ml-auto btn btn-outline-light",
                   style={
                       'margin-left':'50px',
                       'border-radius': '5px',
                       'border': 'none',
                       'padding': '2px'}
                   )

Callback

@app.callback(
    Output('update_lottie_activity', 'options'),
    Input('open-activity_options', 'hoverData')
)

def hover_user_activity_lottie(hoverData):
    print(hoverData)
    if hoverData:
        return dict(loop=True, autoplay=True, rendererSettings=dict(preserveAspectRatio='xMidYMid slice'))
    else:
        return dict(loop=False, autoplay=True, rendererSettings=dict(preserveAspectRatio='xMidYMid slice'))

There isn’t an out-of-the-box way to do this but here’s a workaround:

  • use a Popover from dash_bootstrap_components on the button with trigger “hover”
  • give the popover a class to make it invisible even when it’s open
  • synchronise your Lottie animation true/false option with the is_open attribute of the popover

Here’s a small example, not with Lottie but the idea is the same, it detects the hover on the button and triggers a callback.

from dash import Dash, html, Input, Output
import dash_bootstrap_components as dbc


app = Dash(__name__, external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div(
    [
        dbc.Button("Hover here", id="button"),
        dbc.Popover(target="button", trigger="hover", id="popover", className="d-none"),
        html.Div(id="output"),
    ]
)

@app.callback(
    Output("output", "children"),
    Input("popover", "is_open")
)
def set_output(is_open):
    return "Hovering" if is_open else "Not hovering"


if __name__ == "__main__":
    app.run_server(debug=True)

To improve upon this I would make this a clientside callback too.

dash_hover_trigger_callback

5 Likes

Thank you so much!