为什么这个 feDisplacementMap 过滤器不起作用?
Why isn't this feDisplacementMap filter working?
我正在尝试在 SVG <defs>
元素中构建图像,以用于置换贴图滤镜的 in2
属性。但是,置换贴图滤镜不会扭曲应用它的元素。
正在将置换贴图滤镜应用于网格图案,以便我可以查看置换的工作原理:
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<rect x="0" y="0" width="400" height="400" fill="url(#grid)"/>
</svg>
我打算用作置换贴图 in2
属性的图像很复杂。当我只是通过过滤器中的 <feImage>
元素引用它,并将该过滤器应用于网格图案时,我看到了我构建的图像,正如预期的那样:
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<linearGradient id="gradientRed">
<stop offset="0%" stop-color="rgba(255,0,0,0)"/>
<stop offset="100%" stop-color="rgba(255,0,0,1)"/>
</linearGradient>
<linearGradient id="gradientGreen" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="rgba(0,255,0,0)"/>
<stop offset="100%" stop-color="rgba(0,255,0,1)"/>
</linearGradient>
<rect id="rectRed" width="400" height="400" fill="url(#gradientRed)"/>
<rect id="rectGreen" width="400" height="400" fill="url(#gradientGreen)"/>
<rect id="rectBlack" width="400" height="400" fill="black"/>
<filter id="filterIdentity">
<feImage result="imageRed" href="#rectRed" x="0" y="0" width="400" height="400"/>
<feImage result="imageGreen" href="#rectGreen" x="0" y="0" width="400" height="400"/>
<feImage result="imageBlack" href="#rectBlack" x="0" y="0" width="400" height="400"/>
<feBlend mode="screen" in="imageRed" in2="imageGreen" result="imageRedGreen"/>
<feBlend mode="screen" in="imageRedGreen" in2="imageBlack"/>
</filter>
<mask id="maskCircle">
<rect width="400" height="400" fill="black"/>
<circle cx="200" cy="200" r="200" fill="white"/>
</mask>
<g id="shapeIdentity">
<rect width="400" height="400" fill="black"/>
<rect width="400" height="400" filter="url(#filterIdentity)" mask="url(#maskCircle)"/>
</g>
<filter id="filterDisplace">
<feImage result="imageDisplace" href="#shapeIdentity" x="0" y="0" width="400" height="400"/>
</filter>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<rect x="0" y="0" width="400" height="400" fill="url(#grid)" filter="url(#filterDisplace)"/>
</svg>
然而,当我使用相同的 <feImage>
元素作为 <feDisplacementMap>
元素的 in2
属性时,滤镜不会扭曲它所应用的网格图案。
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<linearGradient id="gradientRed">
<stop offset="0%" stop-color="rgba(255,0,0,0)"/>
<stop offset="100%" stop-color="rgba(255,0,0,1)"/>
</linearGradient>
<linearGradient id="gradientGreen" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="rgba(0,255,0,0)"/>
<stop offset="100%" stop-color="rgba(0,255,0,1)"/>
</linearGradient>
<rect id="rectRed" width="400" height="400" fill="url(#gradientRed)"/>
<rect id="rectGreen" width="400" height="400" fill="url(#gradientGreen)"/>
<rect id="rectBlack" width="400" height="400" fill="black"/>
<filter id="filterIdentity">
<feImage result="imageRed" href="#rectRed" x="0" y="0" width="400" height="400"/>
<feImage result="imageGreen" href="#rectGreen" x="0" y="0" width="400" height="400"/>
<feImage result="imageBlack" href="#rectBlack" x="0" y="0" width="400" height="400"/>
<feBlend mode="screen" in="imageRed" in2="imageGreen" result="imageRedGreen"/>
<feBlend mode="screen" in="imageRedGreen" in2="imageBlack"/>
</filter>
<mask id="maskCircle">
<rect width="400" height="400" fill="black"/>
<circle cx="200" cy="200" r="200" fill="white"/>
</mask>
<g id="shapeIdentity">
<rect width="400" height="400" fill="black"/>
<rect width="400" height="400" filter="url(#filterIdentity)" mask="url(#maskCircle)"/>
</g>
<filter id="filterDisplace">
<feImage result="imageDisplace" href="#shapeIdentity" x="0" y="0" width="400" height="400"/>
<feDisplacementMap in="SourceGraphic" in2="imageDisplace" scale="20" yChannelSelector="R" xChannelSelector="G"/>
</filter>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<rect x="0" y="0" width="400" height="400" fill="url(#grid)" filter="url(#filterDisplace)"/>
</svg>
这是怎么回事?
嗯,您被 Chrome 中的错误绊倒了。这是一个在 Chrome 中工作的版本,它通过将 displacementMap 图像作为单独的 SVG 片段内联在提供给 feImage 的数据 URI 中。请注意,此处的语法不正确 - 但正确的语法 {xlink:href = url(...)} 不起作用。 (注意 - 这在 Firefox 中不起作用,因为 Firefox 不接受 feImage 的片段引用。)
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<filter id="filterDisplace">
<feImage result="imageDisplace" xlink:href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400' width='400' height='400'%3E%3Cdefs%3E%3ClinearGradient id='gradientRed'%3E%3Cstop offset='0%25' stop-color='rgba(255,0,0,0)'/%3E%3Cstop offset='100%25' stop-color='rgba(255,0,0,1)'/%3E%3C/linearGradient%3E%3ClinearGradient id='gradientGreen' gradientTransform='rotate(90)'%3E%3Cstop offset='0%25' stop-color='rgba(0,255,0,0)'/%3E%3Cstop offset='100%25' stop-color='rgba(0,255,0,1)'/%3E%3C/linearGradient%3E%3Crect id='rectRed' width='400' height='400' fill='url(%23gradientRed)'/%3E%3Crect id='rectGreen' width='400' height='400' fill='url(%23gradientGreen)'/%3E%3Crect id='rectBlack' width='400' height='400' fill='black'/%3E%3Cfilter id='filterIdentity'%3E%3CfeImage result='imageRed' href='%23rectRed' x='0' y='0' width='400' height='400'/%3E%3CfeImage result='imageGreen' href='%23rectGreen' x='0' y='0' width='400' height='400'/%3E%3CfeImage result='imageBlack' href='%23rectBlack' x='0' y='0' width='400' height='400'/%3E%3CfeBlend mode='screen' in='imageRed' in2='imageGreen' result='imageRedGreen'/%3E%3CfeBlend mode='screen' in='imageRedGreen' in2='imageBlack'/%3E%3C/filter%3E%3Cmask id='maskCircle'%3E%3Crect width='400' height='400' fill='black'/%3E%3Ccircle cx='200' cy='200' r='200' fill='white'/%3E%3C/mask%3E%3C/defs%3E%3Crect width='400' height='400' fill='black'/%3E%3Crect width='400' height='400' filter='url(%23filterIdentity)' mask='url(%23maskCircle)'/%3E%3C/svg%3E" x="0" y="0" width="400" height="400"/>
<feDisplacementMap in="SourceGraphic" in2="imageDisplace" scale="20" yChannelSelector="R" xChannelSelector="G"/>
</filter>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<g filter="url(#filterDisplace)">
<rect x="0" y="0" width="400" height="400" fill="url(#grid)" />
</g>
</svg>
我正在尝试在 SVG <defs>
元素中构建图像,以用于置换贴图滤镜的 in2
属性。但是,置换贴图滤镜不会扭曲应用它的元素。
正在将置换贴图滤镜应用于网格图案,以便我可以查看置换的工作原理:
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<rect x="0" y="0" width="400" height="400" fill="url(#grid)"/>
</svg>
我打算用作置换贴图 in2
属性的图像很复杂。当我只是通过过滤器中的 <feImage>
元素引用它,并将该过滤器应用于网格图案时,我看到了我构建的图像,正如预期的那样:
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<linearGradient id="gradientRed">
<stop offset="0%" stop-color="rgba(255,0,0,0)"/>
<stop offset="100%" stop-color="rgba(255,0,0,1)"/>
</linearGradient>
<linearGradient id="gradientGreen" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="rgba(0,255,0,0)"/>
<stop offset="100%" stop-color="rgba(0,255,0,1)"/>
</linearGradient>
<rect id="rectRed" width="400" height="400" fill="url(#gradientRed)"/>
<rect id="rectGreen" width="400" height="400" fill="url(#gradientGreen)"/>
<rect id="rectBlack" width="400" height="400" fill="black"/>
<filter id="filterIdentity">
<feImage result="imageRed" href="#rectRed" x="0" y="0" width="400" height="400"/>
<feImage result="imageGreen" href="#rectGreen" x="0" y="0" width="400" height="400"/>
<feImage result="imageBlack" href="#rectBlack" x="0" y="0" width="400" height="400"/>
<feBlend mode="screen" in="imageRed" in2="imageGreen" result="imageRedGreen"/>
<feBlend mode="screen" in="imageRedGreen" in2="imageBlack"/>
</filter>
<mask id="maskCircle">
<rect width="400" height="400" fill="black"/>
<circle cx="200" cy="200" r="200" fill="white"/>
</mask>
<g id="shapeIdentity">
<rect width="400" height="400" fill="black"/>
<rect width="400" height="400" filter="url(#filterIdentity)" mask="url(#maskCircle)"/>
</g>
<filter id="filterDisplace">
<feImage result="imageDisplace" href="#shapeIdentity" x="0" y="0" width="400" height="400"/>
</filter>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<rect x="0" y="0" width="400" height="400" fill="url(#grid)" filter="url(#filterDisplace)"/>
</svg>
然而,当我使用相同的 <feImage>
元素作为 <feDisplacementMap>
元素的 in2
属性时,滤镜不会扭曲它所应用的网格图案。
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<linearGradient id="gradientRed">
<stop offset="0%" stop-color="rgba(255,0,0,0)"/>
<stop offset="100%" stop-color="rgba(255,0,0,1)"/>
</linearGradient>
<linearGradient id="gradientGreen" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="rgba(0,255,0,0)"/>
<stop offset="100%" stop-color="rgba(0,255,0,1)"/>
</linearGradient>
<rect id="rectRed" width="400" height="400" fill="url(#gradientRed)"/>
<rect id="rectGreen" width="400" height="400" fill="url(#gradientGreen)"/>
<rect id="rectBlack" width="400" height="400" fill="black"/>
<filter id="filterIdentity">
<feImage result="imageRed" href="#rectRed" x="0" y="0" width="400" height="400"/>
<feImage result="imageGreen" href="#rectGreen" x="0" y="0" width="400" height="400"/>
<feImage result="imageBlack" href="#rectBlack" x="0" y="0" width="400" height="400"/>
<feBlend mode="screen" in="imageRed" in2="imageGreen" result="imageRedGreen"/>
<feBlend mode="screen" in="imageRedGreen" in2="imageBlack"/>
</filter>
<mask id="maskCircle">
<rect width="400" height="400" fill="black"/>
<circle cx="200" cy="200" r="200" fill="white"/>
</mask>
<g id="shapeIdentity">
<rect width="400" height="400" fill="black"/>
<rect width="400" height="400" filter="url(#filterIdentity)" mask="url(#maskCircle)"/>
</g>
<filter id="filterDisplace">
<feImage result="imageDisplace" href="#shapeIdentity" x="0" y="0" width="400" height="400"/>
<feDisplacementMap in="SourceGraphic" in2="imageDisplace" scale="20" yChannelSelector="R" xChannelSelector="G"/>
</filter>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<rect x="0" y="0" width="400" height="400" fill="url(#grid)" filter="url(#filterDisplace)"/>
</svg>
这是怎么回事?
嗯,您被 Chrome 中的错误绊倒了。这是一个在 Chrome 中工作的版本,它通过将 displacementMap 图像作为单独的 SVG 片段内联在提供给 feImage 的数据 URI 中。请注意,此处的语法不正确 - 但正确的语法 {xlink:href = url(...)} 不起作用。 (注意 - 这在 Firefox 中不起作用,因为 Firefox 不接受 feImage 的片段引用。)
<svg viewBox="0 0 400 400" width="400" height="400">
<defs>
<filter id="filterDisplace">
<feImage result="imageDisplace" xlink:href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 400' width='400' height='400'%3E%3Cdefs%3E%3ClinearGradient id='gradientRed'%3E%3Cstop offset='0%25' stop-color='rgba(255,0,0,0)'/%3E%3Cstop offset='100%25' stop-color='rgba(255,0,0,1)'/%3E%3C/linearGradient%3E%3ClinearGradient id='gradientGreen' gradientTransform='rotate(90)'%3E%3Cstop offset='0%25' stop-color='rgba(0,255,0,0)'/%3E%3Cstop offset='100%25' stop-color='rgba(0,255,0,1)'/%3E%3C/linearGradient%3E%3Crect id='rectRed' width='400' height='400' fill='url(%23gradientRed)'/%3E%3Crect id='rectGreen' width='400' height='400' fill='url(%23gradientGreen)'/%3E%3Crect id='rectBlack' width='400' height='400' fill='black'/%3E%3Cfilter id='filterIdentity'%3E%3CfeImage result='imageRed' href='%23rectRed' x='0' y='0' width='400' height='400'/%3E%3CfeImage result='imageGreen' href='%23rectGreen' x='0' y='0' width='400' height='400'/%3E%3CfeImage result='imageBlack' href='%23rectBlack' x='0' y='0' width='400' height='400'/%3E%3CfeBlend mode='screen' in='imageRed' in2='imageGreen' result='imageRedGreen'/%3E%3CfeBlend mode='screen' in='imageRedGreen' in2='imageBlack'/%3E%3C/filter%3E%3Cmask id='maskCircle'%3E%3Crect width='400' height='400' fill='black'/%3E%3Ccircle cx='200' cy='200' r='200' fill='white'/%3E%3C/mask%3E%3C/defs%3E%3Crect width='400' height='400' fill='black'/%3E%3Crect width='400' height='400' filter='url(%23filterIdentity)' mask='url(%23maskCircle)'/%3E%3C/svg%3E" x="0" y="0" width="400" height="400"/>
<feDisplacementMap in="SourceGraphic" in2="imageDisplace" scale="20" yChannelSelector="R" xChannelSelector="G"/>
</filter>
<pattern id="grid" viewBox="0,0,10,10" width="2.5%" height="2.5%">
<rect x="0" y="0" width="1" height="10"/>
<rect x="0" y="0" width="10" height="1"/>
</pattern>
</defs>
<g filter="url(#filterDisplace)">
<rect x="0" y="0" width="400" height="400" fill="url(#grid)" />
</g>
</svg>