3939
4040 < h1 > CSS Transforms</ h1 >
4141
42- < h2 class ="no-num no-toc " id =longstatus-date > Editor's Draft 26 May 2012</ h2 >
42+ < h2 class ="no-num no-toc " id =longstatus-date > Editor's Draft 28 May 2012</ h2 >
4343
4444 < dl >
4545 < dt > This version:
4646
4747 < dd > < a
48- href ="http://www.w3.org/TR/2012/ED-css3-transforms-20120526 / "> http://dev.w3.org/csswg/css3-transforms/</ a >
49- <!--http://www.w3.org/TR/2012/WD-css3-transforms-20120526 /-->
48+ href ="http://www.w3.org/TR/2012/ED-css3-transforms-20120528 / "> http://dev.w3.org/csswg/css3-transforms/</ a >
49+ <!--http://www.w3.org/TR/2012/WD-css3-transforms-20120528 /-->
5050
5151 < dt > Latest version:
5252
@@ -199,6 +199,10 @@ <h2 class="no-num no-toc" id=contents>Table of contents</h2>
199199 < ul class =toc >
200200 < li > < a href ="#transform-3d-rendering "> < span class =secno > 6.1. </ span > 3D
201201 Transform Rendering</ a >
202+
203+ < li > < a href ="#processing-of-perspective-transformed-boxes "> < span
204+ class =secno > 6.2. </ span > Processing of Perspective-Transformed Boxes
205+ </ a >
202206 </ ul >
203207
204208 < li > < a href ="#transform-property "> < span class =secno > 7. </ span > The
@@ -1117,7 +1121,7 @@ <h3 id=transform-3d-rendering><span class=secno>6.1. </span>3D Transform
11171121 </ div >
11181122
11191123 < p > Using three-dimensional transforms, it's possible to transform an
1120- element such that its reverse side is towards the viewer. 3D-tranformed
1124+ element such that its reverse side is towards the viewer. 3D-transformed
11211125 elements show the same content on both sides, so the reverse side looks
11221126 like a mirror-image of the front side (as if the element were projected
11231127 onto a sheet of glass). Normally, elements whose reverse side is towards
@@ -1129,7 +1133,152 @@ <h3 id=transform-3d-rendering><span class=secno>6.1. </span>3D Transform
11291133 class =css > < code class =css > backface-visibility: hidden</ code > </ code > ’
11301134 were animating, such that its front and reverse sides were alternately
11311135 visible, then it would only be visible when the front side were towards
1132- the viewer.</ p >
1136+ the viewer.
1137+
1138+ < h3 id =processing-of-perspective-transformed-boxes > < span class =secno > 6.2.
1139+ </ span > Processing of Perspective-Transformed Boxes</ h3 >
1140+
1141+ < div class =issue >
1142+ < p class =desc > This is a first pass at an attempt to precisely specify how
1143+ exactly to transform elements using the provided matrices. It might not
1144+ be ideal, and implementer feedback is encouraged. See < a
1145+ href ="https://www.w3.org/Bugs/Public/show_bug.cgi?id=15605 "> bug
1146+ 15605</ a > .</ p >
1147+ </ div >
1148+
1149+ < p > The < a href ="#TermAccumulated3DTransformationMatrix "> accumulated 3D
1150+ transformation matrix</ a > is a 4×4 matrix, while the objects to be
1151+ transformed are two-dimensional boxes. To transform each corner
1152+ (< var > a</ var > , < var > b</ var > ) of a box, the matrix must first be applied to
1153+ (< var > a</ var > , < var > b</ var > , 0, 1), which will result in a
1154+ four-dimensional point (< var > x</ var > , < var > y</ var > , < var > z</ var > ,
1155+ < var > w</ var > ). This is transformed back to a three-dimensional point
1156+ (< var > x</ var > ′, < var > y</ var > ′, < var > z</ var > ′) as follows:
1157+
1158+ < p > If < var > w</ var > > 0, (< var > x</ var > ′, < var > y</ var > ′,
1159+ < var > z</ var > ′) = (< var > x</ var > /< var > w</ var > , < var > y</ var > /< var > w</ var > ,
1160+ < var > z</ var > /< var > w</ var > ).
1161+
1162+ < p > If < var > w</ var > = 0, (< var > x</ var > ′, < var > y</ var > ′,
1163+ < var > z</ var > ′) = (< var > x</ var > ⋅ < var > n</ var > , < var > y</ var > ⋅
1164+ < var > n</ var > , < var > z</ var > ⋅ < var > n</ var > ). < var > n</ var > is an
1165+ implementation-dependent value that should be chosen so that
1166+ < var > x</ var > ′ or < var > y</ var > ′ is much larger than the viewport size,
1167+ if possible. For example, (5px, 22px, 0px, 0) might become (5000px,
1168+ 22000px, 0px), with < var > n</ var > = 1000, but this value of < var > n</ var >
1169+ would be too small for (0.1px, 0.05px, 0px, 0). This specification does
1170+ not define the value of < var > n</ var > exactly. Conceptually,
1171+ (< var > x</ var > ′, < var > y</ var > ′, < var > z</ var > ′) is < a
1172+ href ="http://en.wikipedia.org/wiki/Plane_at_infinity "> infinitely far</ a >
1173+ in the direction (< var > x</ var > , < var > y</ var > , < var > z</ var > ).
1174+
1175+ < p > If < var > w</ var > < 0 for all four corners of the transformed box, the
1176+ box is not rendered.
1177+
1178+ < p > If < var > w</ var > < 0 for one to three corners of the transformed box,
1179+ the box must be replaced by a polygon that has any parts with < var > w</ var >
1180+ < 0 cut out. This will in general be a polygon with three to five
1181+ vertices, of which exactly two will have < var > w</ var > = 0 and the rest
1182+ < var > w</ var > > 0. These vertices are then transformed to
1183+ three-dimensional points using the rules just stated. Conceptually, a
1184+ point with < var > w</ var > < 0 is "behind" the viewer, so should not be
1185+ visible.
1186+
1187+ < div class =example >
1188+ < pre > <style>
1189+ .transformed {
1190+ height: 100px;
1191+ width: 100px;
1192+ background: lime;
1193+ transform: perspective(50px) translateZ(100px);
1194+ }
1195+ </style></ pre >
1196+
1197+ < p > All of the box's corners have < var > z</ var > -coordinates greater than
1198+ the perspective. This means that the box is behind the viewer and will
1199+ not display. Mathematically, the point (< var > x</ var > , < var > y</ var > ) first
1200+ becomes (< var > x</ var > , < var > y</ var > , 0, 1), then is translated to
1201+ (< var > x</ var > , < var > y</ var > , 100, 1), and then applying the perspective
1202+ results in (< var > x</ var > , < var > y</ var > , 100, −1). The
1203+ < var > w</ var > -coordinate is negative, so it does not display. An
1204+ implementation that doesn't handle the < var > w</ var > < 0 case
1205+ separately might incorrectly display this point as (−< var > x</ var > ,
1206+ −< var > y</ var > , −100), dividing by −1 and mirroring the box.</ p >
1207+ </ div >
1208+
1209+ < div class =example >
1210+ < pre > <style>
1211+ .transformed {
1212+ height: 100px;
1213+ width: 100px;
1214+ background: radial-gradient(yellow, blue);
1215+ transform: perspective(50px) translateZ(50px);
1216+ }
1217+ </style></ pre >
1218+
1219+ < p > Here, the box is translated upward so that it sits at the same place
1220+ the viewer is looking from. This is like bringing the box closer and
1221+ closer to one's eye until it fills the entire field of vision. Since the
1222+ default transform-origin is at the center of the box, which is yellow,
1223+ the screen will be filled with yellow.</ p >
1224+
1225+ < p > Mathematically, the point (< var > x</ var > , < var > y</ var > ) first becomes
1226+ (< var > x</ var > , < var > y</ var > , 0, 1), then is translated to (< var > x</ var > ,
1227+ < var > y</ var > , 50, 1), then becomes (< var > x</ var > , < var > y</ var > , 50, 0)
1228+ after applying perspective. Relative to the transform-origin at the
1229+ center, the upper-left corner was (−50, −50), so it becomes (−50,
1230+ −50, 50, 0). This is transformed to something very far to the upper
1231+ left, such as (−5000, −5000, 5000). Likewise the other corners are
1232+ sent very far away. The radial gradient is stretched over the whole box,
1233+ now enormous, so the part that's visible without scrolling should be the
1234+ color of the middle pixel: yellow. However, since the box is not actually
1235+ infinite, the user can still scroll to the edges to see the blue parts.</ p >
1236+ <!-- TODO: Maybe we should specify that the whole thing is
1237+ yellow here somehow? Doesn't seem worth it. -->
1238+ </ div >
1239+
1240+ < div class =example >
1241+ < pre > <style>
1242+ .transformed {
1243+ height: 50px;
1244+ width: 50px;
1245+ background: lime;
1246+ border: 25px solid blue;
1247+ transform-origin: left;
1248+ transform: perspective(50px) rotateY(-45deg);
1249+ }
1250+ </style></ pre >
1251+
1252+ < p > The box will be rotated toward the viewer, with the left edge staying
1253+ fixed while the right edge swings closer. The right edge will be at about
1254+ < var > z</ var > = 70.7px, which is closer than the perspective of 50px.
1255+ Therefore, the rightmost edge will vanish ("behind" the viewer), and the
1256+ visible part will stretch out infinitely far to the right.</ p >
1257+
1258+ < p > Mathematically, the top right vertex of the box was originally (100,
1259+ −50), relative to the transform-origin. It is first expanded to (100,
1260+ −50, 0, 1). After applying the transform specified, this will get
1261+ mapped to about (70.71, −50, 70.71, −0.4142). This has < var > w</ var > =
1262+ −0.4142 < 0, so we need to slice away the part of the box with
1263+ < var > w</ var > < 0. This results in the new top-right vertex being (50,
1264+ −50, 50, 0). This is then mapped to some faraway point in the same
1265+ direction, such as (5000, −5000, 5000), which is up and to the right
1266+ from the transform-origin. Something similar is done to the lower right
1267+ corner, which gets mapped far down and to the right. The resulting box
1268+ stretches far past the edge of the screen.</ p >
1269+
1270+ < p > Again, the rendered box is still finite, so the user can scroll to see
1271+ the whole thing if he or she chooses. However, the right part has been
1272+ chopped off. No matter how far the user scrolls, the rightmost 30px or so
1273+ of the original box will not be visible. The blue border was only 25px
1274+ wide, so it will be visible on the left, top, and bottom, but not the
1275+ right.</ p >
1276+
1277+ < p > The same basic procedure would apply if one or three vertices had
1278+ < var > w</ var > < 0. However, in that case the result of truncating the
1279+ < var > w</ var > < 0 part would be a triangle or pentagon instead of a
1280+ quadrilateral.</ p >
1281+ </ div >
11331282 <!-- ======================================================================================================= -->
11341283
11351284 < h2 id =transform-property > < span class =secno > 7. </ span > The ‘< a
0 commit comments