反转SVG图像蒙版 [英] Inverting SVG image mask

查看:73
本文介绍了反转SVG图像蒙版的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,使用图像遮罩SVG形状比使用其他方法更方便. (可以通过任何一种方式实现所需的多色叠加效果.)问题是,当我使用正常(灰度)图像作为蒙版时,结果看起来像是负片.是否可以使用SVG属性或巧妙的JS/D3技巧告诉浏览器反转其屏蔽协议,还是我自己转换图像(可能最终不如用其他方法方便)?/p>

更新最小示例:

 <!DOCTYPE html>
<title>Image mask</title>

<script type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js">
</script>
<body>
<div>
<button>toggle</button>
</div>
</body>
<script>
var width = 194,
	height = 240;
	maskWidth = 30;
var svg = d3.select('body').append('svg')
	.attr('height', 500);

var myMask = svg.insert('mask', ':first-child')
	.attr('id', 'image_mask');

var marilyn = myMask.append('image')
	.attr('width', width)
	.attr('height', height)
	.attr('xlink:href', "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg/194px-Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg");

var positive = svg.append('rect')
	.attr('width',maskWidth)
	.attr('height', height)
	.attr('fill', 'red')
	.attr('mask', 'url(#image_mask)');

var negative = svg.append('rect')
	.attr('x', maskWidth)
	.attr('width', width - maskWidth)
	.attr('height', height)
	.attr('fill', 'green')
	.attr('mask', 'url(#image_mask)');
	
var toggle = false;
d3.select('button').on('click', function() {
	toggle = !toggle;
	positive.transition()
		.attr('height', toggle ? height/2 : height);
});

</script> 

解决方案

您将需要使用<filter>反转遮罩中的图像.

 <svg height="500" xmlns:xlink="http://www.w3.org/1999/xlink" >
  <defs>
    <filter id="invert">
      <feComponentTransfer>
        <feFuncR type="table" tableValues="1 0"/>
        <feFuncG type="table" tableValues="1 0"/>
        <feFuncB type="table" tableValues="1 0"/>
      </feComponentTransfer>
    </filter> 
    <mask id="image_mask">
      <image width="194" height="240" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg/194px-Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg"
             filter="url(#invert)"/>
    </mask>
  </defs>
  
  <rect width="30" height="120" fill="red" mask="url(#image_mask)"/>
  <rect x="30" width="164" height="240" fill="green" mask="url(#image_mask)"/>
</svg> 

In my application, it is more convenient for me to use an image to mask SVG shapes rather than the other way round. (The desired multi-color overlays effects can be achieved either way.) The problem is, when I use a normal (grayscale) image as the mask, the result looks like a negative film. Is there an SVG attribute or clever JS/D3 trick that I can use to tell the browser to invert its masking protocol or am I stuck with converting the images myself (which may end up being less convenient than doing it the other way)?

Update Minimal example:

<!DOCTYPE html>
<title>Image mask</title>

<script type="text/javascript"
  src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js">
</script>
<body>
<div>
<button>toggle</button>
</div>
</body>
<script>
var width = 194,
	height = 240;
	maskWidth = 30;
var svg = d3.select('body').append('svg')
	.attr('height', 500);

var myMask = svg.insert('mask', ':first-child')
	.attr('id', 'image_mask');

var marilyn = myMask.append('image')
	.attr('width', width)
	.attr('height', height)
	.attr('xlink:href', "https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg/194px-Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg");

var positive = svg.append('rect')
	.attr('width',maskWidth)
	.attr('height', height)
	.attr('fill', 'red')
	.attr('mask', 'url(#image_mask)');

var negative = svg.append('rect')
	.attr('x', maskWidth)
	.attr('width', width - maskWidth)
	.attr('height', height)
	.attr('fill', 'green')
	.attr('mask', 'url(#image_mask)');
	
var toggle = false;
d3.select('button').on('click', function() {
	toggle = !toggle;
	positive.transition()
		.attr('height', toggle ? height/2 : height);
});

</script>

解决方案

You'll need to use a <filter> to invert the image in your mask.

<svg height="500" xmlns:xlink="http://www.w3.org/1999/xlink" >
  <defs>
    <filter id="invert">
      <feComponentTransfer>
        <feFuncR type="table" tableValues="1 0"/>
        <feFuncG type="table" tableValues="1 0"/>
        <feFuncB type="table" tableValues="1 0"/>
      </feComponentTransfer>
    </filter> 
    <mask id="image_mask">
      <image width="194" height="240" xlink:href="https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg/194px-Marilyn_Monroe_photo_pose_Seven_Year_Itch.jpg"
             filter="url(#invert)"/>
    </mask>
  </defs>
  
  <rect width="30" height="120" fill="red" mask="url(#image_mask)"/>
  <rect x="30" width="164" height="240" fill="green" mask="url(#image_mask)"/>
</svg>

这篇关于反转SVG图像蒙版的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