基于canvas使用粒子拼出你想要的文字

寫在最前

本次分享一下使用canvas實(shí)現(xiàn)粒子效果拼出你想要的文字慢哈。

歡迎關(guān)注我的博客,不定期更新中——

起因

不久之前看到大搜車團(tuán)隊(duì)出品的easy mock產(chǎn)品的界面中有一個(gè)使用粒子拼出“mock so easy”的效果垦缅,感覺非常有意思,就像下面這樣:

image

當(dāng)然了译荞,這個(gè)easy mock的界面中還有粒子匯聚瞪醋、散開忿晕、以及緩動(dòng)等效果,這些在之后的文章中會(huì)不定時(shí)的更新實(shí)現(xiàn)思路银受。

我當(dāng)時(shí)看到這個(gè)效果的時(shí)候是一段單一的英文践盼,不知道源碼能不能支持自己配置需要的字符,故想自己實(shí)現(xiàn)一個(gè)可以配置的版本宾巍。

PS:突然想到作者之前也封裝過一個(gè)輸入一段英文咕幻,輸出一段可表示該字母的“黑魔法代碼”:效果就像下面這樣:

_20170825233827

緣由也是網(wǎng)上有人用這種黑魔法代碼拼出了單詞,但是并不是“可配置”的顶霞,也就不能想要啥就是啥肄程,故才有了作者的一版封裝實(shí)現(xiàn),文章如下:(相關(guān)代碼在原文中提及

效果圖

image

你可以任意輸入你能想到的字符选浑,只要打得進(jìn)去:)

示例:


image
image

核心問題:怎么確定粒子的擺放位置蓝厌?

emmmm作者目前想到的辦法是:降低像素?cái)?shù)

來看下這個(gè)“非常粗略”的示意圖:

image

這是當(dāng)我在頁面輸入“an"之后展示的隱藏的canvas的截圖,我將其放入到了ps中并放大鲜侥,我們可以清晰地看到該圖是由一個(gè)個(gè)很小的像素點(diǎn)通過每個(gè)像素點(diǎn)不同的顏色最終繪制出來的。而我們要做的就是用更少的“像素點(diǎn)”來繪制同樣的內(nèi)容诸典。也就是原來100??100像素的圖描函,我們?nèi)绻?5??25來表示,那么每個(gè)像素點(diǎn)就會(huì)粗很多狐粱,同時(shí)粒度也會(huì)更加寬泛舀寓,之后我們?nèi)绻麑⑾袼攸c(diǎn)變?yōu)閳A形,最后我們就可以得到如文章開頭提到的那樣肌蜻,由一個(gè)個(gè)粒子“拼”出了效果互墓。

總的來說就是通過將輸入的信息轉(zhuǎn)化為圖片后,讀取圖片的像素信息蒋搜,同時(shí)粗略的將圖片分塊篡撵,遍歷每塊區(qū)域中的像素點(diǎn)判斷該塊是否需要畫一個(gè)粒子判莉。屆時(shí)所有區(qū)域遍歷完畢就可以用比像素點(diǎn)少很多的粒子來大體表示每一個(gè)輸入的字符。那么具體實(shí)現(xiàn)過程如下:

  • 將輸入的文字轉(zhuǎn)化為圖片插入到一個(gè)隱藏的canvas中
  • 按一定比例如(4像素??4像素)分割該canvas圖像育谬,形成一個(gè)擁有x * y個(gè)格子的區(qū)域券盅,每個(gè)格子中擁有一定像素?cái)?shù)(4??4 = 16)
  • 讀取該canvas中的圖片像素?cái)?shù)據(jù)
  • 獲取在每一個(gè)格子中擁有除灰度顏色的像素?cái)?shù)(白底或者黑底屬于插入到canvas中的圖片的背景)
  • 當(dāng)一個(gè)格子中有顏色的像素?cái)?shù)占所有像素的一定程度后,認(rèn)定該區(qū)域?qū)儆谳斎胱址囊徊糠痔盘矗瑒t在該區(qū)域畫一個(gè)粒子锰镀,否則不畫

實(shí)現(xiàn)過程

文字轉(zhuǎn)化為圖片插入canvas

function loadCanvas(value) {
    var fontSize = 100,
        width = calWordWidth(value, fontSize), 
        canvas = document.createElement('canvas')
    canvas.id = 'b_canvas'
    canvas.width = width 
    canvas.height = fontSize
    var ctx = canvas.getContext('2d')
    ctx.font = fontSize + "px Microsoft YaHei"
    ctx.fillStyle = "orange"
    ctx.fillText(value, 0, fontSize / 5 * 4) //輕微調(diào)整繪制字符位置
    getImage(canvas, ctx) //導(dǎo)出為圖片再導(dǎo)入到canvas獲取圖像數(shù)據(jù)
}
function getImage(canvas, ctx) {
    var image = new Image()
    image.src = canvas.toDataURL("image/jpeg") //canvas導(dǎo)出
    image.onload = function() {
        ... 
    }
}

降低像素?cái)?shù)

