如何让SVG <mask>忽略/抵消引用元素的transform变换?
SVG遮罩忽略元素transform变换的解决方案
原代码示例
CSS
svg { width: 600px; height: 600px; } image { transform-box: fill-box; }
HTML
<svg> <defs> <mask id="myMask"> <rect x="0" y="0" width="100" height="100" fill="white"/> </mask> </defs> <image mask="url(#myMask)" href="https://picsum.photos/200/300" width="200" height="300" transform="rotate(-45)" transform-origin="center center"/> </svg>
问题描述
是否存在简便方法,使SVG的<mask>能够忽略或抵消其引用元素的transform变换?在实际使用场景中,该transform会由用户进行实时修改。
可行方案
方案1:用分组<g>承载变换(推荐)
把需要添加transform的元素放到<g>标签里,将transform属性加在<g>上,而mask直接应用在目标元素(比如<image>)上。这样遮罩只会作用于元素自身的坐标系,不会继承<g>的变换效果,用户后续修改<g>的transform时,遮罩完全不受影响:
<svg> <defs> <mask id="myMask"> <rect x="0" y="0" width="100" height="100" fill="white"/> </mask> </defs> <g transform="rotate(-45)" transform-origin="center center"> <image mask="url(#myMask)" href="https://picsum.photos/200/300" width="200" height="300"/> </g> </svg>
方案2:给遮罩添加反向变换
如果无法调整DOM结构,可以给<mask>内部的图形添加与目标元素完全相反的transform,以此抵消元素变换带来的影响。比如目标元素用了rotate(-45),遮罩里的图形就用rotate(45),同时保持变换原点一致:
<svg> <defs> <mask id="myMask"> <rect x="0" y="0" width="100" height="100" fill="white" transform="rotate(45)" transform-origin="center center"/> </mask> </defs> <image mask="url(#myMask)" href="https://picsum.photos/200/300" width="200" height="300" transform="rotate(-45)" transform-origin="center center"/> </svg>
这种方案需要实时同步变换参数——用户修改目标元素的transform时,你得同步更新遮罩内图形的反向transform,适合DOM结构固定的场景。
内容的提问来源于stack exchange,提问作者Malo Guertin
相关产品推荐
相关产品推荐

