drawing - How do I cut transparent bits out of an otherwise opaque canvas in WPF? -


i have drawing in wpf, set canvas, background colour , draw lots of things on that. want make cuttouts, i.e. have transparent regions in arbitrary shapes. approach use visualbrush opacity mask.

here simplified version of work in progress

<canvas background="lightgray" width="{binding sizex}" height="{binding sizey}">      <canvas.opacitymask>      <visualbrush          viewport / tiling voodo here      >          <visualbrush.visual>              <canvas background="#ffffffff" width="{binding sizex}" height="{binding sizey}">                       draw cuttouts here.                        if got viewport/tiling voodoo right should                       use same coordinate system visible things.              </canvas>          </visualbrush.visual>      </visualbrush>      </canvas.opacitymask>      draw visible things here </canvas> 

but running afoul of retained-mode drawing. idea fill background alpha channel #ff things opaque default, , have transparent cuttouts. of course evaluates transparent shapes on top of opaque background, , no cuttouts.

so how cuttouts?

here go

i placed inner canvas host content , used same canvas visual visual brush used opacity mask outer canvas. enable cut outer canvas based on content in inner canvas

<canvas x:name="outer" background="green" width="100" height="100">     <canvas x:name="inner" width="{binding actualwidth,elementname=outer}" height="{binding actualheight,elementname=outer}">         <!--your arbitery content here-->         <ellipse width="20" height="10" fill="gray" canvas.left="10" canvas.top="10"/>     </canvas>     <canvas.opacitymask>         <visualbrush visual="{binding elementname=inner}"                       viewportunits="absolute" viewboxunits="absolute"                      viewbox="0,0,100,100" viewport="0,0,100,100"/>         <!--you may need write conveter class conversion sizex & sizey viewbox & viewport-->     </canvas.opacitymask> </canvas> 

all hard-coded in example viewbox & viewport numbers (also hard-coded width , height of outer canvas match numbers), may write converter same bind sizex & sizey properties in visual brush need accurate in order map correctly

note not apply background inner canvas

update

as discussed if want cutout background of canvas instead of showing shapes here sample, added trigger disable opacity mask if there no shapes cut out

<canvas background="green">     <canvas.style>         <style targettype="canvas">             <style.resources>                 <canvas x:key="maskvisual">                     <!--your arbitery content here-->                     <ellipse width="20" height="10" fill="gray"                               canvas.left="10" canvas.top="10"/>                 </canvas>             </style.resources>             <setter property="opacitymask">                 <setter.value>                     <visualbrush visual="{staticresource maskvisual}"                                  viewportunits="absolute" viewboxunits="absolute"                                  viewbox="0,0,100,100" viewport="0,0,100,100"/>                     <!--you may need write conveter class conversion sizex & sizey viewbox & viewport-->                 </setter.value>             </setter>             <style.triggers>                 <datatrigger binding="{binding children.count, source={staticresource maskvisual}}" value="0">                     <setter property="opacitymask" value="{x:null}"/>                 </datatrigger>             </style.triggers>         </style>     </canvas.style> </canvas> 

1 point notice that, since canvas not clip default may not require set width , height explicitly


Comments

Popular posts from this blog

javascript - RequestAnimationFrame not working when exiting fullscreen switching space on Safari -

Python ctypes access violation with const pointer arguments -