上一篇寫遺留下來幾個問題:
1、如果是正多面體怎么辦谎柄?
正四面體,我們可以輕松確定translateZ 的值為元素的寬的一半惯雳。那如果是正五面體呢朝巫,正N面體呢?先不急石景,哥先畫個圖劈猿,分析一下。
以一個正五邊形為例:我們最終的目的是求到AO的距離潮孽,這個距離就是我們要進行平移(translateZ)的值 揪荣, 會涉及到簡單的數(shù)學(xué)知識,正N邊形的外角邊之和永遠是360度往史。
那么我們可以算出來角度b = 360 / N 度 仗颈,求出b 再來算a就簡單了 角度a = (180-b) / 2,求出角度a了,AB為元素寬的一半椎例,要求出AO的距離挨决,就容易了。AO = Math.tan(Math.PI/180*a) * AB 粟矿,一個簡單的三角正切就能實現(xiàn)了凰棉。
再來計算下每個面的旋轉(zhuǎn)的角度應(yīng)該為 360 / N * index 度。
好了陌粹,接下來直接上代碼了撒犀。
Document
*{margin:0;padding: 0;}
html,body{
width: 100%;
height: 100%;
font-size:30px;
}
.zmiti-box{
width: 300px;
height: 300px;
position: absolute;
left: 0;
top:200px;
perspective:1800px;
left: 50%;;
margin-left: -150px;
}
.zmiti-box section{
transform-style: preserve-3d;
position:relative;
width: 100%;
height: 100%;
left: 0;
transition:5s;
}
.zmiti-box .zmiti-box-item{
position: absolute;
left: 0;
top:0;
width: 100%;
height: 100%;
line-height: 300px;
color:#fff;
font-size:80px;
text-align:center;
}
var zmitiUtil = {
length:10,//我要創(chuàng)建正20面體
init(){
this.createElement();
this.bindEvent();
},
createElement(){
this.box = document.querySelector('.zmiti-box section');
var html = '';
var elWidth = 300;//元素的寬度,也可以通過獲取元素的clientWidth,我這就硬編碼寫死了。
var angle = 360 / this.length;
var translateZ = Math.tan(Math.PI / 180 * (180 - angle) / 2) * elWidth / 2;
for(var i = 0 ;i < this.length ;i++){
html+= `
};
this.box.innerHTML = html;
},
bindEvent(){
document.body.addEventListener('touchstart',()=>{
this.box.style.transform = 'rotateY(360deg) rotateX(60deg)';
});
}
};
zmitiUtil.init();
效果如下:
但是這個好像沒什么卵用啊,造物節(jié)那個感覺人站在圓柱中間看的或舞,應(yīng)該是這樣的效果
我們改造下荆姆,我們把每個元素的translateZ取反為負值,然后再設(shè)置背面隱藏就ok了映凳。
.zmiti-box .zmiti-box-item{
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
}
記得在移動端要加上webkit前綴胆筒。否則無效哦。
最后的就是把每個面用一張張的圖片拼起來的了诈豌,原理是用一張長圖仆救,平均切成N份,然后填充成背景就搞定了哦矫渔。
移動端的適配問題:可以動態(tài)設(shè)置最外層父級的景深值來做下控制彤蔽。這里就不再做贅述了。大家可以自己研究下庙洼。