摘要:本文分兩章節,分別講解如何使用這個庫生成可以運行的圣誕樹代碼和的原理。例如圣誕樹,圣誕老人,代碼和圖片都可以自定義。
本文分兩章節,分別講解如何使用js2image這個庫生成可以運行的圣誕樹代碼 和 js2image的原理。
github地址:https://github.com/xinyu198736/js2image ps:求star
在線轉換地址:http://f2e.souche.com/cheniu/js2image.html
效果的話,可以去看一下我們公司的官網(http://www.souche.com ),里面涉及到的js代碼在今天大部分被臨時替換成了圣誕樹,打開每個js代碼即可看到效果。
其實也不神奇,我們使用了自己寫的一個nodejs庫,如果您要實現這樣的效果,只需要按照下面第一章節的方法即可。當然您也可以在線壓縮代碼: http://f2e.souche.com/cheniu/js2image.html
下面分兩章節,分別講解如何使用js2image這個庫 和 js2image這個庫的原理。
js2image使用github地址:https://github.com/xinyu198736/js2image 歡迎送上star或者follow。
js2image主要有兩個比較特殊的特性:
將任意js源碼 壓縮成 用代碼堆砌成圖形的最終代碼。例如圣誕樹,圣誕老人,代碼和圖片都可以自定義。
壓縮后的js代碼格式雖然被破壞,但是仍然可以運行。這個是關鍵點!
壓縮后的示例可以查看這些js(均來自搜車官網)
http://assets.souche.com/assets/js/souche.js souche主腳本
http://assets.souche.com/assets/js/lib/jquery-1.7.1.min.js jquery 1.7.1
http://assets.souche.com/assets/js/lib/mustache.js mustache
使用方式很簡單:
npm install js2image -g;
然后在存在js的文件夾中執行:
js2image -s ./resource/jquery.js
或者針對某個目錄下所有的js執行(慎用),會深度遍歷此目錄里所有的js文件然后壓縮出.xmas.js后綴的結果文件。
js2image -s ./resource/
即可生成一個對應的 **.xmas.js 的文件。
如果要將js2image集成到gulp或者其他nodes項目中,可以使用用模塊的形式:
var Js2Image = require("js2image");//獲取結果的 codeJs2Image.getCode("./resource/jquery.js","./resource/tree.png",{}).then(function(code){ console.log(code); })
更多的信息可以參照github上的文檔。
如果只是要使用這個效果,看到這里就ok啦,下面講解這個庫的原理,有些地方可能比較繞。
js2image實現原理js2image的實現從宏觀來說,大體只有3個要點。
從圖片生成字符畫,這個有現成的庫。
把js代碼分割成一小塊一小塊,盡量小,然后用逐行填充的方式分別替換到上一步生成的字符畫里去。
js代碼中有諸多不能分開的語法,分塊的時候要把這些語法保留在一個塊內。這個是這個庫的難點所在,也是代碼最多最繞的地方。
稍有想法的同學估計看到這里基本已經明白是怎么回事了,下面一一講解這3個要點。
① 從圖片生成2值得字符畫這里用到了一個現成的npm包:image-to-ascii 。這個庫的作用是用指定的字符來還原一個圖像。而我們用這個庫來生成一個用 ?字符和空格 分別表示黑和白的字符畫,然后將字符畫的每一行分解成數組的一個元素,供第二步使用,這就是我們中間生成的一個struct,代碼見 utils/image-to-struct.js
② 分割js源碼成盡量小的小塊。這是非常重要的一步,js代碼具體可以分解成多細的小塊呢?
看下面一段代碼:
!function (e,t ){ ( "objec" +"t") == typeof module && ( "objec"+"t") == typeof module .exports?module. exports=e.document?t(e ,!0):function(e){if(!e. document) throw new Error ( ("jQuer"+"y req"+"uires"+" a wi" +"ndow "+"with "+"a doc"+"ument") ) ; return t (e)}:t(e)}( ("undef"+"ined") !=typeof window ?window:this,function(e,t){var
這是jQuery開始的一段代碼,可以看到,大部分操作符都允許中間插入任意多的空格或者換行,我們正是利用這一特性將js代碼解肢,然后拼接成任意形狀的圖片。
核心代碼其實就是一個正則,我們用這個正則把js源碼解構成一個數組,然后后續根據每行需要的字符數,從這個數組里不斷取片段出來拼接。
//分離代碼,以可分割單位拆分成數組。var lines = hold_code.replace(/([^a-zA-Z_0-9=!|&$])/g," $1 ").split(" "); 有了這個lines數組之后后面就簡單了,根據第一步里生成的struct不斷遍歷從lines抽取代碼填充到struct里即可生成最終的代碼: while(lines.length>0){ //循環往struct里填充代碼 struct.forEach(function(s){ var chars_arr = s.replace(/ +/g," ");//一行有多組分離的***** var r = s; chars_arr.split(/ +/).forEach(function(chars){ if(chars.length == 0){ return; } var char_count = chars.length; //從lines里取出char_count數量的代碼來填充,不一定精準,要確保斷行正確 var l = pickFromLines(lines,char_count); r = r.replace(chars,function(){ return l; }) }) result += r+" " }) }③ 保留不可分割的語法
注意:到了這一步,還很早,你分解出來的代碼是無法運行的,很多不能換行和加空格的代碼都被你分開了,自然會報錯,那如何處理這些情況呢?
這一步,我們做的工作就是:
在執行代碼分拆之前,提取出代碼里所有不可分割的語法,將他們保留在一個對象中,并且在源代碼中用占位符替代這些語法,然后讓占位符參與上個步驟的分離,因為占位符是一個完整的連字符變量,所以不會被分割。在分割完成之后,我們再把這些占位符替換回來即可。
不過,在js中哪些語法必須是連接在一起才能正常運行的呢?
這里總結下:
字符串不可分割 包括雙引號單引號內的內容。
正則表達式絕對不可分割 正則里的轉義很難處理,這是這個算法里的難點。
運算操作符 包括2字符的3字符的 例如 以下兩種
var double_operator = ["==", ">=", "<=", "+=", "-=", "*=", "/=", "%=", "++", "--", "&&", "||", ">>", "<<"] var three_operator = ["===", "!=="]
一些固定語法,可以用正則表達,如下:
var reg_operator = [ { start:"return", reg:/^return[^a-zA-Z_0-1""][a-zA-Z_0-1.]+/ // return 0.1 或者 return function 或者return aaabb }, { start:"return"", reg:/^return".*?"/ // return "d" 或者 return "" }, { start:"return"", reg:/^return".*?"/ // return "d" 或者 return "" }, { start:"throw", reg:/^throw [a-zA-Z_0-1]+?/ //throw new 或者 throw obj } ]
小數點語法,例如 0.01 因為之前我們用點號來分割代碼的,但是這里的點號不能作為分割符使用,需要保留前后數字跟點號在一行
其他語法,例如 value++ 之類的語法,變量和操作符之間不可分割。
那我們如何從源代碼中解析出這些語法,然后做處理呢?
核心代碼均在 utils/keep-line.js 中
核心算法,事實上是通過一個對字符串的遍歷來完成的,然后在遍歷每個字符的時候都會判斷是否進入某個邏輯來跳躍處理。
例如,判斷出當前在雙引號內,則進入字符串提取邏輯,一直到字符串結束的時候再繼續正常的遍歷。
其他操作符和正則表達式的算法也是類似,不過里面很多細節需要處理,例如轉義字符之類的。
有些比較特殊的,例如小數點語法的提取,在判斷到當前字符是點號之后,需要往前和向后循環查找數字,然后把整個語法找出來。
這里不細講,在keep-line.js 這個文件中又一大坨代碼做這個事情的。
④ 字符串解構做到這一步的時候,其實效果已經很不錯了,也可以保證代碼的可運行,但是代碼里有些字符串很長,他們總是會被被保留在一行里,這樣就造成他會影響一些圖案的邊緣的準確性(代碼分離原則是越細越好,就是為這個考慮)。
我們如何處理呢,那就是將字符串解構,以5個為單位將字符串分離成小塊。
這里有兩個比較重要的問題需要處理;
字符串內的轉義字符如何處理,還有一些特殊字符,例如0x01這樣的字符,這些字符不能被分離到不同的字符串里,所以分離的時候要保留這些字符串的完整性。
字符串分離成小字符串,然后用+號拼接起來,不過要注意操作符優先級的問題,所以所有分離后的字符串,都要用括號包起來,讓這個+號的優先級永遠最高。
具體算法見 keep-line.js 中的 splitDoubleQuot (分離雙引號字符串)。
至此,整個應用就完成了,可以順利完成從任意js和圖像生成圖形代碼了。
再說一遍項目開源地址:https://github.com/xinyu198736/js2image 歡迎star,順便follow下樓主就更開心了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/78356.html
摘要:一些有用的一些有用的,包括轉換小箭頭三角形媒體查詢等中文指南是當下最熱門的前端資源模塊化管理和打包工具。 nodejs 入門 nodejs 入門教程,大家可以在 github 上提交錯誤 2016 年最好用的表單驗證庫 SMValidator.js 前端表單驗證工具分享 淺談前端線上部署與運維 說到前端部署,可能大多數前端工程師在工作中都是使用的公司現成的部署系統,與SRE對接、一起完...
摘要:一些有用的一些有用的,包括轉換小箭頭三角形媒體查詢等中文指南是當下最熱門的前端資源模塊化管理和打包工具。 nodejs 入門 nodejs 入門教程,大家可以在 github 上提交錯誤 2016 年最好用的表單驗證庫 SMValidator.js 前端表單驗證工具分享 淺談前端線上部署與運維 說到前端部署,可能大多數前端工程師在工作中都是使用的公司現成的部署系統,與SRE對接、一起完...
摘要:關于節日圣誕節,元旦,看大家情侶在朋友圈里發各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。預覽效果本地下打開很卡,火狐正常圣誕樹早先的時候是圣誕節的時候,看到各種用字符組成圣誕樹的形式,于是自己就去試了下,還是比較簡單的。 關于節日 圣誕節,元旦,看大家(情侶)在朋友圈里發各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。作為單身狗,我們也有自己慶祝節日的方式,今天我們就來實現...
摘要:關于節日圣誕節,元旦,看大家情侶在朋友圈里發各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。預覽效果本地下打開很卡,火狐正常圣誕樹早先的時候是圣誕節的時候,看到各種用字符組成圣誕樹的形式,于是自己就去試了下,還是比較簡單的。 關于節日 圣誕節,元旦,看大家(情侶)在朋友圈里發各種慶祝的或者祝福的話語,甚是感動,然后悄悄拉黑了。作為單身狗,我們也有自己慶祝節日的方式,今天我們就來實現...
閱讀 1572·2021-11-25 09:43
閱讀 2476·2019-08-30 15:54
閱讀 2938·2019-08-30 15:53
閱讀 1087·2019-08-30 15:53
閱讀 747·2019-08-30 15:52
閱讀 2538·2019-08-26 13:36
閱讀 807·2019-08-26 12:16
閱讀 1210·2019-08-26 12:13