純CSS3打造七巧板

2018-06-16 18:25 更新

最近項目上要制作一個七巧板,腦子里瞬間閃現(xiàn),什么。。。七巧板不是小時候玩的嗎。。。

七巧板的由來

先來個科普吧,是我在查資料過程中看到的,感覺很有意思。

宋朝有個叫黃伯思的人,對幾何圖形很有研究,他熱情好客,發(fā)明了一種用6張小桌子組成的“宴幾”——請客吃飯的小桌子。后來有人把它改進為7張桌組成的宴幾,可以根據(jù)吃飯人數(shù)的不同,把桌子拼成不同的形狀,比如3人拼成三角形,4人拼成四方形,6人拼成六方形……這樣用餐時人人方便,氣氛更好。后來,有人把宴幾縮小改變到只有七塊板,用它拼圖,演變成一種玩具。

因為它十分巧妙好玩,所以人們叫它“七巧板”。

今天,在世界上幾乎沒有人不知道七巧板和七巧圖,它在國外被稱為“唐圖”(Tangram),意思是來自中國的拼圖(不是唐代發(fā)明的圖)。

納尼,原來Tangram是咱們中國的,。。。

方案

看完了有趣的東西,該開始正題了,就是無論使用什么技術(shù)給我整出個七巧板來。。。(在前端頁面里)

結(jié)合自己的知識體系,思考了下大概的思路:

  1. Canvas,萬能的Cavans一定可以解決問題,加上之前做過Painter。靈活性+擴展性滿足。
  2. CSS3,每個版子是一個dom元素,然后使用css3搞定。靈活性 擴展性不如canvas。
  3. svg,這個應(yīng)該也可以吧,但自己對這方面的知識匱乏。
  4. 。。。暫時未想出。

考慮到時間成本(太緊了)和其他。。。原因,決定使用css3的方案。

開始想板子使用圖片來做,但多虧自己以前寫過一篇‘用CSS代碼寫出的各種形狀圖形的方法’,里面收錄了使用CSS3制作20種圖形的方法,有興趣的同學(xué)可以看下,查了下可以滿足所需的7種板子的形狀。

用到屬性

  • transform
  • translation

技術(shù)驗證

開始之前先要驗證下,所要用到的CSS3是否可以兼容所要需平臺,這多虧http://caniuse.com/。

因為我要運行在移動端,查了下要用到的css3屬性,在安卓2.3以上都支持,但需加前綴,所以可以放心使用。

編碼實現(xiàn)

首先我們需要一個容器和起個元素用來表示七塊板子。

<div class="wrap">
    <div class="t t1 t11"></div>
    <div class="t t2 t22"></div>
    <div class="t t3 t33"></div>
    <div class="t t4 t44"></div>
    <div class="t t5 t55"></div>
    <div class="t t6 t66"></div>
    <div class="t t7 t77"></div>
</div>

其實我們總共用到的圖形總共有三種,三角形、正方形行和平行四邊形。這在上面提到的文章里面全有,這里涉及到的一點點數(shù)學(xué)的知識,就是這些板子之間是有一定大小關(guān)系的,只需一點點數(shù)學(xué)知識姐可以解決了。

至此板子的表示就不是問題了,其次還需把板子移動到指定位置才可以拼成好看的圖形,這全靠css3的 transform搞定,可以實現(xiàn)平移、縮放、旋轉(zhuǎn)、變形多種操作。

這里我們設(shè)置wap的position為relative。所有板子都為absolute。并設(shè)置top和left為零,這樣初始化時所有的板子都位于左上角,然后將板子的transform-origin設(shè)為左上角,就實現(xiàn)了定位時的好計算,下面是css部分的代碼。

.wrap{
    position: relative;
    width:300px;
    height: 400px;
}
.t{
    position: absolute;
    top:0;
    left:0;
    width: 0;
    height: 0;
    transform-origin:0 0;
}
.t1{
    
    border-top: 212.13203435596425732025330863145px solid red; 
    border-right: 212.13203435596425732025330863145px solid transparent;
    transform: translate(150px, 150px) rotate(-135deg);
}
.t2{
    border-top: 212.13203435596425732025330863145px solid #fdaf17; 
    border-right: 212.13203435596425732025330863145px solid transparent;
    transform: translate(150px, 150px) rotate(135deg);
}
.t3{
    width: 106.06601717798212866012665431573px;
    height: 106.06601717798212866012665431573px;
    background: #c3d946;
    transform: translate(150px,150px) rotate(45deg);
}
.t4{
    border-top: 106.06601717798212866012665431573px solid #00bdd0; 
    border-right: 106.06601717798212866012665431573px solid transparent;
    transform: translate(150px,150px) rotate(-45deg);
}
.t5{
    border-top: 106.06601717798212866012665431573px solid #5dbe79; 
    border-right: 106.06601717798212866012665431573px solid transparent;
    transform: translate(75px,225px) rotate(45deg);
}
.t6{
    width: 150px;
    height: 75px;
    transform: translate(300px) rotate(90deg) skew(45deg);
    background: #ffdd01;
}
.t7{
    border-top: 150px solid #0177bf; 
    border-right: 150px solid transparent;
    transform: translate(300px,300px) rotate(180deg);
}

DEMO

好了,七巧板終于做好了讓我們來看下效果吧。

提高

僅此而已了嗎,當(dāng)然不是,還有很多可考慮的東西,這里的css都是寫死的,靈活性太差,如果用LESS的話(我用的就是less),我們可以設(shè)置一個基本長度變量(less支持變量和數(shù)學(xué)運算哦),然后其他的全部基于這個變量計算,這樣只要改變這個變量,就能輕松改變整個七巧板的大小,可擴展性是不是有很大進步(實際上我就是這么做的,但jsfiddle不支持less語法,所以我就寫了個css版的)。

其實還可以通過css3變化出多種圖形,據(jù)說七巧板的可以拼出的圖形多大幾千種之多。。??炜扉_動你的腦筋來制作吧,做好了記得給博主留個鏈接啊。

進一步的提高就是通過CSS3的transtion,制作動畫,在配合key-frame,可以制作七巧板變形的復(fù)雜動畫,效果美輪美奐啊。

這里只貼一個圖片吧,不提供代碼了。。。

 

參考資料

  • CSS3動畫詳解(http://beiyuu.com/css3-animation/)
  • 騰訊動畫手冊(http://ecd.tencent.com/css3/guide.html)
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號