我們缺的不是技術,而是創意...
周末閑在家確實無聊。宅的不成樣子了。偶然發現國外一個web設計的網站上有一個3D時鐘。頓時來了興趣。其實一看代碼,不是svg,也不是canvas,而是簡單的利用層級關系,大小關系作了一個視覺差。看起來會有立體運動的感覺。
于是,借著源碼,我稍微把它整理一下,利用閉包規避了它大量的全局變量,稍微封裝了一下,增加了幾項可配置性。覺得好玩,分享給大家。
這個效果主要有兩個核心的變換,一個是時鐘整體圓周的變化,一個是組成時鐘的小元素的位置和層級的變化。
核心變換代碼主要有兩段:
mainloop: function () {
// rotations
_dir == 'left' ? A-=0.1 : A+=0.1;
rx+=px;
ry+=py;
crx=Math.cos(rx);
srx=Math.sin(rx);
cry=Math.cos(ry+Math.PI/2);
sry=Math.sin(ry+Math.PI/2);
// return to the horizontale
rx*=.9; ry*=.9; px*=.9; py*=.9;
// refresh time
.
.
.
// call animation
for(var i in O){
for(var j in O[i].O){
O[i].O[j].anim();
}
}
setTimeout(arguments.callee,32);
}
// rotations
_dir == 'left' ? A-=0.1 : A+=0.1;
rx+=px;
ry+=py;
crx=Math.cos(rx);
srx=Math.sin(rx);
cry=Math.cos(ry+Math.PI/2);
sry=Math.sin(ry+Math.PI/2);
// return to the horizontale
rx*=.9; ry*=.9; px*=.9; py*=.9;
// refresh time
.
.
.
// call animation
for(var i in O){
for(var j in O[i].O){
O[i].O[j].anim();
}
}
setTimeout(arguments.callee,32);
}
然后結合anim(),可以造出圓環的效果。
// main 3D function
CObj.prototype.anim=function() {
// z axis rotation
var x=Math.sin(A+this.a)*100;
var y=Math.cos(A+this.a)*100;
// simple 3D
var x1=y*crx-this.z*srx;
var zz=y*srx+this.z*crx;
var y1=x*cry-zz*sry;
zz=x*sry+zz*cry;
// 2D projection
var r=400/(400+zz);
x=Math.round(150-x1/r);
y=Math.round(100-y1/r);
var w=Math.round(2+Math.max(4,zz*.07));
// leds lighting
this.alpha(zz);
// html positioning
var css = this.o.style;
css.left=x+"px";
css.top=y+"px";
css.width=css.height=w+"px";
css.zIndex=Math.round(1000+zz);
}
CObj.prototype.anim=function() {
// z axis rotation
var x=Math.sin(A+this.a)*100;
var y=Math.cos(A+this.a)*100;
// simple 3D
var x1=y*crx-this.z*srx;
var zz=y*srx+this.z*crx;
var y1=x*cry-zz*sry;
zz=x*sry+zz*cry;
// 2D projection
var r=400/(400+zz);
x=Math.round(150-x1/r);
y=Math.round(100-y1/r);
var w=Math.round(2+Math.max(4,zz*.07));
// leds lighting
this.alpha(zz);
// html positioning
var css = this.o.style;
css.left=x+"px";
css.top=y+"px";
css.width=css.height=w+"px";
css.zIndex=Math.round(1000+zz);
}
里面嵌雜了一些亮灰度的變化和層級大小的變化就不細說了。大概思路是這樣。不僅3D的處理有創意,時間的組成也有創意,用了一個數組模擬了1~9的數字:
var digits = [
"##### # ########### ########################## ",
"# # # # ## ## # ## ## # ",
"# # # # ## ## # ## ## # # ",
"# # # ##### ################### ########### ",
"# # # # # # ## # ## # # # ",
"# # # # # # ## # ## # # ",
"##### # ########## ########### ########### "
]
"##### # ########### ########################## ",
"# # # # ## ## # ## ## # ",
"# # # # ## ## # ## ## # # ",
"# # # ##### ################### ########### ",
"# # # # # # ## # ## # # # ",
"# # # # # # ## # ## # # ",
"##### # ########## ########### ########### "
]
然后可以把組成數字的#號替換成想要的元素,可以是小圖片,也可以是其他。然后每次循環的時候根據時間的數字讓數組里的#拼湊成當前所需的數字。
function Cdigit(N,d){
// digit prototype
this.O = [];
for(var i=0;i<7;i++){
for(var j=0;j<5;j++){
if(digits[i].charAt(5*d+j)!=" "){
this.O.push(
new CObj((
...
)
);
}
}
}
}
// digit prototype
this.O = [];
for(var i=0;i<7;i++){
for(var j=0;j<5;j++){
if(digits[i].charAt(5*d+j)!=" "){
this.O.push(
new CObj((
...
)
);
}
}
}
}
基本思路就是這樣子,然后在主循環里每次刷新時間的時候移除上一次的元素,重新拼湊就可以了。沒有實例上面的話都是白說,還是給大家看看實例吧。(我只是做了稍微的封裝,核心代碼并沒有改動原作者的),代碼運行有問題的同學請自行拷到本地運行。(使用chrome的需拷到本地運行)
調用方式:
<div id="clock3D"></div>
<script type="text/javascript"><!--
new clock3D({
id: 'clock3D',
direction: 'right' // or 'left'
});
// --></script>
<script type="text/javascript"><!--
new clock3D({
id: 'clock3D',
direction: 'right' // or 'left'
});
// --></script>
【附贈】
另外,附贈一個昨晚上隨便寫的一個仿twitter/新浪微博首頁的 自動無縫滾動效果。
調用方式:
<script type="text/javascript">
new slider({
id:'slider', //必選:滾動ul的id
auto:4 //可選,滾動間隙,默認3秒
})
</script>
new slider({
id:'slider', //必選:滾動ul的id
auto:4 //可選,滾動間隙,默認3秒
})
</script>
全站熱搜