html5 svg 第九章 裁剪和屏蔽 Clipping and Masking

来源:互联网 发布:c语言文件读写格式 编辑:程序博客网 时间:2024/06/06 01:41

有时候,你不希望看到整个画面,例如,你可能想画一幅画,就好像是看到通过双筒望远镜或锁孔目镜或锁孔的边界之外的一切都将是无形的。或者,您可能要设置所显示的图像,仿佛透过半透明的窗帘观看的心情。SVG实现这样的效果,与剪切和屏蔽。

裁剪路径Clipping to a Path

当你创建一个SVG文档,建立它的视口指定您感兴趣的区域的宽度和高度。这将自动成为你的裁剪区域,将不会显示任何超出这些限制绘制。你可以建立自己的裁剪区域与<clipPath>元素。这是最简单的情况:建立一个矩形剪辑路径。将是内部<clipPath>元素<rect>我们希望夹。矩形本身不显示,我们只喜欢它,它的坐标。因此,我们是免费添加任何填充或中风的风格,我们希望的元素在<clipPath>内。在被裁剪的对象,我们添加一个剪辑路径样式属性的的参考价值<clipPath>元素。请注意该财产是复姓,而不是资本化,资本化元素,而不是复姓。在例9-1中,被修剪的对象从第1章图9-1是一个小版本的猫图片。

例9-1所示。裁剪的矩形路径


<defs><clipPath id="rectClip">    <rect id="rect1" x="15" y="15"       width="40" height="45"       style="stroke: gray; fill: none;"/></clipPath></defs><!-- clip to rectangle --><use xlink:href="minicat.svg#cat" style="clip-path: url(#rectClip);"/><!--  for reference, show entire picture with clipping area outlined --><g transform="translate(100,0)">    <use xlink:href="#rect1"/>    <!-- show clip rectangle -->    <use xlink:href="minicat.svg#cat"/></g>

正如它的名字<clipPath>意味着,你可以夹到任意路径。事实上,的<clipPath>元素可以包含任意数量的基本的形状中,<path>的元素,或<文本>的元素。实施例9-2显示了一组夹的弯曲路径和同组的形状剪裁文本的形状。

例9-2。复杂的剪辑路径

<defs><clipPath id="curveClip">    <path id="curve1"        d="M5 55 C 25 5, 45 -25, 75 55, 85 85, 20 105, 40 55 Z"        style="stroke: black; fill: none;"/></clipPath><clipPath id="textClip">    <text id="text1" x="20" y="20" transform="rotate(60)"        style="font-size: 48pt; stroke: black; fill: none;">    CLIP    </text></clipPath><g id="shapes"><rect x="0" y="50" width="90" height="60" style="fill: #999;"/><circle cx="25" cy="25" r="25" style="fill: #666;"/><polygon points="30 0 80 0 80 100" style="fill: #ccc;"/></g></defs><!-- draw with curved clip-path --><use xlink:href="#shapes" style="clip-path: url(#curveClip);" /><g transform="translate(100,0)">    <use xlink:href="#shapes"/>    <use xlink:href="#curve1"/>   <!-- show clip path --></g><!-- draw with text as clip-path --><g transform="translate(0,150)">    <use xlink:href="#shapes" style="clip-path: url(#textClip);"/></g><g transform="translate(100,150)">    <use xlink:href="#shapes"/>    <use xlink:href="#text1"/></g>

为了帮助您更好地看到区域,前面的SVG绘制整个图形剪切路径上面,你的右半图9-2中看到这一点

在用户坐标系中的坐标前面的剪辑路径已经指定。如果你想表达的对象边界框的坐标,然后设置clipPathUnits objectBoundingBox(默认是userSpaceOnUse)例9-3使用剪辑路径,这将产生一个圆形或椭圆形窗口的任何对象上,它的应用到。

例9-3。使用objectBoundingBox clipPathUnits

