Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CSS3 matrix3d rectangle to trapezoid transformation

I am trying to use webkit's support for CSS3 transform: matrix3d(<matrix>) to create a 'falling card' effect. (The only target for the output of this is Chrome)

The end effect should transition through the 4 stages below and end up as just a horizontal line:

enter image description here

Here is the CSS I have now:

#test { 
            margin: auto auto;
            height: 200px;
            width: 200px;
            border:1px solid black;
            background-color: lightblue;
            -webkit-perspective: 1000; 
            -webkit-transform-origin: 50% 100%;
            -webkit-transform-style: preserve-3d;
            -webkit-animation-name: flip-card;        
            -webkit-animation-duration: 1s;        
            -webkit-animation-iteration-count: infinite;        
            -webkit-animation-timing-function: linear;
            -webkit-box-shadow: 0px 5px 20px rgba(0, 0, 0, 0.5);
        }
         @-webkit-keyframes flip-card {
            0%    {-webkit-transform: ;}
            100%    {-webkit-transform:
                        matrix3d(1, 0, 0, 0,
                                 0, 1, 0, 0, 
                                 0, 0, 0, 0, 
                                 0, 0, 0.001, 1);}
        }    

And the HTML is simple for testing:

<body>
   <div id="test">this div should fall forward...</div>
</body>

The matrix3d in the above was based on reading this SO question, but it produces a shrinking square that flips around the x-axis defined by the bottom of the initial box.

I understand that CSS 2d matrix can only produce rectangles and parallelograms by transformation of a box and that irregular shapes need the matrix3d transform operation (this was helpful in refreshing my fading linear algebra!), but I seem to only be able to produce rectangles and parallelograms.

I've looked around at some of the SO questions tagged with matrix and transformation. Most of them are not CSS based and I have not been able to get the transformation I want.

like image 457
beggs Avatar asked Feb 10 '11 08:02

beggs


1 Answers

-webkit-perspective doesn't work in Chrome yet (just Safari), so this won't work (try your code in Safari). Also 3D transforms in Chrome, in general, are a bit iffy, and don't combine well with gradients, for one.

Also rotate3d(1, 0, 0, 90deg) works just as well as a matrix to accomplish what you're doing. The matrix notation is just a short way of combining 3D rotate, skew, move and origin into a single array. Since you're only rotating around the x-axis, you don't need to go to these lengths.

webkit-transform: perspective(800) rotate3d(1, 0, 0, -90deg)

Is exactly what you need.

Update: Here is a link to a jsfiddle with exactly what you are looking for that works in both chrome and safari. Please note that its important to specify that the transform origin for the flip is the same as the origin for the perspective. Webkit-perspective origin specifies where the "camera" is in 3D space relative to any 3d transforms and it's easy to get unintuitive results if you're not careful.

2nd Update: Perspective is now supported in all edge browsers (although firefox's anti-aliasing has little to recommend it (and needs -moz obviously))

3rd Update: Updated the fiddle for cross browser for Firefox, IE and unprefixed.

like image 136
Michael Mullany Avatar answered Nov 11 '22 14:11

Michael Mullany