Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
174 views
in Technique[技术] by (71.8m points)

javascript - CSS 3D animation, how?

I would like to animate things in 3D space. I know this is possible with CSS and HTML5, but I can't find a good tutorial for practical use!

I found this website as an example. You can select text etc. All the time. Can somebody give a very easy to understand and little example how this works? I see the source code but I don't really understand it…

Is this CSS3 or HTML5 or both?

How much JavaScript do I need?

Which browsers support this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are two parts to this.

  1. The first one is about building the 3D shape.
  2. The second one involves animating it (and this is the simple part).

UPDATE AUGUST 2019

This is a really old answer and I'll leave the meat of the original below, just removing the links that don't work anymore.

But since I wrote this, both my coding abilities and browsers have progressed, so if you want to build a CSS cube in a more efficient fashion, check out this article I wrote on the topic:

Simplifying CSS Cubes with Custom Properties


I'll go through each one of them in detail, but first I'll briefly answer the three questions you've asked at the end.

is this css3 or html5 or both?

It's CSS3. CSS 3D transforms and keyframe animations.

how much javascript do I need?

Well, if you don't want to create 3D shape itself with JavaScript, then you don't need any JavaScript to animate it. Any browser that supports 3D transforms also supports keyframe animations and, if a browser supports keyframe animations, then you probably want to use those instead of jQuery (and maybe even your own custom JS) animations.

which browsers support this?

Things didn't look good two years ago, but they're getting better...

