Re: svgView transform behaviour (was: Re: [svg2] transform on <svg>)

Below I discuss current implementations and then the options with a more
careful description of the consequences.

The attached examples consist of pairs of SVG and HTML files; either
download them all to the same folder or open them from the w3 email archive
web page [1].

ABR

[1]: https://lists.w3.org/Archives/Public/www-svg/2015Mar/
__________________________________________________

*Current Behavior*

I did some more careful testing of current implementations.  It helped that
I figured out why Blink was giving erratic results (it resets the viewBox
parameter if you don't specify it in svgView).

*Basic behavior of #svgView(transform(...)):*
See the file svgViewTransform.html, which uses svgNoTransform.svg and then
applies transformations with view fragments.

   - Firefox applies the transformation to the viewport width/height
   defined for the SVG; in other words, translation units are calculated
   before adjusting for viewBox.
   - IE and Blink apply the transformation as if all the content of the SVG
   was contained in a <g> element with the transform applied to it; in other
   words, translations use the scaled coordinate system and the image looks
   the same regardless of canvas size.


*Basic behavior of a transformation on a root element:*
See the file svgRootTransform.svg, which uses the transform style property
to rotate the graphic in the opposite direction.

   - The browsers differ according to the default transform-origin, but if
   you set that explicitly they all have the same behavior, consistent with
   the CSS specs: the transformation applies to the entire canvas, in the
   initial coordinate system.  (You would probably have to use
   `-webkit-transform` for Safari, but I assume the rendering is the same.)


*Applying an svgView transformation on a SVG with a root transform style:*
See svgViewRootTransform.html, which uses svgRootTransform.svg but is
otherwise the same as the first page.

   - All the browsers tested (including Firefox) apply the `transform`
   style on the root element to the canvas *and then* the viewTransform is
   applied to the SVG, without changing the clipping region created by the
   transform on the canvas.
   - As before, Firefox applies the view transform in canvas units, while
   the others apply it in viewBox units.

This is the opposite order of operations that we had agreed on last week.

*Applying an svgView transform on a SVG with a root transform style:*
Firefox supports the transform attribute on a <svg> element.  It *replaces*
this attribute with any value specified in an svgView fragment.  See
svgViewRootTransformAttribute.html, which uses
svgRootTransformAttribute.svg.

   - Theoretically, using the replace behavior you could cancel out a
   transformation on the root element.  You can currently create a
   `transform:none` effect in Firefox by using #svgView(transform(rotate(0)))
   or a similar null transformation.


__________________________________________________

*What *should* happen?*

Considerations: what are the use cases for svgView?

   - Using a viewBox in an svgView fragment is very useful, for image
   sprites or otherwise cropping a graphic.
   - Similarly, setting your own preserveAspectRatio options can be useful
   for layout (at least until the CSS object-fit properties are better
   supported!).
   - Transformations are more questionable -- you can achieving scaling and
   centering with viewBox, so it is mostly for rotating.
   Specifically, rotating the graphic within the image frame (not rotating the
   whole image on the web page).
   - The main use I see is with maps or other complex diagrams, to be able
   to not only zoom in but also rotate to a specific section of the graphic
   that you're discussing in the text.
   - A second possible use would be to cancel out a transformation from the
   original graphic.
   - The third use is within an interactive SVG application, to create
   effects when you click on internal links, without

Considerations: what might web developers expect to happen?
(Note, these result in contradictory suggestions for what to do -- I'm just
listing all the things to consider, not making a structured argument one
way or the other!)

   - A given image URL usually looks the same at different sizes, just
   scaled up.  However, this isn't true when using media queries inside the
   SVG, and media queries will become more powerful as more SVG layout
   attributes get converted to presentation.
   - The different parts of the svgView fragment should work the same way;
   viewBox and preserveAspectRatio replace the equivalent attributes on the
   <svg>, so the transform should work the same
   - Transformations on a root <svg> should work the same way, regardless
   of whether they are applied via attributes, styles, or an svgView fragment.

Considerations: CSS vs XML transform

   - CSS has a cascade order, styles override attributes.  Where do svgView
   settings fit in the cascade?
   - CSS transforms introduces other style properties that can affect the
   result of the transformation: if you can set a transform style with an
   svgView fragment, should you not also be able to set a transform-origin?
   - Styles (except for the `:target` pseudoclass) don't change when you
   click on an internal link, so why should a transform style property?


__________________________________________________

*What *could* happen?*

1) Deprecate the #svgView(transform(...)) option and don't worry about it.
 (This is starting to look tempting...)

2) State that svgView transform applies to the *canvas* before applying any
transformation specified within the SVG file.  Or conversely, that the SVG
is drawn as it normally would be, including any transformations in the
file, and then that drawing is shifted within the viewport.  This is how I
interpreted what we agreed last week.  It is not like anything currently
implemented.

   - Using the example from svgViewRootTransform.html, the result for
   `rotate(45)` would be that the lower right part of the square is visible,
   upright, in the image frame, with the upper right clipped.  In other words,
   the graphic's position within the SVG clipping region would not change, but
   then the entire canvas is shifted within the image frame.
   - For translation, the units would be based on the canvas, so would be a
   fixed 20px translation, not 20 scaled units.

3) State that any transformations specified in the svgView are pre-pended
to the transformation list for the root element, and therefore apply to the
canvas (including clipping region borders) the same way as transform style
on the root element.  This is how Erik interpretted what we agreed on last
week, also not like any current implementations.

   - Using the example with the negative rotation in the file and positive
   rotation in the view, the rotation would cancel out but the clipping region
   would still match the SVG drawing region, so the entire square would be
   visible, unrotated and unclipped, in the image.
   - For translation, the units would be based on the canvas (in the same
   manner as a transform on the root element), so would be a fixed 20px
   translation, not 20 scaled units.
   - It could be explicitly stated that a #svgView(transform(none)) value
   cancels out the root transform, since it doesn't make sense to pre-pend it.

4) State that any transformations specified in the svgView *replace* the
transformations for the root element.  This is what happens in Firefox when
the transformation on the root element is specified using an attribute.
However, it gets tricky from a CSS cascade perspective.

   - To make it work, we could state that any transform properties
   specified in the svgView fragment get treated as  "!important" author
   declarations with the specificity of an inline style attribute, that is
   applied after any inline style attributes on the root element.
   - This would give them override over any styles specified in the file,
   but not over !important user style sheet options (maybe someone would want
   a `transform: none !important;` option?).
   - We might as well discuss this now -- if viewBox gets turned into a
   presentation attribute, the same issue applies.
   - The actual transformation rules are clearly defined as a
   transformation on the root element.  Well, except for that transform-origin
   disagreement, but that's another topic...

5) State that an svgView transform works completely separately from the
transformation on the root element or on the canvas, as if all the content
of the SVG was contained within a <g> element with that transformation.

   - In other words, the current IE/Blink behavior, including weird
   clipping when there is also a transformation on the root.
   - Translations get applied in the

The other thing to think about -- for every option except "deprecate it!"
-- is whether you want to allow other transformation style properties to be
specified within the view.  Or for that matter, arbitrary CSS properties,
which gets into the CSS variables-as-SVG parameters discussion.

Received on Thursday, 5 March 2015 03:29:28 UTC