w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.44k stars 656 forks source link

[css-transforms-2] Keywords for `transform` #944

Open Crissov opened 7 years ago

Crissov commented 7 years ago

The transform property currently accepts none or a list of transform functions. I believe it would make sense to add some keywords for common use cases. This could make code more readable especially for beginners and math-illiterates.

Keyword Equivalent function
flip-vertical, flip? scale(1, -1)
flip-horizontal, mirror? scale(-1, 1)
mirror flip in writing direction?
rotate, flip?, straight, turn-down, down rotate(0.5turn) = flip-vertical flip-horizontal (rotate(straight)?)
rotate-clockwise, turn-right, right rotate(0.25turn) (rotate(right)?)
rotate-anticlockwise, turn-left, left rotate(0.75turn) or rotate(-0.25turn) (rotate(left)?)
flip-diagonal-right, flip-right turn-right flip-vertical = turn-left flip-horizontal
flip-diagonal-left, flip-left turn-right flip-horizontal = turn-left flip-vertical
spin, full, turn-up, up rotate(1turn) (only makes sense with animation)
north-north-east rotate(22.5deg)
clock-1 rotate(30deg)
north-east rotate(45deg)
clock-2 rotate(60deg)
east-north-east rotate(67.5deg)
clock-3, east rotate(90deg)
east-south-east rotate(112.5deg)
clock-4 rotate(120deg)
south-east rotate(135deg)
clock-5 rotate(150deg)
south-south-east rotate(157.5deg)
clock-6, south rotate(180deg)
south-south-west rotate(202.5deg)
clock-7 rotate(210deg)
south-west rotate(225deg)
clock-8 rotate(240deg)
west-south-west rotate(247.5deg)
clock-9, west rotate(270deg)
west-north-west rotate(292.5deg)
clock-10 rotate(300deg)
north-west rotate(315deg)
clock-11 rotate(330deg)
north-north-west rotate(337.5deg)
clock-12, north rotate(360deg)

In SVG, where transform-origin defaults to (0 0) instead of (50% 50%), flipping also requires a translation by the respective size (i.e. width or height) of the box.

The systematic rotations (which were added in early May 2019 to this issue) are obviously based upon twelfth-turns (clock) and sixteenth-, eighth- or quarter-turns (compass directions). Those could be implemented as global <angle> keywords in css-values instead, e.g. rotate(north-north-west) or perhaps rather rotate(NNW). This could also include special named angles like the Golden Angle of ca. 137.5° = π·(3−√5) and the Magic Angle of ca. 54.7° = arctan √2.

AmeliaBR commented 5 years ago

The geometry APIs already have flipX and flipY as shorthand functions. I'd love to be able to use those as transform: flipX() (with or without the empty parentheses).

https://drafts.fxtf.org/geometry/#dom-dommatrixreadonly-flipx

In SVG, where transform-origin defaults to (0 0) instead of (50% 50%), flipping also requires a translation by the respective size (i.e. width or height) of the box.

That would not be consistent with the existing APIs.

Crissov commented 5 years ago

Since CSS usually prefers 🥙 over 🐪 case, I think keywords like flip-x and flip-y would work well.

Crissov commented 5 years ago

Recently, I came across another use case that would benefit from predefined keywords: projections of 3D objects into 2D space or, in other words, displaying 2D boxes as if they were in 3D space. There are several standardized and common ways to do this, which come with specific skewing angles (measured from the horizon) and scaling factors:

Orthographic representations (ISO 5456-2)

Orthographic representation in its various forms is the most widely used method of representing technical objects in all fields of technical drawing (mechanical, electrical, construction, etc.), and is thus considered to be the accepted technical language.

Axonometric representations (ISO 5456-3)

Axonometric representations are simple pictorial representations obtained by projecting the object to be represented from an infinitely distant point (projection centre) on a single projection plane (normally the drawing surface). This kind of parallel projection gives an adequate approximation for distant views.

Isometric projection

These have the same scaling factor on all axes.

Dimetric projections

One axis is scaled differently.

Oblique projections (ISO 5456-3 5.3)

One skewing angle from the horizon is 45°.

Central projections (ISO 5456-4)

Central projection (perspective) is a realistic pictorial representation obtained by projecting the object to be represented from a point at finite distance (projection centre) on a single projection plane (normally the drawing surface). Central projection provides excellent visual appearance of the object (monocular vision) and is often used in architectural drawings.


I imagine being able to specify something like transform: isometric right to treat a 2D box as the right side XY view of a 3D object by skewing, scaling and perhaps translating it into what would be the right-hand YZ plane (CSS axes, ISO: X′Z′).

Name: transform
Value: <direction>? <projection> <view>? | <transform-list>

I am still trying to wind my head around these terms and the math behind them, so not everything above may make immediate sense. However, I found it way too complicated to achieve such a projection in SVG.

tabatkins commented 5 years ago

transform is about positioning an item in 3d space; you're talking about changing the way 3d space is rendered into a 2d surface. This is more akin to perspective than anything else (tho, perspective is implemented hackily as a per-element transform that just approximates the idea of perspective depth).

In particular, setting something as "facing" one of the six cardinal directions isn't enough to reproduce your examples, where there are diagonal surfaces, etc.

If I'm reading your examples correctly, tho, all the transformations are achievable as a rotate/scale/skew transform on the container, and then rendering isometrically?

Crissov commented 5 years ago

Oh, I failed to see and thus consider perspective, but it sounds more like a real 3D feature, i.e. produce this:

You are right that the transforms would not be enough to make a proper 3D object (other than cuboids) out of 2D tiles. The blue house graphics from Wikipedia are intended to visualize the differences of the various methods, not to suggest this was actually possible to achieve.

I was only (or should have only be) thinking about 2D transformations of 2D boxes into a 3D space projected onto the 2D surface. My actual use case was an transformed CSS Grid that should align with isometric bitmaps. I think that would be in scope of transform because the projections from three (or, with transparency, six) perpendicular views are indeed achievable with its level 1 capabilities – some may also require translate and proper transform-origin in addition to skew.

Like I said, I have not yet thought this through completely. It could well belong elsewhere. Possibly, projections belong in two places:

  1. 2D to 2D transform
  2. 3D to 2D projection or perspective