5
<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 を生成すると、マスクは効果がなく、巨大な赤い四角形が表示されます。

<defs></defs>迷惑なことに、開発者ツールを開いてsvgに無意味なものを追加すると、生成時に表示することができます。それはどういうわけかsvgを蹴り、マスクする必要があることを思い出させるようです。

ここで何が起こっているか知っている人はいますか?empty を注入するようにタイマーを設定する必要のない回避策はあります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、問題はなくなりました。質問は:

  1. なぜこれが修正されたのですか?
  2. これを重要なものにしている、ここの裏で何が起こっているのでしょうか?
  3. 私が経験した問題がコンパイル時のエラーになるように、これをタイプセーフにすることはできますか?
4

2 に答える 2

3

この2行の原因:

import Html exposing (..)
import Svg

最初のものは、名前空間をインポートするだけの 2 番目をHtml含むすべての属性をインポートします。したがって、この環境で使用している場合は. このインポートではコンパイル エラーが発生します。nodeSvgnodenodeHtml.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

そのため、コンパイラはそれらを区別できません。

于 2016-02-17T14:11:59.827 に答える
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

これが発生した場合、コンパイラは警告を表示する必要があります。

于 2016-02-18T06:50:02.200 に答える