Svg 遮罩在生成时不呈现


<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 时,蒙版没有任何效果,我们只有一个巨大的红色矩形。

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

有人知道这是怎么回事吗?有没有一种解决方法不涉及设置计时器来注入空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)

更新

在评论的帮助下想通了。这是nodeSvg.node。当我将其更改为Svg.node时,问题消失了。问题是:

  1. 为什么会修复它?
  2. 这里到底发生了什么,使这变得很重要?
  3. 是否可以将其设置为类型安全,以便我遇到的问题可能是编译时错误?

这 2 行的原因:

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.AttributeHtml.Attribute不是实际类型,而是VirtualDom.Property的类型别名。因此,对于编译器,两者是相同的类型。对于Htm.HtmlSvg.Svg相同,它们都是VirtualDom.Node的别名。

最后,node两个函数都有签名

String -> List VirtualDom.Property -> List VirtualDom.Node -> VirtualDom.Node

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

仅供参考,以下是两个node函数的代码:

--Html.node
node : String -> List Attribute -> List Html -> Html
node =
    VirtualDom.node

--Svg.node
node : String -> List Attribute -> List Svg -> Svg
node name =
  attributes children ->
    VirtualDom.node name (svgNamespace :: attributes) children

也许编译器应该在发生这种情况时警告您。

相关内容

  • 没有找到相关文章

最新更新