? Chrome, Safari, Firefox (though Firefox 3D animations are jiggly and not nice to my CPU... I do have a 6-year-old old laptop, it's true) Opera 15+ (WebKit) support 3D transforms. And of course keyframe animations.

Firefox supports everything unprefixed, Chrome/Safari/Opera need the -webkit- prefix - update: Chrome 36+ and Opera 23+ support them unprefixed as well, so it's only Safari left now. I won't be using any prefixes in the answer or in the demo (-prefix-free takes care of things there). Another update: Safari 9 unprefixes transforms.

? 3D transforms were not supported by Opera before switching to WebKit.

? IE up to and including 9 don't support 3D transforms. IE10 and IE11 support 3D transforms, but do not support nesting of 3D transformed elements (cannot create realistic looking 3D shapes via applying 3D transforms on both parent and child elements, as 3D transformed children of a 3D transformed parent get flattened into the plane of the parent). Update: Edge now supports nesting of 3D transformed elements.


Alright, I hope that clears a few things. Now...

1 Building a CSS cube.

1.2 What is a cube and starting off with the HTML

First of all, try to picture a cube. Maybe this link helps? Or let's have an image here as well.

cube

It has 6 square faces. 1 top, 1 bottom; 1 in front, 1 in the back; 1 left, 1 right. This means that the HTML is simply:

<ul class='cube'>
    <li class='face'></li>
    <li class='face'></li>
    <li class='face'></li>
    <li class='face'></li>
    <li class='face'></li>
    <li class='face'></li>
</ul>

You first put some regularity into the faces, give them equal width and height, position them absolutely so that they're all stacked one on top of the other, give them different backgrounds, they don't mind that. You can give them some padding, put some dummy text into them, whatever...

Now comes the interesting part: moving them so that they form a cube in space. You do that using 3D transforms.

1.2 The Coordinate System

Consider this 3D coordinate system:

3D coordinate system

Initially, all the 6 faces are all exactly where you see the blue square, in the xOy plane (where O is the intersection of the 3 axes).

Pay attention to the direction of the y-axis. Coming from a mathematical background, this seemed a bit weird to me at first, but this is how the coordinate system is for the screen.

In 2D, the origin O is at the top left corner, so the + (positive direction) of the x-axis points right and the + of the y-axis points down.

1.2.a Translations along the axes

So a translation of a positive value along the x-axis (for example, translateX(10px)) moves the element to which it is applied to the right (towards the + of the x-axis), while a translation of a negative value along the x-axis (something like translateX(-10px)) moves it to the left.

Similarly, a translation of a positive value along the y-axis (like translateY(10px)) moves the element down (towards the + of the y-axis), while a translation of a negative value along the y-axis (like translateY(-10px)) moves it up.

Now add another dimension. With the z-axis. The + (positive direction) of the z-axis comes out of the screen, towards you. So a translation of a positive value along the z-axis (like translateZ(10px)) moves the element forward (towards the + of the z-axis and towards you), while a translation of a negative value along the z-axis (like translateZ(-10px)) moves it backward (away from you).

1.2.b Rotations around the axes

Rotations of positive angle values (for example, rotate(15deg) - note that if the rotation axis is not specified, then it is assumed to be the z-axis) in CSS are clockwise and rotations of negative angle values (like rotate(-15deg)) are counter-clockwise.

And clockwise means clockwise as seen from the + of the axis around which you rotate the element.

So a positive rotation around the x-axis means a clockwise rotation in the yOz plane as seen from the + of the x-axis, which is at the right.

A positive rotation around the y-axis means a clockwise rotation in the zOx plane (the horizontal plane) as seen from the + of the y-axis, which is at the bottom.

A positive rotation around the z-axis means a clockwise rotation in the xOy plane (the plane of the screen) as seen from the + of the z-axis, which is how you naturally see the screen.

1.3 Put the faces in the right positions in order to form the cube

1.3.1 Put one face at the front

This means translating it forwards (in the positive direction) along the z-axis. What is this? A translateZ of a positive value. What value? Well, it should be half the width (or the height, doesn't matter, it's a square, they're equal).

Suppose I have the width: 16em;

Then in this case, you translate the face forward (along the positive z-axis) by 16em/2 = 8em. In CSS, that's

.face:nth-child(1) { transform: translateZ(8em); }

Note: The translate transform moves the entire coordinate system of the element that is translated (and consequently, the transform-origin for any subsequent transforms).

1.3.2 Put the second face at the back

That's simple, right? Just a translate along the z-axis, by the same value in the opposite direction, right? .face:nth-child(2) { transform: translateZ(-8em); }, right?

Well... actually... only if you don't want to put any content on that face. Or if you don't want to have as a background an image for which it matters which is left and which is right.

Each of these squares that make up the cube has a front and a back. The front is the one towards the positive direction of the z-axis; the one that "looks at you from the computer screen". If you put text there, it flows normally on the front. But it looks vertically mirrored on the back.

That's why the first thing that you should do is to rotate the second square face by 180° around the vertical axis (y-axis). After doing that, you can then translate this second square face along the z-axis in order to move it to the back.

The translate value is again positive in this case. Just like the translate transform moves the coordinate system of the element that is translated, the rotate transform... well... rotates it. This means that after rotateY(180deg) is applied, the + of the z-axis points towards the back (not towards the front anymore).

So the CSS that rotates and then translates the second face into its position on the cube is:

.face:nth-child(2) { transform: rotateY(180deg) translateZ(8em); }

Note: the cube is a really simple 3D shape, but one CSS property that I find really useful to check whether I've rotated faces the right way is backface-visibility. If I set it to hidden and I don't see the rotated element, it means that I'm looking at it from the back.

1.3.3 Put the third face to the right

First of all, its front has to "look" towards the right. This means that it has to be rotated around the y-axis so that the + of the z-axis ends up pointing towards the right and then it has to be translated along the positive z-axis by the same positive value (8em in this case) that is half the length of the side of the square.

Rotated by what angle? Well, 90°, which means the CSS needed is:

.face:nth-child(3) { transform: rotateY(90deg) translateZ(8em); }

1.3.4 Put the fourth face to the left

First rotate it by 90°, but the other way, to make its front "look" towards the left. "The other way" means rotateY(-90deg), then apply the same old translateZ(8em). In one CSS line:

.face:nth-child(4) { transform: rotateY(-90deg) translateZ(8em); }
<h3

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...