Open Crissov opened 7 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.
Since CSS usually prefers 🥙 over 🐪 case, I think keywords like flip-x
and flip-y
would work well.
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 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 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.
These have the same scaling factor on all axes.
One axis is scaled differently.
One skewing angle from the horizon is 45°.
Cavalier projection (5.3.1): no scaling (isometric), one axis unskewed, the other by 45°
Cabinet projection (5.3.2): same as Cavalier but depth axis scaled by ½ (dimetric)
Planometric projections (5.3.3)
skewing angles from horizon add up to 90°, choices of n×15° are common, 0°, 90° and 180° (as in the picture below) should be avoided; normally no scaling (5.3.3.1, isometric), but shortening of the height by ⅔ possible (5.3.3.2, dimetric)
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> |
<projection>
= [ none
| isometric
| cavalier
| cabinet
| engineer
| military
| game
| … ]<direction>
= top-right
| bottom-right
| bottom-left
| top-left
<view>
= front
| back
| top
| right
| bottom
| left
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.
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?
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:
transform
projection
or perspective
The
transform
property currently acceptsnone
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.flip-vertical
,flip
?scale(1, -1)
flip-horizontal
,mirror
?scale(-1, 1)
mirror
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)
orrotate(-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 ratherrotate(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.