CSS3 製作魔方 玩轉魔方

2022-05-24 20:33:10 字數 3591 閱讀 7904

由於魔方格的位置與轉動的路徑相關,僅依靠 rotatex,rotatey,rotatez 單個的值無法直接表明其定位。如下圖,第乙個魔方格進行了特殊化處理。

當使用路徑 rotatey(90)->rotatey(90)->rotatex(90)->rotatey(-90)  來旋轉這個特殊魔方格時,y 最終是 90度,x 是90 度,按路徑旋轉的結果如下圖。

它並不等於

y  90度,x 90 度的旋轉結果:rotatey(90)->rotatex(90)

不能直接表示,就換一種方式。可以根據旋轉的方向重算魔方格在魔方中的座標並重繪魔方格,而旋轉動畫效果可以採用逆向90度重繪再 transition 回來的方式,詳見後述。

縱觀魔方,實現各層的旋轉它應該開放什麼介面呢?進行旋轉需要指定的資料是什麼呢?這便形成了功能的頂層描述與介面需求:指定x,y,z軸向、給定第幾層、規定轉向完成90度的旋轉。

於是在 magicbox 類中可以增加方法:功能介面名稱使用 rotate,其引數為 軸向(axis)、層(level)、轉向(turn)。

其中:旋轉的層所包含的具體魔方格,對於頂層而言,則只需要對旋轉要求通知到位即可,而通知的內容為軸向(axis)、轉向(turn),以及魔方階數(dimension)。

有此描述,頂層 rotate 方法非常簡單,功能為找出指定的層進行通知即可:

/** magicbox.rotate 旋轉

* axis 軸向

* level 層

* turn 轉向

**/this.rotate = function(axis, level, turn)}};

軸向有x,y,z,但每層的旋轉只涉及到兩個軸向,有(x,y)、(y,z)、(x,z),儘管魔方格看上去很多的,但座標的轉換卻都遵循非常簡單的變換規律,以4階的 (x,y) 座標轉換為例,如下,黃色為同乙個座標旋轉變換的值:

很容易得出規律,旋轉前後的座標中,總有乙個是相同的,另兩個的和是固定的,而且剛好為魔方階數減1。

假設旋轉前後座標分別為(x1,y1)、(x2,y2),則:

往左旋轉,座標變換規律為:x2 = y1, y2 = 3 - x1,這其中的 3 為魔方階數減1。

往右旋轉,座標變換規律為:x2 = 3 - y1, y2 = x1。

這恰是:我成為了你,而你是我的補

於是有了以下轉換過程:

/** 座標轉換

* axis 軸向

* turn 轉向

* dimension 階數

**/this.transcoordinate = function(axis, turn, dimension) else

} else if(axis == 'y') else

} else if(axis == 'z') else } }

在魔方格里,通過版面(block)在旋轉方向上的變換達到旋轉的效果,方式為根據旋轉方向同向移動方向即可。

/** 將各 block 調整位置,重繪魔方格

* axis 軸向

* turn 轉向

**/this.redrawblocks = function(axis, turn) }}

調整好的魔方格,逆向旋轉90度,則外觀保持跟旋轉前一樣,這就有了進行動畫的基礎,動畫的實質就是欺騙眼睛。

然後,利用 transition 讓其過濾到不旋轉的(即調整好的)外觀即可達到效果。這樣的好處是,魔方格不論在什麼位置,每次相關的旋轉角度僅是逆向的 90 度,問題區域性化時,事情就變得簡單

// 先停止動畫效果,逆向 90 度,此時外觀跟旋轉前一致

this.element.style["transition"] = "";

var rotatedegs = new object();

rotatedegs[axis] = (turn == 'left' ? -90 : 90);

this.element.style["transform"] = this.formattransform(rotatedegs);

// 旋轉原點旋轉的層都需要以魔方的中心點旋轉

// 旋轉原點是以元素自身來計算的,因所有魔方格都是從(0,0,0)平衡的,因此計算結果都一樣

var centerx = this.blocksize * dimension / 2;

var centery = this.blocksize * dimension / 2;

var centerz = -this.blocksize * dimension / 2;

this.element.style["transformorigin"] = centerx + "px " + centery + "px " + centerz + "px";

// 這樣才能觸發動畫

settimeout(function(obj);

}(this), 1);

// 以下為transfrom 屬性格式化的乙個方法,這個屬性值太長了又是旋轉平移多組合

// 格式化 transform 屬性

// css3 把旋轉與平移混一起(真不好用)

this.formattransform = function (rotatedegs)

return rotatepart + " translate3d(" + (this.x * this.blocksize) + "px," + (this.y * this.blocksize) + "px,-" + (this.z * this.blocksize) + "px) ";

}

有了這個旋轉的方法,通過給定一組旋轉引數序列,可以讓魔方自動運轉,並且自動復原。

function onload(){

//* 魔方繪製示例

var magicbox = new magicbox(5, 50);

magicbox.drawin( document.queryselector(".wrap") );

var rotates = genrotateactions(5, 10);

for(var i=0; i效果如下:

尋找共性向上抽象,形成統一的處理模式能夠讓處理模型變得簡單。

本文例項,支援動態建立多階的魔方,但對引數缺少邊界檢查,同時對旋轉的是否結束未作標記或判斷,感興趣的朋友可以進一步完善它。

本例項**發布在 

CSS3 製作魔方 相關立體樣式

最好的實踐,就是給定乙個實踐的目標去實踐。目標 利用 css3 的一些特性,繪製乙個魔方,要可以玩轉的那種,即上下左右每一層都可以獨立旋轉。效果如下 螢幕的起點座標是 0,0,0 往右遞增為 x 方向,使用 left 屬性表示,往下走,遞增為 y 方向,使用 top 屬性表示。而 3d 場景中 z ...

CSS3簡單魔方動畫效果

在魔方效果中我們主要用到的是animation動畫,transition 過渡 transform 變換 首先我們在body裡面下我們需要的標籤元素 這裡也可以用div寫 li li li li li li ul body 寫好後我們在style標籤裡寫我們所需要的的樣式 先給ul設定我們所需要的樣...

3D製作魔方

從10號開始做這個東西,是一邊學習一邊做的,學了dxut框架 拾取技術 dx提供的 別人寫的演算法和用外接球模擬 先說一下還要改進的地方 1 無論先點哪乙個方塊,都按照程式設定的去轉 2 光照問題 轉了之後變暗 3 記憶體洩露 這個找了很久都沒找到,我估計是dxut框架的,汗 設計思路 1 渲染 設...