基于JavaScript實(shí)現(xiàn)年份數(shù)字拼圖效果
背景
時光荏苒,2022年又要收尾了,公司的年會是不是都安排上了?(順便問一嘴,您陽了嗎?)
前幾天看到一個年會抽獎系統(tǒng),功能十分的強(qiáng)大,其中有一個年份數(shù)字的拼圖效果深深的吸引了哥,決定深入探索一番。先看下具體的效果,圖中有個2022的年份數(shù)字。
實(shí)現(xiàn)原理
從效果能看出,實(shí)際就是將相應(yīng)卡片設(shè)置為高亮顏色拼成數(shù)字,實(shí)現(xiàn)原理大致是:
- 設(shè)計好數(shù)字(0-9)在橫向和縱向占據(jù)的卡片列數(shù)和行數(shù),比如上圖中的橫向?yàn)?列,縱向?yàn)?行;
- 針對每個數(shù)字(0-9)的形狀,獲取亮色卡片位置的坐標(biāo),從而得到每個數(shù)字的形狀坐標(biāo)數(shù)組;
- 根據(jù)每個數(shù)字的形狀坐標(biāo)、要展示數(shù)字的順序計算出具體的位置,將對應(yīng)坐標(biāo)卡片設(shè)置為亮色就可以了;
具體實(shí)現(xiàn)
1. 創(chuàng)建背景卡片
拼圖展示的數(shù)字是當(dāng)前的年份(2022),也就是4位數(shù)字。根據(jù)數(shù)字在橫行占3列,縱向占5行,數(shù)字前后間隔1列,為了美觀數(shù)字區(qū)域上下左右邊界要空出一行或者一列。所以整個背景卡片的列數(shù)和行數(shù)就有了:
行數(shù) = 5 + 1 + 1 = 7;
列數(shù) = 3 * 4 + 3(間隔) + 1 + 1 = 17;
const rowCount = 7; const colCount = 17; // 創(chuàng)建卡片 const createCard = () => { const frag = document.createDocumentFragment(); for (let i = 0; i < rowCount; i++) { for (let j = 0; j < colCount; j++) { const item = document.createElement('div'); item.className = "item"; frag.appendChild(item); } } document.querySelector('.container').appendChild(frag); }
2. 設(shè)置數(shù)字形狀坐標(biāo)
這個其實(shí)就是根據(jù)每個數(shù)字的形狀,記錄下形狀路徑上的每個點(diǎn)的坐標(biāo)。規(guī)則是從上到下,從左到右,找到所有路徑上的點(diǎn)。0-9的形狀坐標(biāo)數(shù)組如代碼所示,可以比照著上文中的圖片,確認(rèn)下數(shù)字的形狀坐標(biāo)。
注意:如果想設(shè)計其他的數(shù)字字體展示形式,可以根據(jù)具體形狀收集路徑點(diǎn)坐標(biāo)。
// 0-9數(shù)字的坐標(biāo)形狀 const NUMBER_MATRIX = [ [ // 0 [0, 0], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [2, 2], [0, 3], [2, 3], [0, 4], [1, 4], [2, 4] ], [ // 1 [1, 0], [0, 1], [1, 1], [1, 2], [1, 3], [0, 4], [1, 4], [2, 4] ], [ // 2 [0, 0], [1, 0], [2, 0], [2, 1], [0, 2], [1, 2], [2, 2], [0, 3], [0, 4], [1, 4], [2, 4] ], [ // 3 [0, 0], [1, 0], [2, 0], [2, 1], [0, 2], [1, 2], [2, 2], [2, 3], [0, 4], [1, 4], [2, 4] ], [ // 4 [0, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1, 2], [2, 2], [2, 3], [2, 4] ], [ // 5 [0, 0], [1, 0], [2, 0], [0, 1], [0, 2], [1, 2], [2, 2], [2, 3], [0, 4], [1, 4], [2, 4] ], [ // 6 [0, 0], [1, 0], [2, 0], [0, 1], [0, 2], [1, 2], [2, 2], [0, 3], [2, 3], [0, 4], [1, 4], [2, 4] ], [ // 7 [0, 0], [1, 0], [2, 0], [2, 1], [2, 2], [2, 3], [2, 4] ], [ // 8 [0, 0], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1, 2], [2, 2], [0, 3], [2, 3], [0, 4], [1, 4], [2, 4] ], [ // 9 [0, 0], [1, 0], [2, 0], [0, 1], [2, 1], [0, 2], [1, 2], [2, 2], [2, 3], [0, 4], [1, 4], [2, 4] ] ];
3. 數(shù)字拼圖
第二步中,給出的數(shù)字形狀坐標(biāo)實(shí)際是單個數(shù)字展示時的坐標(biāo),如果多個數(shù)字并排展示,需要對每個數(shù)字的坐標(biāo)進(jìn)行換算,換算規(guī)則主要有2條
- 因?yàn)閿?shù)字是橫向排列的,所以每增加一個數(shù)字,x坐標(biāo)都要增加4列(包含一列數(shù)字間隔)
- 由于數(shù)字展示區(qū)域周邊上下左右都空了一行或者一列,所以x坐標(biāo)和y坐標(biāo)的開始位置,都是從(1,1)開始的。
// 根據(jù)數(shù)字形狀、當(dāng)前年份等信息,篩選出需要設(shè)置為亮色的卡片位置 const getHighlight = () => { // 獲取當(dāng)前年份 let year = new Date().getFullYear() + ""; let step = 4, xoffset = 1, yoffset = 1, highlight = []; year.split('').forEach(n => { highlight = highlight.concat( NUMBER_MATRIX[n].map(item => { return `${item[0] + xoffset}-${item[1] + yoffset}`; }) ); xoffset += step; }); return highlight; }
最后highlight
返回的其實(shí)就是點(diǎn)坐標(biāo)字符串的數(shù)組,類似['1-1', '2-1']
這種。
然后就可以根據(jù)返回的點(diǎn)坐標(biāo)數(shù)組進(jìn)行繪制拼圖,其實(shí)就是將對應(yīng)坐標(biāo)的卡片添加高亮的樣式類名
const createHighLight = async (cards, hightLight) => { for (let i = 0; i < hightLight.length; i++) { const [col, row] = hightLight[i].split('-'); const index = Math.floor(row) * colCount + Math.floor(col); cards[index].className = 'item highlight' } }
最終實(shí)現(xiàn)效果如下圖所示:
延伸
上文中只是實(shí)現(xiàn)了靜態(tài)數(shù)字的拼圖展示效果,如果能夠讓數(shù)字動起來呢?比如實(shí)現(xiàn)一個寫字效果、或者倒計時變動數(shù)字效果,這些會讓拼圖更加的酷炫。我們下面實(shí)現(xiàn)一個寫字效果
其實(shí),原理很簡單,只需要在繪制數(shù)字拼圖卡片時,將每個坐標(biāo)點(diǎn)的繪制,改成異步串行繪制就行了
const createHighLight = async (cards, hightLight) => { for (let i = 0; i < hightLight.length; i++) { await new Promise((resolve, reject) => setTimeout(resolve, 100)); const [col, row] = hightLight[i].split('-'); const index = Math.floor(row) * colCount + Math.floor(col); cards[index].className = 'item highlight' } // 繪制結(jié)束后,循環(huán)繪制 await new Promise((resolve, reject) => setTimeout(resolve, 100)); drawData(); }
具體實(shí)現(xiàn)效果如下所示:
注意:數(shù)字的繪制效果可能和我們正常的書寫筆畫順序不一致,這是因?yàn)樽鴺?biāo)點(diǎn)是按照從上到下,從左到右的順序收集的,其實(shí)可以調(diào)整坐標(biāo)點(diǎn)順序,讓它符合書寫筆畫的順序,就可以看到正常的書寫效果了,自己嘗試吧哈
總結(jié)
本文主要分析了數(shù)字拼圖效果的實(shí)現(xiàn)原理,實(shí)現(xiàn)核心就是要先確定每個數(shù)字的形狀坐標(biāo),然后根據(jù)形狀坐標(biāo)去繪制高亮卡片。最后在靜態(tài)數(shù)字拼圖效果的基礎(chǔ)之上,借助異步串行,實(shí)現(xiàn)了手寫字的效果,其他效果可以自己在此基礎(chǔ)上自己嘗試。
以上就是基于JavaScript實(shí)現(xiàn)年份數(shù)字拼圖效果的詳細(xì)內(nèi)容,更多關(guān)于JavaScript年份數(shù)字拼圖的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
BootStrap fileinput.js文件上傳組件實(shí)例代碼
這篇文章主要介紹了BootStrap fileinput.js文件上傳組件實(shí)例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02js實(shí)現(xiàn)StringBuffer的簡單實(shí)例
下面小編就為大家?guī)硪黄猨s實(shí)現(xiàn)StringBuffer的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09學(xué)習(xí)JavaScript一定要知道的3個小技巧
這篇文章主要給大家分享的是學(xué)習(xí)JavaScript一定要知道的3個小技巧,通常在 Angular 或 React 項(xiàng)目中,code review 時看到一些老式的 JavaScript 代碼,就會將開發(fā)人員歸類為初學(xué)者,下面我們就來一起看看初學(xué)者需要知道的三個小技巧,需要的朋友可以參考一下2021-12-12基于JavaScript實(shí)現(xiàn)年份數(shù)字拼圖效果
時光荏苒,2022年又要收尾了,公司的年會是不是都安排上了?前幾天看到一個年會抽獎系統(tǒng),功能十分的強(qiáng)大,其中有一個年份數(shù)字的拼圖效果深深的吸引了哥,決定用JS實(shí)現(xiàn)一下該效果,需要的可以參考一下2022-12-12JavaScript中concat復(fù)制數(shù)組方法淺析
在本篇文章里小編給大家總結(jié)了關(guān)于JavaScript中concat復(fù)制數(shù)組方法知識點(diǎn),有需要的朋友們可以學(xué)習(xí)下。2019-01-01