Re: Event handling in clipping conditions

Hi Robin, wrote on 12/05/2008 04:29:35 AM:

> On Dec 4, 2008, at 22:52 , wrote:
> > wrote on 12/04/2008 10:43:58 AM:
> > > [[
> > > 14.3.6 Clipping paths and geometry
> > > [...]
> > > Therefore, an element which has 'pointer-events' property 
> > > values which depend  upon the visibility of the element 
> > > (i.e. 'visiblePainted', 'visibleFill', 'visibleStroke', 
> > > 'visible') will not receive pointer events for the
> > > occluded parts of the element.
> >
> >    So does this apply to Mask as well, which has _exactly_ the same
> > appearance implications in many cases?  If so at what level of
> > opacity does the Mask stop transmitting events?
> It's not about the appearance implications, display none, visibility 
> hidden, and opacity 0 all have the same appearance implications but 
> different semantics, and behave differently. 

   When I read the quoted part of the errata it seems pretty clear 
that it tying the concept of pointer events that refer to the 
'visibility' of the element to the actual visibility
of the element.

> I'd expect mask to work  like opacity, but that's just my 
> personal opinion.

   Sure, but I would argue that given the wording in the spec one
could easily decide that an element with opacity="0" should not
receive events if it's pointer-events is any of the 'visible*'
values; "Will not receive pointer events for the occluded parts
of the element".

> > > We believe that this is the most consistent and predictable 
> > > behavior, and that it should be relatively simple to implement.
> >
> >    It's not very consistent with the mask element.  And implementing
> > it with mask may not be relatively simple to implement...
> In what way is the behavior not consistent with mask?

   <clipPath id="clip1">
     <rect x="0" y="0" width="640" height="480"/>
   <g clip-path="url(#clip1)"> <!-- Doesn't recieve events outside rect 

   <mask id="mask1">
     <rect x="0" y="0" width="640" height="480"/>
   <g mask="url(#mask1)"> <!-- Does recieve events outside rect -->

   These two snippets have effectively identical results on the
image, the difference being that the mask will likely have anti-aliased
edges.  Honestly I think that clipping is simply a lightweight version
of mask, so I think adding this extra baggage to clip retroactively
is really not good.  In fact the standard it's self seems to support
this view (from 14.3.1 Introduction);

     A clipping path can be thought of as a mask wherein those pixels 
outside the clipping path 
are black with an alpha value of zero and those pixels inside the clipping 
path are white with 
an alpha value of one (with the possible exception of anti-aliasing along 
the edge of the silhouette). 

   The two features are combined in one chapter in the specification.
Really this addition to the standard is the first instance where a
significant _semantic_ difference between the two elements is introduced
(clipping effects events as well as rendering).

> >    There are of course other cases that have similar issues like
> > filters where the actual geometry can be offset from the apparent
> > geometry.
> >
> >    My personal opinion is that content authors should handle these 
> > cases with 'hidden' event targets that gives them much more control 
> > over the behavior they desire.
> I don't think that's a very nice solution, it forces people to update 
> things twice whenever they script or animate. 

   Sure, I understand that the specification as written isn't perfect
but this 'patch' is really a poor hack for the real problem.  I'll
agree that it captures a good chunk of the common use cases but I
think it does it in a clumsy way that is likely to cause problems
in the future.

   Really the SVG standard should (eventually) have a defined set of 
properties that actually act on events that is orthogonal to rendering. 
Trying to tie the two together is just too likely to cause unintended
side effects.  A really nice SVG 1.2 solution would be and 'event-clip'
property that can either reference a clipPath element, or have the
value 'clip-path' (which uses what ever clip-path is referencing).

   My fear is that this quick fix will make that future 'clean' 
solution to the problem more complex and likely not backwards

> And even if it were a solution, UAs still need to have properly defined 
> interoperable behaviour for hit testing in all cases.

   I would argue the standard already has an interoperable behaviour.
The standard makes no reference to clipping with regards to hit testing,
why someone would decide that they should added such a thing when it is
totally absent from the standard makes no sense to me.  I understand that
a number of UA agents decided to do just that but it doesn't make it 
correct.  Going this route wouldn't even require an errata it would
simply be a clarification.

   Aside from all the above I have an actual question on implementation
of the proposed errata.  The errata talks a lot like the element with
the clip-path and the event target must be the same element.  In practice
the clip is often on a higher level 'g' element.  So the question I
have is do I take the errata literally and stop event propagation if
the 'g' element has pointer-events="visible" and the event is outside
of the clip the event will not propagate to the children of the 'g'
even though some of the children may have their pointer-events set to
'all' (and hence should not be effected by clipping). 

   It's especially unclear because of course a 'g' element is never
actually the event target (and hence it's pointer-event's property 
is currently never used in SVG).  I actually think it's more useful
if the pointer-event property of the element with the clip-path
effects event propagation for that clip as it allows one to 
effectively control if the clip-path also effects events (which I
think is more useful than overloading the pointer-events property
on the actual target which would then need to serve two masters).

Received on Friday, 5 December 2008 11:38:11 UTC