如何将 div 放入 svg 对象中

How to put a div within an svg object

我想在我的 Shiny app 中的 svg 对象中放置一个 div,如下所示 -

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) {

  }
)

将第二个 div 放在 svg 中的原因是第二个 div 应该始终放在 svg 中,即使在调整父 [=42] 的大小时也是如此=].如果父 window 变得太小,那么 svg 应该隐藏第二个 div.

的溢出部分

根据Robert Longson的建议我引入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 从这些元素中移除阴影 并且只保留外边界?

任何关于如何实现这一点的指示都将非常有帮助。

谢谢,

我建议——当然这取决于你的应用程序的最终目标——为此使用 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);(或使用您设置的任何 ID)将阴影添加到适当的元素。

# 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。那应该可以解决阴影问题。

希望对您有所帮助!如果您有任何问题,请告诉我。有关更多信息,请查看以下资源。