次の図は 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" />""" )