次の図は mask の効果を示す。例は簡単でしかも mask の効果が分かりやすいものにした。
透明度を設定できる、様々な形のフィルタで、図形をマスクできる。
この SVG ファイルを生成する Python のコードは
#encoding: utf-8 import svg c = svg.Canvas(0,0,400,300,map=(-1.4,1.3,1.4,-1.3)) d = c.define() m = d.mask(-0.8,-1.1,0.8,1.1,id="M") c.rect(-0.8,-1.1,0.8,1.1) c.text(0,-1.1,text="masking region",anchor="N",font="size:12") c.rect(-1,-1,1,1,stroke="green") c.text(-1,1,text="masked region",anchor="S",font="size:12") m.polygon(-1,-1,-1,1,1,1,stroke="black;width:4",fill="grey") m.polygon(-1,-1,1,-1,1,1,stroke="black;width:4",fill="white") d.end() g = c.group(mask="url(#M)") g.rect(-1,-1,1,1,fill="red",stroke="red") g.text(0,0,text="abc",id="T",font="size:60",anchor="C",stroke="black",fill="none") c.close()
特定の色だけをマスクできれば面白いのだが、特定の色だけをマスクできない。
(透明度だけが設定できる)
白色のストライプが入ったのは
stroke="black;width:4"
stroke="none" を指定すれば、このストライプは出ない。
なお、text で
stroke="black",fill="none"
マスクされた同じ絵をいくつも描きたいのであれば use が便利である。その場合には次のようになる。
#encoding: utf-8 import svg c = svg.Canvas(0,0,400,300,map=(-1.4,1.3,1.4,-1.3)) d = c.define() g = d.group(id="T",scale=0.5) m = g.mask(-0.8,-1.1,0.8,1.1,id="M") m.polygon(-1,-1,-1,1,1,1,stroke="black;width:4",fill="grey") m.polygon(-1,-1,1,-1,1,1,stroke="black;width:4",fill="white") h = g.group(mask="url(#M)") h.rect(-1,-1,1,1,fill="red",stroke="red") h.text(0,0,text="abc",id="T",font="size:60",anchor="C",stroke="black",fill="none") d.end() c.use(-0.5,0.5,ref="T") c.use(0.5,0.5,ref="T") c.use(-0.5,-0.5,ref="T") c.use(0.5,-0.5,ref="T") c.close()
次の図は少し複雑なフィターを使った mask の効果を示す。
この SVG ファイルを生成する Python のコードは
#encoding: utf-8
import svg
c = svg.Canvas(0,0,400,300,map=(-1.4,1.3,1.4,-1.3))
d = c.define()
d.svgout("linearGradient","""id="G" gradientUnits="userSpaceOnUse"
x1="-100" y1="-100" x2="100" y2="100" """,
"""<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="0.7" stop-color="white" stop-opacity="1" />"""
)
m = d.mask(-0.8,-1.1,0.8,1.1,id="M")
c.rect(-0.8,-1.1,0.8,1.1)
c.text(0,-1.1,text="masking region",anchor="N",font="size:12")
c.rect(-1,-1,1,1,stroke="green")
c.text(-1,1,text="masked region",anchor="S",font="size:12")
m.rect(-1,-1,1,1,stroke="black;width:2",fill="url(#G)")
g = d.group(id="T")
g.rect(-1,-1,1,1,fill="red",stroke="red")
g.text(0,0,text="abc",id="T",font="size:60",anchor="C",stroke="black",fill="none")
d.end()
c.use(ref="T",mask="url(#M)")
c.close()
マスクされた領域の中に着目すると、左上から右下に向かって透明度が高くなっている。これは linearGradient の中の
x1="-100" y1="-100" x2="100" y2="100"
svgout メソッドを使った場合には、SVG の生の座標系を使わなくてはならないと言う分かりにくさがある。問題の軽減のために、次のようにライブラリの内部で使用されている関数 svgxy を使う事ができる。この関数は、map で与えた論理座標を、SVG の座標系に変換する。
d.svgout("linearGradient","""id="G" gradientUnits="userSpaceOnUse"
x1="%s" y1="%s" x2="%s" y2="%s" """%c.svgxy(-1,1,1,-1),
"""<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="0.7" stop-color="white" stop-opacity="1" />"""
)