最近項目上要制作一個七巧板,腦子里瞬間閃現,什么。。。七巧板不是小時候玩的嗎。。。
七巧板的由來
先來個科普吧,是我在查資料過程中看到的,感覺很有意思。
宋朝有個叫黃伯思的人,對幾何圖形很有研究,他熱情好客,發明了一種用6張小桌子組成的“宴幾”——請客吃飯的小桌子。后來有人把它改進為7張桌組成的宴幾,可以根據吃飯人數的不同,把桌子拼成不同的形狀,比如3人拼成三角形,4人拼成四方形,6人拼成六方形……這樣用餐時人人方便,氣氛更好。后來,有人把宴幾縮小改變到只有七塊板,用它拼圖,演變成一種玩具。
因為它十分巧妙好玩,所以人們叫它“七巧板”。
今天,在世界上幾乎沒有人不知道七巧板和七巧圖,它在國外被稱為“唐圖”(Tangram),意思是來自中國的拼圖(不是唐代發明的圖)。
納尼,原來Tangram是咱們中國的,。。。
方案
看完了有趣的東西,該開始正題了,就是無論使用什么技術給我整出個七巧板來。。。(在前端頁面里)
結合自己的知識體系,思考了下大概的思路:
- Canvas,萬能的Cavans一定可以解決問題,加上之前做過Painter。靈活性+擴展性滿足。
- CSS3,每個版子是一個dom元素,然后使用css3搞定。靈活性 擴展性不如canvas。
- svg,這個應該也可以吧,但自己對這方面的知識匱乏。
- 。。。暫時未想出。
考慮到時間成本(太緊了)和其他。。。原因,決定使用css3的方案。
開始想板子使用圖片來做,但多虧自己以前寫過一篇‘用CSS代碼寫出的各種形狀圖形的方法’,里面收錄了使用CSS3制作20種圖形的方法,有興趣的同學可以看下,查了下可以滿足所需的7種板子的形狀。
用到屬性
- transform
- translation
技術驗證
開始之前先要驗證下,所要用到的CSS3是否可以兼容所要需平台,這多虧http://caniuse.com/。
因為我要運行在移動端,查了下要用到的css3屬性,在安卓2.3以上都支持,但需加前綴,所以可以放心使用。
編碼實現
首先我們需要一個容器和起個元素用來表示七塊板子。
<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>
其實我們總共用到的圖形總共有三種,三角形、正方形行和平行四邊形。這在上面提到的文章里面全有,這里涉及到的一點點數學的知識,就是這些板子之間是有一定大小關系的,只需一點點數學知識姐可以解決了。
至此板子的表示就不是問題了,其次還需把板子移動到指定位置才可以拼成好看的圖形,這全靠css3的 transform搞定,可以實現平移、縮放、旋轉、變形多種操作。
這里我們設置wap的position為relative。所有板子都為absolute。並設置top和left為零,這樣初始化時所有的板子都位於左上角,然后將板子的transform-origin設為左上角,就實現了定位時的好計算,下面是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
好了,七巧板終於做好了讓我們來看下效果吧。
留個jsfiddle的代碼,博客園不能欠入,只能留個鏈接了http://jsfiddle.net/yanhaijing/3tf8ac6q/1/
提高
僅此而已了嗎,當然不是,還有很多可考慮的東西,這里的css都是寫死的,靈活性太差,如果用LESS的話(我用的就是less),我們可以設置一個基本長度變量(less支持變量和數學運算哦),然后其他的全部基於這個變量計算,這樣只要改變這個變量,就能輕松改變整個七巧板的大小,可擴展性是不是有很大進步(實際上我就是這么做的,但jsfiddle不支持less語法,所以我就寫了個css版的)。
其實還可以通過css3變化出多種圖形,據說七巧板的可以拼出的圖形多大幾千種之多。。。快快開動你的腦筋來制作吧,做好了記得給博主留個鏈接啊。
進一步的提高就是通過CSS3的transtion,制作動畫,在配合key-frame,可以制作七巧板變形的復雜動畫,效果美輪美奐啊。
這里只貼一個圖片吧,不提供代碼了。。。
參考資料
-
CSS3動畫詳解(http://beiyuu.com/css3-animation/)
- 騰訊動畫手冊(http://ecd.tencent.com/css3/guide.html)