生成时不渲染 Svg mask

标签 svg elm image-masking virtual-dom

<svg x="0" y="0" height="2048" width="4096" style="position: absolute; top: 0px; left: 0px; pointer-events: none;">
   <defs>
      <mask x="0" y="0" id="shadowLayerMask">
         <polygon fill="#FFF" points="1042,1578 630,2048 3902,2048 3370,1464"></polygon>
      </mask>
   </defs>
   <rect x="0" y="0" fill="red" mask="url(#shadowLayerMask)" maskContentUnits="userSpaceOnUse" height="2048" width="4096"></rect>
</svg>

简单吧?事情是这样的,如果我把这个 svg 放到一个 html 文件中,掩码就可以完美地工作。但是当我使用虚拟 dom 生成相同的 svg 时, mask 没有效果,我们只有一个巨大的红色矩形。

烦人的是,如果我打开开发人员工具并添加一个毫无意义的 <defs></defs>,我可以在生成时显示它到svg。这似乎以某种方式踢了 svg 并提醒它需要屏蔽。

有人知道这里发生了什么吗?是否有不涉及设置计时器以注入(inject)空 defs 的解决方法? ?

更新:

这是来源
render : Layer -> Html
render { key, shader, mask, size } =
  let
    key' =
      key ++ "LayerMask"

    style' =
      [ "position" => "absolute"
      , "top" => "0px"
      , "left" => "0px"
      , "pointer-events" => "none"
      ]

    hw =
      [ A.height << toString <| getY size
      , A.width << toString <| getX size
      ]

    polygon =
      Svg.polygon
        [ A.fill "#FFF"
        , toPoints mask
        ]
        []

    mask' =
      node
        "mask"
        [ A.x "0", A.y "0", id key' ]
        [ polygon ]

    image =
      Svg.rect
        (A.x "0"
          ::
            A.y "0"
          --   :: A.xlinkHref shader
          ::
            A.fill "red"
          ::
            A.mask (url key')
          ::
            A.maskContentUnits "userSpaceOnUse"
          ::
            hw
        )
        []
  in
    Svg.svg
      (A.x "0" :: A.y "0" :: style style' :: hw)
      [ Svg.defs [] [ mask' ]
      , image
      ]

这是一些相关的进口
import Html exposing (..)
import Svg
import Svg.Attributes as A
import Html.Attributes as H exposing (style, id)

更新

在评论的帮助下弄清楚了。它是 node对比 Svg.node .当我将其更改为 Svg.node问题消失了。问题是:
  • 为什么要修复它?
  • 这里的幕后发生了什么使这变得重要?
  • 可以将其设为类型安全的,以便我遇到的问题可能是编译时错误吗?
  • 最佳答案

    这两条线的原因:

    import Html exposing (..)
    import Svg
    

    第一个导入Html的所有属性包括node第二个只是导入 Svg命名空间。所以当你使用 node在这个环境中nodeHtml.node .你会得到这个导入的编译错误:
    import Html exposing (..)
    import Svg exposing (..)
    

    或这个:
    import Html exposing (node)
    import Svg exposing (node)
    

    因为那时,Elm 不知道是哪个 node你想用。
    所以导入你需要的函数而不是使用 (..) 会更安全。

    所以主要问题是为什么Html.node接受 List Svg.Attribute没有抛出错误。其原因 Svg.Attribute Html.Attribute 不是真正的类型,而是 VirtualDom.Property 的类型别名.所以对于编译器来说,两者都是相同的类型。 Htm.Html 相同和 Svg.Svg它们都是 VirtualDom.Node 的别名.

    到底node函数有签名
    String -> List VirtualDom.Property -> List VirtualDom.Node -> VirtualDom.Node
    

    所以编译器无法区分它们。

    关于生成时不渲染 Svg mask ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35423498/

    相关文章:

    css - 使用变换属性创建背景

    Elm - 映射列表并将字符串附加到每个项目的末尾

    css - HTML 5 屏蔽和裁剪一张图像

    swift - 快速裁剪图​​像

    css - 矩形上的文本会消除矩形的悬停效果

    html - 将工具提示添加到 SVG 矩形标签

    javascript - 我如何在现有的服务器呈现的网络应用程序中开始使用 Elm?

    list - elm 列表推导,检索列表的第 n 个元素

    css - 如何在 HTML5 Canvas 上使用外部 CSS 绘制 SVG