Как поместить div в объект SVG - PullRequest
0 голосов
/ 30 марта 2020

Я хочу поместить div в объект svg в моем Shiny app, как показано ниже -

library(shiny)
shinyApp(
  ui = fluidPage(
    div(id = "height: 255px; width: 205px", 
                                tag("svg", 
                                    list('viewBox' = "0 0 500 150",
                                            'preserveAspectRatio' = "none",
                                            'style' = "height: 100%; width: 100%;  filter: drop-shadow( 12px 12px 7px #00acd6 );",
                                            tag("path", list('d' = "M0.28,-0.48 C178.61,30.09 229.40,133.70 501.41,129.77 L500.00,0.00 L0.28,-1.47 Z",
                                                                'style' = "stroke: #00acd6;  stroke-width: 1px; fill: rgba(0,172,214, .01);"
                                                            )),
                                            div(style = "height: 160px; width: 160px; background-color: rgba(0,0,0,.5);", HTML("AAA"))))

                            )
  ),
  server = function(input, output) {

  }
)

Причина, по которой 2-й div находится внутри svg, заключается в том, что 2nd div всегда должен быть помещен в svg даже при изменении размера родительского окна. Если родительское окно становится слишком маленьким, тогда svg должен скрывать переполненную часть 2-го div.

На основании предложения Роберта Лонгсона, я представил foreignObject как ниже -

library(shiny)
shinyApp(
  ui = fluidPage(
    div(id = "height: 255px; width: 205px", 
                                tag("svg", 
                                    list('viewBox' = "0 0 500 150",
                                            'preserveAspectRatio' = "none",
                                            'style' = "height: 100%; width: 100%;  filter: drop-shadow( 12px 12px 7px #00acd6 ); overflow: hidden;",
                                            tag("path", list('d' = "M0.28,-0.48 C178.61,30.09 229.40,133.70 501.41,129.77 L500.00,0.00 L0.28,-1.47 Z",
                                                                'style' = "stroke: #00acd6;  stroke-width: 1px; fill: rgba(0,172,214, .01);"
                                                            )),
                                            tag("foreignObject",
                                                list(x = "0", y = "0",
                                                      width = "100%", height = "50%",
                                                      div(style = "height: 160px; width: 200px; background-color: rgba(0,0,0,1);
                                                                    position: absolute; top: 0; right: 0;", HTML("AAA"))
                                                    ))


                                          ))

                            )
  ),
  server = function(input, output) {

  }
)

Теперь, когда я вижу тень на каждом элементе в пределах foreignObject. Можно ли как-нибудь r удалить тень от этих элементов и сохранить ее только с внешней границей?

Любой указатель, как этого добиться, будет очень полезен.

Спасибо,

1 Ответ

1 голос
/ 30 марта 2020

Я бы порекомендовал - в зависимости от конечной цели вашего приложения - использовать для этого элементы svg. Элементы <rect> и <text> помогут в этом, так как вы можете указать координаты и другие полезные атрибуты.

Добавление теней к элементам SVG работает немного иначе, чем в css. Вместо этого используйте для этого элементы svg <filter> и <feDropShadow>. Фильтры должны быть определены в элементе <defs>. Вы можете использовать функцию tag(...) для определения этих элементов, но может быть проще обернуть все это в функцию HTML().

# using html
HTML('
    <defs>
        <filter id="shadow">
            <feDropShadow dx="0.2" dy="0.6" stdDeviation="0.8"/>
        </filter>
    </defs>
')

# using tag
tag(
    "defs",
    list(
        tag(
            "filter",
            list(
                "id" = "shadow",
                tag(
                    "feDropShadow",
                    list(
                        "dx" = "0.2",
                        "dy" = "0.6",
                        "stdDeviation" = "0.8"
                    )
                )
            )
        )
    )
)

Затем добавьте тень к соответствующему элементу (ам) используя style = "filter: url(#shadow); (или используйте любой идентификатор, который вы установили).

# add to path
tag(
    "path",
    list(
        d = "...",
        style = "filter: url(#shadow);"
        ...
    )
)

Вот полный пример использования чистых элементов SVG.

library(shiny)
ui <- fluidPage(
    div(
        id = "height: 255px; width: 205px", 
        tag(
            "svg", 
            list(
                'viewBox' = "0 0 500 150",
                'preserveAspectRatio' = "none",
                'style' = "height: 100%; width: 100%;",
                tag(
                    "defs",
                    list(
                        tag(
                            "filter",
                            list(
                                "id" = "shadow",
                                tag(
                                    "feDropShadow",
                                    list(
                                        "dx" = "0.2",
                                        "dy" = "0.6",
                                        "stdDeviation" = "0.8"
                                    )
                                )
                            )
                        )
                    )
                ),
                HTML('
                    <defs>
                    <filter id="shadow">
                        <feDropShadow dx="0.2" dy="0.6" stdDeviation="0.8"/>
                    </filter>
                    </defs>
                '),
                tag(
                    "path", 
                    list(
                        'd' = "M0.28,-0.48 C178.61,30.09 229.40,133.70 501.41,129.77 L500.00,0.00 L0.28,-1.47 Z",
                        'style' = "stroke: #00acd6;  stroke-width: 1px; fill: rgba(0,172,214, .01); filter: url(#shadow)"
                    )
                ),
                tag(
                    "rect",
                    list(
                        "width" = "100px",
                        "height" = "100px",
                        "x" = "0",
                        "y" = "50",
                        "fill"  = "rgba(0, 0, 0, 0.5)"
                    )
                ),
                tag(
                    "text",
                    list(
                        "x" = "5",
                        "y" = "70",
                        "AAA"
                    )
                )
            )
        )

    )
)
server <- function(input, output) {}

shinyApp(ui, server)

Если вам нужен div, то адаптируйте filter для вашего приложения. Это должно исправить проблему с тенями.

Надеюсь, это поможет! Дайте знать, если у вас появятся вопросы. Для получения дополнительной информации обращайтесь к следующим ресурсам.

...