Reputation: 28940
Here is a jsbin of what I have so far and below is an image of what I am trying to construct:
Here is the html, I have only 2 sides of the pyramid added so far:
<div class="pyramid-container">
<div id="pyramid">
<div class="base"></div>
<div></div>
<div></div>
</div>
</div>
And here is the css:
.pyramid-container {
perspective: 800px;
}
#pyramid {
position: relative;
transform-style: preserve-3d;
transform-origin: 116px 200px 116px;
padding-left: 100px;
margin-top: 50px
}
#pyramid div:not(.base) {
position: absolute;
width: 0;
height: 0;
border-left: 100px solid transparent; /* left arrow slant */
border-right: 100px solid transparent; /* right arrow slant */
border-bottom: 100px solid; /* bottom, add background color here */
font-size: 12px;
line-height: 0;
opacity: .5;
}
.base {
position: absolute;
width: 200px;
height: 200px;
background-color: #ff0000;
transform: rotateX(80deg) translate3d(0px, 10px, 0px);
}
#pyramid div:nth-child(2) {
border-bottom-color: blue;//#e04545;
transform: rotateX(-30deg) rotateY(0deg) rotateZ(0deg) translate3d(0px, 0px, 100px);
}
#pyramid div:nth-child(3) {
border-bottom-color: yellow;//#ccaf5a;
transform: rotateX(30deg) rotateY(0deg) rotateZ(0deg) translate3d(0px, 25px, 0px);
}
I am using css3 to create 1 base rectangular div and 4 triangular divs.
I would like some help with the maths involved as well as how to position the elements.
I would like all 4 of the triangle sides to meet at an apex and have the four triangle bottom sides positioned on the rectangular div.
I am struggling with how to get the points of the different triangles to meet in at an apex.
Can anyone help me out with the maths or what logic to use to achieve this.
I'm not looking for code but more the logic or maths I should use.
Upvotes: 2
Views: 2205
Reputation: 11415
So first, a couple fundamental points on CSS transforms
transform-origin
, it is by default the center of the object (borders et al. included, afaict)Then on pyramids:
Let us look at the Base angle (let's call it α). Expressing the triangle sizes based on the angle α, you get:
In the pyramid of your attempt, Base = 200px thus 1/2 Base = 100px and Apothem = triangle height = 100px. This forces cos(α) = 1 thus α = 0° -- you will have a flat pyramid.
If you want α = 60°, you want apothem = 200px, and you'll get pyramid height = 173.2
If you want α = 45°, you want apothem = 141px, and you'll get pyramid height = 100
etc.
The main secret now you know the parameters, is to reason at each step, about where the axis are pointed, and at which point of the object you are applying the transforms. Paper & pencil or trial & error, whatever works is good.
So here's how I would do to place triangles:
Thanks to the first rotation, the two identical last steps will do what you want on all triangles.
For the base, it's easier, you can keep the default css-transform
Below is what it would look like for α = 45°, feel free to not open the snippet if you don't want spoilers.
#pyramid {
perspective: 400px;
padding: 50px 0 0 200px;
}
#pyramid div:not(.base) {
position: absolute;
border-left: 100px solid transparent; /* 1/2 Base */
border-right: 100px solid transparent; /* 1/2 Base */
border-bottom: 141px solid; /* Apothem */
transform-origin: 100px 141px 0; /* bottom of trangle (1/2 Base, Apothem) */
opacity: .5;
}
.base {
position: absolute;
width: 200px;
height: 200px;
background-color: #2f2f2f;
/* transform by default from middle (100px, 100px)
move by Apothem - 1/2 Base = 41px */
transform: rotateX(90deg) translate3d(0px, 0px, -41px);
opacity: .5;
}
#pyramid div:nth-child(2) {
border-bottom-color: #e04545;
transform: rotateY(0deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
#pyramid div:nth-child(3) {
border-bottom-color: #ccaf5a;
transform: rotateY(90deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
#pyramid div:nth-child(4) {
transform: rotateY(180deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
#pyramid div:nth-child(5) {
border-bottom-color: #4ccfc7;
transform: rotateY(270deg) translate3d(0px, 0px, 100px) rotateX(45deg);
}
<!doctype html>
<html>
<head><title>Pyramid</title></head>
<body>
<div class="pyramid-container">
<div id="pyramid">
<div class="base"></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</body>
</html>
Upvotes: 2