<defs><clipPath id="circularPath" clipPathUnits="objectBoundingBox">    <circle cx="0.5" cy="0.5" r="0.5"/></clipPath><g id="shapes"><rect x="0" y="50" width="100" height="50" style="fill: #999;"/><circle cx="25" cy="25" r="25" style="fill: #666;"/><polygon points="30 0 80 0 80 100" style="fill: #ccc;"/></g><g id="words"><text  x="0"  y="19" style="font-size: 12;"><tspan x="0"  y="19">If you have form'd a circle</tspan><tspan x="12" y="33">to go into,</tspan><tspan x="0"  y="47">Go into it yourself</tspan><tspan x="12" y="61">and see how you would do.</tspan><tspan x="50" y="80">­William Blake</tspan></text></g></defs><use xlink:href="#shapes" style="clip-path: url(#circularPath);" /><use xlink:href="#words" transform="translate(110,0)"    style="clip-path: url(#circularPath);"/>

图9-3中,几何数字碰巧有一个方形边框,所以出现圆形裁剪。该文本范围内的一个矩形区域,所以该标记的区域似乎是一个椭圆形的。

图9-3。使用一个圆形/椭圆形裁剪路径

注意

指定一个剪辑矩形为<marker> <symbol>标签的剪辑风格属性。它的值是4个空格分隔的数字,指定矩形的上,右,下,左界限。此设置剪辑矩形匹配的标记或符号的viewBox,而不是它的视口。

屏蔽 Masking

在SVG的掩码是一个化妆舞会的面具,你穿的正好相反。一个化妆舞会的面具,隐藏你的脸是不透明的部分是半透明的部分,让人们依稀看到你的脸,和孔(透明),让人们清楚地看到你的脸。的SVG掩模,另一方面,将其透明度的对象,它掩盖。这里掩码是不透明的,被屏蔽的对象的像素是不透明的。这里掩码是半透明的,所以对象,掩膜的透明部分被屏蔽的对象对应的部分的不可见。

您可以使用<mask>取值元素创建一个口罩。您可以指定遮罩的尺寸的XY宽度高度属性。这些尺寸是中的蒙面objectBoundingBox。如果你想在用户空间坐标尺寸时,设置maskUnits userSpaceOnUse

开始掩码> </掩码和结束标签之间的任何基本形状,文字,或你想用作蒙的路径。缺省情况下,用户坐标空间中,这些元件上的坐标表示。如果你想使用对象边界框的内容的面具,将设置maskContentUnitsobjectBoundingBox。(默认为userSpaceOnUse的)。

那么问题就变成:SVG是如何决定的透明度,或alpha值的面具?我们知道,所描述的每个像素的四个值组成:红,绿,蓝三色的值,其不透明度。虽然乍看之下,这似乎合乎逻辑只使用不透明度值,SVG决定使用它提供的所有信息,而不是扔掉四分之三的一个像素的信息。SVG使用这个公式:

( 0.2125 * red value +0.7154 * green value +0.0721 * blue value ) * opacity value         

其中所有的值都介于0到1的浮点数。你可能会惊讶,这个比例是不相等的,但如果你看一下在完全饱和的红,绿,蓝,绿色的亮,暗红色,蓝色最黑暗的。(你可以看到在图9-4)。颜色越深,产生的alpha值越小,就越不透明蒙板的对象将是。


例9-4创建黑白文本和一个黑色圆圈所掩盖一个完全不透明的红色,绿色,蓝色和白色方形。的文字和圆组合在一起,组使用了一种的面具样式属性引用适当的屏蔽。

例9-4。掩蔽与不透明的颜色。