var imageData = ctx.getImageData(0, 0, this.width, this.height)
var dataLength = imageData.data.length
var diff = 4 //按4??4劃分區(qū)域,可自行改變嘗試
var newCanvas = document.getElementById('canvas')
var newCtx = newCanvas.getContext('2d')
for (var j = 0; j < this.height; j += diff) { //height為canvas高
    for (var i = 0; i < this.width; i += diff) {//width為canvas寬
        var colorNum = 0
        for (var k = 0; k < diff * diff; k++) {
            var row = k % diff
            var col = ~~(k / diff)
            let r = imageData.data[((j + col) * this.width + i + row) * 4 + 0]
            let g = imageData.data[((j + col) * this.width + i + row) * 4 + 1]
            let b = imageData.data[((j + col) * this.width + i + row) * 4 + 2]
            if (r < 10 && g < 10 && b < 10) colorNum++ 
            //如果滿足此條件說明當(dāng)前為背景色黑色(canvas轉(zhuǎn)出來的圖片背景并不是純黑的
        }
        if (colorNum < diff * diff / 3 * 2) {
        //黑色背景占比小于一定程度說明此處應(yīng)該畫粒子咖刃,占比度可自行調(diào)整
            var option = {
                x: i,
                y: j,
                radius: 6,
                color: '#fff'
            }
            var newBubble = new Bubble(option)
            newBubble.draw(newCtx) //畫粒子
        } 
    }
}

其他canvas相關(guān)文章

最后

源代碼見:https://github.com/Aaaaaaaty/Blog/blob/master/canvas/canvasImitateWord/main.js

本次只實(shí)現(xiàn)了可配置拼出字符的功能泳炉,粒子動(dòng)態(tài)上沒加入特效,其他效果實(shí)現(xiàn)思路之后可能會(huì)不定時(shí)更新——

慣例po作者的博客嚎杨,不定時(shí)更新中——
有問題歡迎在issues下交流花鹅。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市磕潮,隨后出現(xiàn)的幾起案子翠胰,更是在濱河造成了極大的恐慌,老刑警劉巖自脯,帶你破解...
    沈念sama閱讀 217,509評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件之景,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡膏潮,警方通過查閱死者的電腦和手機(jī)锻狗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來焕参,“玉大人轻纪,你說我怎么就攤上這事〉祝” “怎么了刻帚?”我有些...
    開封第一講書人閱讀 163,875評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)涩嚣。 經(jīng)常有香客問我崇众,道長(zhǎng),這世上最難降的妖魔是什么航厚? 我笑而不...
    開封第一講書人閱讀 58,441評(píng)論 1 293
  • 正文 為了忘掉前任顷歌,我火速辦了婚禮,結(jié)果婚禮上幔睬,老公的妹妹穿的比我還像新娘眯漩。我一直安慰自己,他們只是感情好麻顶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評(píng)論 6 392
  • 文/花漫 我一把揭開白布赦抖。 她就那樣靜靜地躺著舱卡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪摹芙。 梳的紋絲不亂的頭發(fā)上灼狰,一...
    開封第一講書人閱讀 51,365評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音浮禾,去河邊找鬼交胚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛盈电,可吹牛的內(nèi)容都是我干的蝴簇。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼匆帚,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼熬词!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吸重,我...
    開封第一講書人閱讀 39,062評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤互拾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后嚎幸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體颜矿,經(jīng)...
    沈念sama閱讀 45,500評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評(píng)論 3 335
  • 正文 我和宋清朗相戀三年嫉晶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骑疆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,834評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡替废,死狀恐怖箍铭,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情椎镣,我是刑警寧澤诈火,帶...
    沈念sama閱讀 35,559評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站状答,受9級(jí)特大地震影響冷守,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜剪况,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評(píng)論 3 328
  • 文/蒙蒙 一教沾、第九天 我趴在偏房一處隱蔽的房頂上張望蒲跨。 院中可真熱鬧译断,春花似錦、人聲如沸或悲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至翎蹈,卻和暖如春淮菠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荤堪。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工合陵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人澄阳。 一個(gè)月前我還...
    沈念sama閱讀 47,958評(píng)論 2 370
  • 正文 我出身青樓拥知,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親碎赢。 傳聞我的和親對(duì)象是個(gè)殘疾皇子低剔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,110評(píng)論 25 707
  • 0x00 簡(jiǎn)介驗(yàn)證碼作為一種輔助安全手段在Web安全中有著特殊的地位,驗(yàn)證碼安全和web應(yīng)用中的眾多漏洞相比似乎微...
    windgod閱讀 2,279評(píng)論 0 19
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程肮塞,因...
    小菜c閱讀 6,409評(píng)論 0 17
  • 之后的比賽進(jìn)行得挺順利襟齿。自行車賽習(xí)以被視一項(xiàng)精密的工作,大腦迅速對(duì)路面枕赵、坡度和風(fēng)速做出測(cè)評(píng)和判斷猜欺,身體依據(jù)它的承受...
    一沭閱讀 216評(píng)論 0 0
  • (草稿) 目錄 第二章 維護(hù)服務(wù)的延續(xù)性 在正常工作條件下,一個(gè)MongoDB的部署將根據(jù)系統(tǒng)的性能和功能目標(biāo)來運(yùn)...
    Tommy_MFG閱讀 725評(píng)論 0 0