Как изменить изображение при нажатии на изображение в сюжете?

#javascript #python #plotly #plotly-dash

Вопрос:

В моем приложении мне нужно изменить изображение при нажатии на изображение. Как я могу это сделать?

Структура папок:

 - app.py
- assets/
    |-- custom-script.js
 

app.py

 app = dash.Dash(__name__)
app.layout = html.Div(
[
html.Img(
            className="myImg",
            id="speak_btn",
            src="assets/img/microphone.png",


              style={},
            ),

])
 

custom-script.js

 $(document).ready(function () {
    $(".myImg").click(function () {
        if ($(this).attr("src") === "assets/img/microphone.png")
            $(this).attr("src", "assets/img/voice_gif.gif");
        else if ($(this).attr("src") === "assets/img/voice_gif.gif")
            $(this).attr("src", "assets/img/microphone.png");
    })
});
 

Вот руководство по пониманию того, почему я поместил его в папку «Ресурсы
» https://dash.plotly.com/external-resources

Он custom-script.js протестирован и работает. Нужна помощь в адаптации его к dash. Спасибо

Ответ №1:

Вы можете использовать app.clientside_callback() для запуска JS на стороне клиента следующим образом:

 import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([

    html.Img(id='speak_btn', src='assets/img/microphone.png', className='myImg', n_clicks_timestamp=0)

])

app.clientside_callback(
    """
    function(click, src) {
        if ( src == 'assets/img/microphone.png' amp;amp; click != 0 ) {
            return 'assets/img/voice_gif.gif';
        } else {
            return 'assets/img/microphone.png';
        }
    }
    """,
    Output('speak_btn', 'src'),
    [Input('speak_btn', 'n_clicks_timestamp')],
    [State('speak_btn', 'src')]
)

if __name__ == '__main__':
    app.run_server()
 

Вы также можете выполнить эту задачу без JS, написав обратный вызов для изменения src атрибута html.Img при каждом n_clicks_timestamp обновлении, например:

 import dash
from dash.dependencies import Input, Output, State
import dash_html_components as html
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)

microphone = 'assets/img/microphone.png'
voice_gif = 'assets/img/voice_gif.gif'

app.layout = html.Div([

    html.Img(id='speak_btn', src=microphone, className='myImg', n_clicks_timestamp=0)

])

@app.callback(
    Output('speak_btn', 'src'),
    [Input('speak-btn', 'n_clicks_timestamp')],
    [State('speak_btn', 'src')])
def change_img(click, src):

    if not click: raise PreventUpdate

    return gif if src==microphone else microphone

if __name__ == '__main__':
    app.run_server()
 

Комментарии:

1. Спасибо. Это хороший способ сделать это. Однако это не единственное, для чего я использую JS. Если бы я должен был строго выполнять это, используя пользовательский JS, как бы я это сделал?

2. Я включил пример, в котором выполняется JS на стороне клиента.