<defs><mask id="redmask" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1" style="fill: #f00;"/></mask><mask id="greenmask" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1" style="fill: #0f0;"/></mask><mask id="bluemask" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1" style="fill: #00f;"/></mask><mask id="whitemask" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1" style="fill: #fff;"/></mask></defs><!-- display the colors to show relative brightness (luminance) --><rect x="10" y="10" width="50" height="50" style="fill: #f00;"/><rect x="70" y="10" width="50" height="50" style="fill: #0f0;"/><rect x="130" y="10" width="50" height="50" style="fill: #00f;"/><rect x="190" y="10" width="50" height="50"    style="fill: #fff; stroke: black;"/><g style="mask: url(#redmask);    font-size: 14pt; text-anchor: middle;"><circle cx="35" cy="115" r="25"  style="fill: black;"/><text x="35" y="80">Red</text></g><g style="mask: url(#greenmask);    font-size: 14pt; text-anchor: middle;"><circle cx="95" cy="115" r="25" style="fill: black;"/><text x="95" y="80">Green</text></g><g style="mask: url(#bluemask);    font-size: 14pt; text-anchor: middle;"><circle cx="155" cy="115" r="25" style="fill: black;"/><text x="155" y="80">Blue</text></g><g style="mask: url(#whitemask);    font-size: 14pt; text-anchor: middle;"><circle cx="215" cy="115" r="25" style="fill: black;"/><text x="215" y="80">White</text></g>

注意

搞清楚颜色,不透明度和最后的alpha值之间的互动关系是不完全直观。如果您填写和/或中风白色的面具内容,“色因子”,增加了高达1.0,不透明度,然后将控制遮罩的Alpha值的唯一因素。示例9-5是这样写的,结果是在图9-5。

示例9-5。面膜alpha通道的使用不透明

<defs><mask id="fullmask" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1"        style="fill-opacity: 1.0; fill: white;"/></mask><mask id="three-fourths" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1"        style="fill-opacity: 0.75; fill: white;"/></mask><mask id="one-half" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1"        style="fill-opacity: 0.5; fill: white;"/></mask><mask id="one-fourth" x="0" y="0" width="1" height="1"    maskContentUnits="objectBoundingBox">    <rect x="0" y="0" width="1" height="1"        style="fill-opacity: 0.25; fill: white;"/></mask></defs><g style="font-size: 14pt; text-anchor:middle; fill:black;">    <g style="mask: url(#fullmask);">    <circle cx="35" cy="35" r="25"/>    <text x="35" y="80">100%</text>    </g>    <g style="mask: url(#three-fourths);">    <circle cx="95" cy="35" r="25"/>    <text x="95" y="80">75%</text>    </g>    <g style="mask: url(#one-half);">    <circle cx="155" cy="35" r="25"/>    <text x="155" y="80">50%</text>    </g>    <g style="mask: url(#one-fourth);">    <circle cx="215" cy="35" r="25"/>    <text x="215" y="80">25%</text>    </g></g>
案例研究--屏蔽图形

例9-6添加一个JPG图像始建于8.10节的形象。正如你可以看到在图9-6(减少以节省空间和灰度避免使用彩色墨水),图像掩盖主椭圆弯道内侧,和蓝色的天空侵入可怕的淡红色部分。

例9-6。揭密形象

<defs>    <font-face font-family="bakbatn">        <font-face-src>            <font-face-uri xlink:href="kfont.svg#kfont-defn"/>        </font-face-src>         </font-face></defs><!-- draws ellipse and text --><use xlink:href="ksymbol.svg#ksymbol"/><image xlink:href="kwanghwamun.jpg" x="72" y="92"    width="160" height="120"/>

解决的办法是淡出图像的边缘,这是很容易地通过使用作为掩模的径向渐变。下面的代码被添加到的文件<defs>部分:

<radialGradient id="fade">    <stop offset="0%" style="stop-color: white; stop-opacity: 1.0;"/>    <stop offset="85%" style="stop-color: white; stop-opacity: 0.5;"/>    <stop offset="100%" style="stop-color: white; stop-opacity: 0.0;"/></radialGradient><mask id="fademask">    <rect x="72" y="92" width="160" height="120"        style="fill: url(#fade);"/></mask>
然后添加蒙版的<IMAGE>标签,图9-7

<image xlink:href="kwanghwamun.jpg" x="72" y="92"    width="160" height="120"    style="mask: url(#fademask);"/>