使用code-printer生成一份炫酷的簡歷

拓跋zhleven發表於2018-04-17

我的個人網站:拓跋的前端客棧瞭解一哈,這裡是原文地址,這裡是專案地址,歡迎star&fork。如果您發現我文章中存在錯誤,請盡情向我吐槽,大家一起學習一起進步φ(>ω<*)


DEMO


最終效果請點選 這裡 ,是不是有點意思?

code-printer.png

原始碼分析


code-printer的最基本的原理是首先搭起一個骨架,然後通過遍歷的方式,一點一點地往骨架裡塞東西。

骨架主要有三塊:

  • <pre id="my-code">: 主要用來展示的HTML程式碼的,帶標籤
  • <style id="style-elem">: 主要填CSS程式碼的,用於把<pre>裡特定的標籤轉換成特定的樣式
  • <div id="script-area">: 主要是填JS程式碼的。但是由於一個字元一個字元往裡面填程式碼會出現大量報錯,因此這部分需要一個段落的JS程式碼全部書寫完畢以後,通過一個命令符'~'來一次性填入。

printCodes

let printCodes = function (message, index, interval) {
    if (index < message.length) {
        $code_pre.scrollTop = $code_pre.scrollHeight;
        printChar(message[index++]);
        return setTimeout((function () {
            return printCodes(message, index, interval);
        }), speed);
    }
};
複製程式碼

這段程式碼的主要作用就是遍歷列印字元,同時每次列印的時候都將滾動條拖到最底下,保證使用者能看到最新的變化。

printChar

let printChar = function (which) {
    let char, formatted_code, prior_block_match, prior_comment_match, script_tag;
    if (which === "`") {
        // 重置為空字串,防止列印出來
        which = "";
        isJs = !isJs;
    }
    if (isJs) {
        if (which === "~" && !openComment) {
            script_tag = createElement("script");
            // two matches based on prior scenario
            prior_comment_match = /(?:\*\/([^\~]*))$/;
            prior_block_match = /([^~]*)$/;
            if (unformatted_code.match(prior_comment_match)) {
                script_tag.innerHTML = unformatted_code.match(prior_comment_match)[0].replace("*/", "") + "\n\n";
            } else {
                script_tag.innerHTML = unformatted_code.match(prior_block_match)[0] + "\n\n";
            }
            $script_area.innerHTML = "";
            $script_area.appendChild(script_tag);
        }
        char = which;
        formatted_code = jsHighlight($code_pre.innerHTML, char);
    } else {
        char = which === "~" ? "" : which;
        $style_elem.innerHTML += char;
        formatted_code = cssHighlight($code_pre.innerHTML, char);
    }
    prevAsterisk = which === "*";
    prevSlash = (which === "/") && !openComment;
    openInteger = which.match(/[0-9]/) || (openInteger && which.match(/[\.\%pxems]/)) ? true : false;
    if (which === '"') {
        openString = !openString;
    }
    unformatted_code += which;
    return $code_pre.innerHTML = formatted_code;
};
複製程式碼

printChar函式是code-printer的核心函式,這個函式會根據當前的程式碼是JS還是CSS,來進行不同的處理。

如何判斷是JS還是CSS程式碼呢?預設設定

let isJs = false;
複製程式碼

也就是預設是CSS,然後以 ` 作為切換符號,每次遇到 ` 就切換一次語言。

當前字元屬於JS時,在沒遇到執行符號 ~ 之前,printChar只是單純的列印格式化後的字元。遇到 ~ 以後,printChar進行了如下操作:

  1. 函式首先通過正則匹配,匹配出之前的JS整段程式碼。
  2. 再呼叫**createElement()**來創造一對<script></script>標籤,用來存放JS程式碼。
  3. 然後將處理過的JS程式碼存入<script></script>標籤內。
  4. 最後通過$script_area.appendChild()的方式將<script></script>及其內部的JS程式碼存入<div id="script-area">中。注意,每次呼叫**$script_area.appendChild()**之前,都要將之前<div id="script-area">清空一遍,防止之前的JS程式碼再執行一次。

當前字元屬於CSS時,每次列印過程,一方面會將未格式化的字串傳入<style id="style-elem">中,用以生成樣式。另一方面會將格式化的程式碼輸出到<pre id="my-code">中,用以展示程式碼。

cssHighlightjsHighlight

這兩個函式十分類似,主要作用就是通過正則匹配,給不同型別的字元兩端封上不同的標籤,用以高亮程式碼。舉個栗子:

if (openInteger && !which.match(/[0-9\.]/) && !openString && !openComment) {
    s = string.replace(/([0-9\.]*)$/, "<em class=\"int\">$1</em>" + which);
}
複製程式碼

這就是一處典型的匹配+替換標籤組合拳。作用是程式碼在以數字結尾時,給數字兩端封上<em class="int"></em>的標籤。

程式碼中還有很多用作標誌位的引數,比如說openInteger,表示這段輸入都是數字。通過對這些控制位進行操作,可以將零散的字元分成一段一段的,方便進行處理。

其他部分就不談了,自己可以看原始碼,我已經加了備註。

使用方法


您可以fork過去直接修改,也可以按照如下步驟操作

git clone https://github.com/tuobaye0711/code-printer.git
複製程式碼

安裝依賴檔案

npm install
複製程式碼

打包檔案

npm start
複製程式碼

起服務

npm run server
複製程式碼

修改配置說明:

resume 檔案存放簡歷或者其他靜態資源

source/code.js 存放需要列印並展示樣式的程式碼(CSS/JS)

source/app.js 是主程式碼,可以修改一些比如說列印速度、高亮色等配置

小結


能在自己網站掛一份帶列印特效的簡歷,想必能讓人眼前一亮吧。這篇文章主要安利了一下我這個名為code-printer的小專案,希望能幫到各位~

相關文章