preface

I have been longing for JS panorama for a long time, which seems to have been seen since 16 years ago. At that time, I was still a small chicken (although I am not a big man now). Due to my work, I did not understand many aspects of the front end in time.

The preparatory work

Understand some basic concepts in Transform, such as:

The rotate rotating

Translate defines 2D transformations

TranslateZ defines 3D transformations

Perspective defines the perspective for 3D transformation elements.

transform-style: preserve-3d; Specifies that child elements are positioned in three dimensions. In addition, the property is non-inherited.

Let’s get started

There is a cube demo in my Github, as shown below:

The demo link is here

Source link


Cube principle

A cube, as we all know, is a regular polyhedron made up of six squares. The diagram below:


panorama

Here we use a panoramic example to help us understand perspective and translateZ.

There are two kinds of composition of panorama, namely cube and sphere (prism). We use cube here for example.

I have not yet understood the difference between a sphere and a prism, so when I do, we will come back later


Make a cube

1. Make 6 noodles

Since the cube is made up of six squares, we make its parts first and then assemble them.

Here we use face as the surface, but the top, bottom, left, right, after, the first to represent the up, down, left, right, before and after a few surface.

Here we are looking directly at First

We define a window stage, a perspective box CTX, and a cube container facelist.

Let’s start by defining the window as 800 by 800 centered vertically relative to the page

Let’s start by defining the cube as 800px wide and 800px high; Then define the width and height of each face as 800px and give each face a different color to distinguish it.

The code is as follows:

<! DOCTYPE html> <html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge"< span style> * {margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } .stage { width: 800px; height: 800px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .face { width: 800px; height: 800px; } .top { background: green; } .bottom { background: yellow; } .after { background: red; } .left { background: black; } .right { background: blue; } .first { background: blueviolet; } </style> </head> <body> <div class='stage'>
    <div class='ctx'>
      <div class='facelist'>
        <div class='face top'>1</div>
        <div class='face bottom'>2</div>
        <div class='face after'>3</div>
        <div class='face left'>4</div>
        <div class='face right'>5</div>
        <div class='face first'>6</div>
      </div>
    </div>
  </div>

  <script>

  </script>
</body>

</html>
Copy the code

Second, the combination of

At this point we have made the six faces of the cube, but they are arranged on the page at once, which is not what we want;

Let’s put them together first. Add position to face: absolute;

So that they are superimposed, we need to do this:

1. Rotate them to their respective angles
For example: The face of.top we rotate it 90 degrees about the X-axis; The. Left surface is rotated 90 degrees about the Y axis; ...Copy the code

Think no

<! DOCTYPE html> <html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge"< span style> * {margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } .stage { width: 800px; height: 800px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .face { width: 800px; height: 800px; position: absolute; } .top { background: green; transform: rotateX(90deg); } .bottom { background: yellow; transform: rotateX(90deg); } .after { background: red; transform: rotateX(0deg); } .left { background: black; transform: rotateY(90deg); } .right { background: blue; transform: rotateY(90deg); } .first { background: blueviolet; transform: rotateY(0deg); } </style> </head> <body> <div class='stage'>
    <div class='ctx'>
      <div class='facelist'>
        <div class='face top'>1</div>
        <div class='face bottom'>2</div>
        <div class='face after'>3</div>
        <div class='face left'>4</div>
        <div class='face right'>5</div>
        <div class='face first'>6</div>
      </div>
    </div>
  </div>

  <script>

  </script>
</body>

</html>

Copy the code

It should look something like this

To make it look like nothing has changed, let’s look at this picture:

Superimposing each face on the black origin is what it actually looks like, which means it’s not a cube yet

Because their centers overlap, how do you turn them into cubes? Look at the steps below

2. Push them through translateZ with the corresponding side length
Since we have a cube here, the side length of the square is ±400px, and we set the translateZ value for them, and let the faces move in different directions until a complete cube is formed.Copy the code
<! DOCTYPE html> <html lang="zh">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge"< span style> * {margin: 0; padding: 0; } html, body { height: 100%; overflow: hidden; } .stage { width: 800px; height: 800px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .face { width: 800px; height: 800px; position: absolute; } .top { background: green; transform: rotateX(90deg) translateZ(400px); } .bottom { background: yellow; transform: rotateX(90deg) translateZ(-400px); } .after { background: red; transform: rotateX(0deg) translateZ(-400px); } .left { background: black; transform: rotateY(90deg) translateZ(-400px); } .right { background: blue; transform: rotateY(90deg) translateZ(400px); } .first { background: blueviolet; transform: rotateY(0deg) translateZ(400px); } </style> </head> <body> <div class='stage'>
    <div class='ctx'>
      <div class='facelist'>
        <div class='face top'>1</div>
        <div class='face bottom'>2</div>
        <div class='face after'>3</div>
        <div class='face left'>4</div>
        <div class='face right'>5</div>
        <div class='face first'>6</div>
      </div>
    </div>
  </div>

  <script>

  </script>
</body>

</html>
Copy the code
3. Add 3D effect

We added 3D properties to the CTX box to make 3D three-dimensional

···. CTX {/* 3d perspective */ transform-style: preserve-3d; }...Copy the code
4. Push our perspective to the center

First adjust the visual distance of the stage, and adjust our eyes to the first side of the CTX

At this point we are 800px away from the after plane and 400px away from the CTX plane

We then push the CTX perspective box out by a distance of 1/2width (400px), placing our eyes in the center

If you don’t understand, please pay attention to the separate explanation below.

.stage { width: 800px; height: 800px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); /* The distance from the current perspective to the corresponding plane is the distance from stage to CTX */ perspective: 400px; /* /* perspective origin: 50% 100%; */}. CTX {/* 3d Angle */ transform-style: preserve-3d; */ transform: translateZ(400px) rotateY(0deg); }Copy the code

Third, finished

So we’ve made a 3D cube and put our perspective on the center of the inside of the cube.

We can view the entire cube by changing the value of perspective-Origin

Adjust the Angle and see the cube from different angles, which helps to understand the perspective faster.

Explain perspective and translateZ separately

I found a picture that helped me understand:

Here Z means translateZ and D means perspective

And here we have to know that the Z axis is positive.

So the summary is:

  • Perspective is the distance from your current perspective to the plane you see
  • TranslateZ refers to the distance from the plane you are looking at to the perspective of propulsion. In plain English, it’s the distance that pulls you in or pulls you out from the current distance
  • The perspective of the person in the 3D projection effect is near larger than far smaller

A top priority

Understand the perspective relationship between the eyes and the plane is the picture above!!

conclusion

These things might be a little hard for someone new to CSS 3D to understand;

For most of us, it’s impossible to fully understand just by reading the text;

So here’s another quote for you:

Practice is the sole criterion for testing truth

I hope you can always give priority to practice, reading as a supplement, their real understanding is their own. Thank you very much!