<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)
在评论的帮助下计算出来。它是node
vs Svg.node
。当我将其更改为Svg.node
时,问题就消失了。问题是:
答案 0 :(得分:3)
这两行的原因是:
import Html exposing (..)
import Svg
第一个导入Html
的所有属性,包括node
,第二个只导入Svg
命名空间。因此,当您在node
中使用node
时,Html.node
是import Html exposing (..)
import Svg exposing (..)
。使用此导入会出现编译错误:
import Html exposing (node)
import Svg exposing (node)
或者这个:
node
因此,榆树不知道您要使用哪个(..)
。
因此,导入所需的功能而不使用Html.node
所以主要问题是为什么List Svg.Attribute
接受VirtualDom.Property
而不会抛出错误。其原因Svg.Attribute
和Html.Attribute
不是真实类型,而是Htm.Html
的类型别名。所以对于编译器来说两者都是相同的类型。 Svg.Svg
和VirtualDom.Node
相同,它们都是node
的别名。
最后,String -> List VirtualDom.Property -> List VirtualDom.Node -> VirtualDom.Node
个函数都有签名
<div>
所以编译器无法区分它们。
答案 1 :(得分:1)
仅供参考,以下是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
当发生这种情况时,编译器可能会发出警告。