React中固定SVG与静态SVG重叠变色的SVG mask实现问题
需求与问题
页面顶部有一个fixed定位的矢量Logo,页面下方有一个大型矢量元素,二者颜色相同。当Logo滚动经过第二个元素时,希望重叠区域的颜色发生变化。
尝试用SVG mask实现:制作目标颜色的Logo副本,以第二个元素作为遮罩。遇到两个问题:
- 将副本放在第二个
<svg>标签内,位置显示正确,但无法让Logo副本保持与原Logo相同的fixed定位 - 使用单独的
<svg>元素,Logo副本可以fixed定位,但第二个元素的遮罩无法处于正确位置
预期效果
- 滚动位置为0时:Logo正常显示,未与下方元素重叠
- 重叠区域:Logo与下方元素的重叠部分颜色改变
- 元素交错时:Logo部分位于下方元素上方,部分在外部,仅重叠区域变色
使用React开发,接受需要JS的解决方案。
版本一:两个SVG,固定元素仅在红色区域位于顶部时可见,但为静态定位
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <svg width="100%" viewBox="0 0 1920 1080" style="position: fixed; top:0;left:0; z-index:-1" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_35_234)"> <path style="position: fixed; top:0" d="M960 43L975.94 92.0598H1027.53L985.792 122.38L1001.73 171.44L960 141.12L918.267 171.44L934.208 122.38L892.475 92.0598H944.06L960 43Z" fill="orange"/> </g> </svg> <div style="height: 50vh;; z-index: -2;"> filler</div> <svg width="100%" viewBox="0 0 1920 1080" style="z-index: 5;" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M411 105L855 132.5L1158.5 86L1508 105V238H411V105Z" fill="#FF0000"/> <mask id="mask0_35_233" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="411" y="86" width="1097" height="152"> <path d="M411 105L855 132.5L1158.5 86L1508 105V238H411V105Z" fill="#FF0000"/> </mask> <g mask="url(#mask0_35_233)"> <path d="M960 43L975.94 92.0598H1027.53L985.792 122.38L1001.73 171.44L960 141.12L918.267 171.44L934.208 122.38L892.475 92.0598H944.06L960 43Z" fill="black"/> </g> </svg> <div style="height: 50vh; "> </div> </body> </html>
版本二:Logo为fixed定位,但遮罩也为fixed定位
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <svg width="100%" viewBox="0 0 1920 1080" style="position: fixed; top:0;left:0; z-index:-1" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_35_234)"> <path style="position: fixed; top:0" d="M960 43L975.94 92.0598H1027.53L985.792 122.38L1001.73 171.44L960 141.12L918.267 171.44L934.208 122.38L892.475 92.0598H944.06L960 43Z" fill="orange"/> </g> </svg> <div style="height: 50vh;; z-index: -2;"> filler</div> <svg width="100%" viewBox="0 0 1920 1080" style="position: fixed; top:0;left:0; z-index:-1"style="z-index: 5;" fill="none" xmlns="http://www.w3.org/2000/svg"> <g mask="url(#mask0_35_233)"> <path d="M960 43L975.94 92.0598H1027.53L985.792 122.38L1001.73 171.44L960 141.12L918.267 171.44L934.208 122.38L892.475 92.0598H944.06L960 43Z" fill="black"/> </g> </svg> <svg width="100%" viewBox="0 0 1920 1080" style="z-index: 5;" fill="none" xmlns="http://www.w3.org/2000/svg"> <path d="M411 105L855 132.5L1158.5 86L1508 105V238H411V105Z" fill="#FF0000"/> <mask id="mask0_35_233" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="411" y="86" width="1097" height="152"> <path d="M411 105L855 132.5L1158.5 86L1508 105V238H411V105Z" fill="#FF0000"/> </mask> </svg> <div style="height: 50vh; "> </div> </body> </html>
其他尝试:固定元素放入带mask的相对容器,但mask尺寸无法填满100%宽度
尝试将fixed元素放入带有mask属性和overflow:hidden的相对容器,将容器和内部固定元素的背景色设为目标颜色,但无法调整mask尺寸以填满100%宽度的容器,请问该如何调整mask的尺寸?
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <svg width="100%" viewBox="0 0 1920 1080" style="position: fixed; top:0;left:0; z-index:-1" fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_35_234)"> <path style="position: fixed; top:0" d="M960 43L975.94 92.0598H1027.53L985.792 122.38L1001.73 171.44L960 141.12L918.267 171.44L934.208 122.38L892.475 92.0598H944.06L960 43Z" fill="orange"/> </g> </svg> <div style="height: 100vh;; z-index: -2;"> filler</div> <div> <div style="overflow: hidden; background-color: rgba(0, 0, 255, 0.151); width: 100%; position: relative;"> <svg width="0" viewBox="0 0 1097 152" style="z-index: 5; width: 0%; aspect-ratio: 1097/152;" fill="none" xmlns="http://www.w3.org/2000/svg" > <path d="M0 19L444 46.5L747.5 0L1097 19V152H0V19Z" fill="#000000"/> <mask id="mask0_35_233" style="mask-type:alpha; width: 100%; aspect-ratio: 1097/152;" width="100%" > <path d="M0 19L444 46.5L747.5 0L1097 19V152H0V19Z" fill="#000000"/> </mask> </svg> <div style="mask:url(#mask0_35_233); background-color: red; width: 100%; aspect-ratio: 1097/152;"> <svg width="100%" viewBox="0 0 1920 1080" style="position: fixed; top:0;left:0; z-index:-1; " fill="none" xmlns="http://www.w3.org/2000/svg"> <g clip-path="url(#clip0_35_234)"> <path style="position: fixed; top:0" d="M960 43L975.94 92.0598H1027.53L985.792 122.38L1001.73 171.44L960 141.12L918.267 171.44L934.208 122.38L892.475 92.0598H944.06L960 43Z" fill="black"/> </g> </svg> </div> </div> </div> <div style="height: 100vh; "> </div> </body> </html>
内容的提问来源于stack exchange,提问作者Crimson in Capitals
相关产品推荐
相关产品推荐

