用 JavaScript 玩轉 Emoji 表情圖示原來這麼簡單

栏目: JavaScript · 发布时间: 6年前

内容简介:這陣子花了一些時間研究 Unicode 萬國碼,看著看著就研究起 Emoji 表情圖示來了。過程中還跑去看了首先,先來講怎樣在文件中使用 Emoji 表情圖示。這過程說簡單很簡單,要說複雜其實也有點複雜。基本上,你有 4 種方式可以在文件中輸出 Emoji 表情圖示:其實每一個 Emoji 就是一個 Unicode 字元,就跟一般文字一樣,所以你大可將 Emoji 字元放在任意字串中,完全沒有問題!
用 JavaScript 玩轉 Emoji 表情圖示原來這麼簡單

這陣子花了一些時間研究 Unicode 萬國碼,看著看著就研究起 Emoji 表情圖示來了。過程中還跑去看了 Unicode® Emoji 官方規格,要是沒有先建立對 Unicode 的理解,要完全看懂 Emoji 的來龍去脈是不太容易的。研究的過程中,還發現了一些有趣的冷知識,欲知詳情請繼續看下去! :wink:

首先,先來講怎樣在文件中使用 Emoji 表情圖示。這過程說簡單很簡單,要說複雜其實也有點複雜。基本上,你有 4 種方式可以在文件中輸出 Emoji 表情圖示:

  1. 直接輸入 Emoji 字元
  2. 將 12 個按鍵符號轉換為 Emoji 圖示
  3. 在現有的 Emoji 字元後方加入菲茨派屈克修飾符 (膚色深度)
  4. 透過 零寬連字(ZWJ) 將多個 Emoji 連接在一起

直接輸出 Emoji 字元

其實每一個 Emoji 就是一個 Unicode 字元,就跟一般文字一樣,所以你大可將 Emoji 字元放在任意字串中,完全沒有問題!

任何支援 Unicode (UTF-8, UTF-16, UTF-32) 的文件,都可以完全合法的放入 Emoji 字元,使用者的作業系統 (包含行動裝置) 只要有安裝含有 Emoji 的字型 (大多已內建),就可以正確顯示 Emoji 表情圖示。

  1. 直接上網搜尋並複製貼上

    大部分 Emoji 字元都可以上網找到,直接透過複製/貼上就可以立即使用,相當便利:

  2. 使用 Windows 10 的 Emoji 輸入法視窗

    從 Windows 10 周年更新內建了一個 Win+. 快速鍵,可以叫出 Emoji 鍵盤來用,非常方便!

    用 JavaScript 玩轉 Emoji 表情圖示原來這麼簡單

  3. 透過 HTML Entities 語法輸出到 HTML 文件中

    &what: Discover Unicode & HTML Character Entities

  4. 透過 JavaScript 的 Unicode escape sequences 寫在字串中

    在寫 JavaScript 字串的時候,直接將 Emoji 字元寫入字串是可以的,例如:

    var a = ':information_desk_person::ok_hand::bamboo::heart_eyes:';

    JavaScript 有個 Unicode escape sequences 表示法,可以用在字串中,假設 Unicode 的字碼為 U+1F197 ( :ok: ),那麼 JavaScript 有兩種表示法:

    1. ES6 (ES2015) 可以使用 UTF-32 編碼

      var st = '\u{01F197}';
    2. ES5 僅支援 UTF-16 編碼,而大部分 Emoji 字元被定義在 UTF-16 以外的字碼區域 (UTF-32),你必須把一個 UTF-32 字碼 (Code point) 轉換成兩個 UTF-16 字碼才行,透過 surrogate pair 的方式來表達一個 UTF-32 字元,所以 U+1F197 只能用以下語法來寫:

      '\uD83C\uDD97'

      你可以透過 ES6 (ES2015) 提供的 API 來計算出 ES5 可以使用的兩個 UTF-16 字碼:

      var hb = '\u{01F197}'[0].codePointAt(0).toString(16); // \ud83c
      var lb = '\u{01F197}'[1].codePointAt(0).toString(16); // \udd97

      也可以透過 以下函式 將 UTF-32 字碼轉換為兩個 UTF-16 的表示法:

      function toUTF16(codePoint) {
          var TEN_BITS = parseInt('1111111111', 2);
          function u(codeUnit) {
              return '\\u'+codeUnit.toString(16).toUpperCase();
          }
      
          if (codePoint <= 0xFFFF) {
              return u(codePoint);
          }
          codePoint -= 0x10000;
      
          // Shift right to get to most significant 10 bits
          var leadingSurrogate = 0xD800 | (codePoint >> 10);
      
          // Mask to get least significant 10 bits
          var trailingSurrogate = 0xDC00 | (codePoint & TEN_BITS);
      
          return u(leadingSurrogate) + u(trailingSurrogate);
      }

      使用範例如下:

      toUTF16(0x1F197)

將 12 個按鍵符號轉換為 Emoji 圖示

Emoji 定義了 12 個按鍵符號 ( 0123456789#* ),只要加入一組 2 個字元的 Emoji Keycap Sequence ( '\uFE0F\u20E3' ) 就可以把文字自動轉成 Emoji 圖示。

var keycap = '\uFE0F\u20E3';
console.assert(':zero:' === '0' + keycap);
console.assert(':one:' === '1' + keycap);
console.assert(':two:' === '2' + keycap);
console.assert(':three:' === '3' + keycap);
console.assert(':four:' === '4' + keycap);
console.assert(':five:' === '5' + keycap);
console.assert(':six:' === '6' + keycap);
console.assert(':seven:' === '7' + keycap);
console.assert(':eight:' === '8' + keycap);
console.assert(':nine:' === '9' + keycap);
console.assert(':hash:' === '#' + keycap);
console.assert('*️⃣' === '*' + keycap);

在現有的 Emoji 字元後方加入菲茨派屈克修飾符 (膚色深度)

在 Emoji 表情圖示的 Unicode 規格中,有個特別的 EMOJI MODIFIER FITZPATRICK (菲茨派屈克修飾符) 可用,這個 修飾符 (Modifier) 也是一個合法的 Unicode 字元,必須緊接著在 Emoji 字元後面出現。

目前全世界人類的 膚色分級 ( Fitzpatrick scale ) 是 1975 年由一位叫做 Thomas B. Fitzpatrick 的人訂定出來的,他當初定義了 6 種膚色等級。(Type 1 ~ Type 6)。研究 Emoji 竟然還能學習到這種冷知識,哈!

在 Emoji 表情符號中,總共定義了 5 個字元,用來代表 Emoji 的顏色深度。為什麼不是 6 個呢?因為 Type 1 與 Type 2 顏色太相近了,在電腦螢幕上不容易區分,索性就合併了。這五個字元分別是:

字元名稱 Code point 字元 UTF-16 (使用 JavaScript 字串) UTF-8
FITZ-1-2 U+1F3FB 0xD83C 0xDFFB ( '\uD83C\uDFFB' ) 0xF0 0x9F 0x8F 0xBB
FITZ-3 U+1F3FC 0xD83C 0xDFFC ( '\uD83C\uDFFC' ) 0xF0 0x9F 0x8F 0xBC
FITZ-4 U+1F3FD 0xD83C 0xDFFD ( '\uD83C\uDFFD' ) 0xF0 0x9F 0x8F 0xBD
FITZ-5 U+1F3FE 0xD83C 0xDFFE ( '\uD83C\uDFFE' ) 0xF0 0x9F 0x8F 0xBE
FITZ-6 U+1F3FF 0xD83C 0xDFFF ( '\uD83C\uDFFF' ) 0xF0 0x9F 0x8F 0xBF

以下是不同的 Emoji 在加上菲茨派屈克修飾符之後的比較表:

Code point Default FITZ-1-2 FITZ-3 FITZ-4 FITZ-5 FITZ-6
U+1F9D2: 小孩
U+1F466: 男孩 :boy: :boy|type_1_2: :boy|type_3: :boy|type_4: :boy|type_5: :boy|type_6:
U+1F467: 女孩 :girl: :girl|type_1_2: :girl|type_3: :girl|type_4: :girl|type_5: :girl|type_6:
U+1F9D1: 大人
U+1F468: 男人 :man: :man|type_1_2: :man|type_3: :man|type_4: :man|type_5: :man|type_6:
U+1F469: 女人 :woman: :woman|type_1_2: :woman|type_3: :woman|type_4: :woman|type_5: :woman|type_6:

我簡單透過 JavaScript 示範將 (大人) 膚色改成 (黑人) 的程式寫法:

var adult = '  ';

var fitz6 = '\uD83C\uDFFF';

var black = adult + fitz6; // 只要透過簡單的字串相加就可以完成!

console.log(black);

請注意:不是所有 Emoji 都能加上膚色,只有跟「人類」有關的 Emoji 才能這樣用,例如 Emoji 中有出現臉、手、腳、身體的,都可以這樣用。目前 Unicode v11.0 定義了 106 個 Emoji 圖示是可以加上 EMOJI MODIFIER FITZPATRICK 字元的,完整清單可以參考 這裡

透過零寬連字(ZWJ)將多個 Emoji 連接在一起

這個就真的很酷了,我以前一直很納悶有些 Emoji 到底是怎樣產生的,深入研究後才發現,原來 Emoji 這麼好玩,除了有幾千種不同的 Emoji 之外,還可以將其組合成各種千變萬化的玩法。

Unicode 中有個特殊的 零寬連字(ZWJ) 符號 ( ‍U+200D ),這基本上是一個合法的 Unicode 文字,只是他預設是看不見的 零寬 (Zero Width) 字元。這個字元通常用在排版用途,不過卻被 Emoji 拿來用了。你可以透過這個字元,任意串接兩個不同的 Emoji 字元,然後就可以創造出新的、不存在 Emoji 清單中的全新 Emoji 字元。

這邊我做個非常簡單的示範,我直接把 :man: (男人) 與 :woman: (女人) 串加起來,但中間卡一個 ZWJ 字元,這個 Emoji 就會自動變成 :man:‍:woman: (一男一女):

var man = ':man:';
var women = ':woman:';

var zwj = '\u200D';

console.log(man + zwj + women);

如果希望顯示一家三口全家福的 Emoji 圖示,可以直接把 :man: (男人) 、 :woman: (女人) 與 (男孩) 串加起來,但不同的字元中間都要卡一個 ZWJ 字元,此時 Emoji 就會自動變成 :man:‍:woman:‍:boy: (一男一女外加一個男孩):

var man = ':man:';
var women = ':woman:';
var child = ':boy:';

var zwj = '\u200D';

console.log(man + zwj + women + zwj + child);

相同的邏輯,如果你想顯示一家三口全家福,但小孩是個女兒的話,的 Emoji 圖示,可以直接把 :man: (男人) 、 :woman: (女人) 與 :girl: (女孩) 串加起來,不同的字元中間依然要卡一個 ZWJ 字元,此時 Emoji 就會自動變成 :man:‍:woman:‍:girl: (一男一女外加一個女孩):

var man = ':man:';
var women = ':woman:';
var child = ':girl:';

var zwj = '\u200D';

console.log(man + zwj + women + zwj + child);

如果有兩個小孩呢?沒問題! :man: + :woman: + :boy: + :girl: = :man:‍:woman:‍:boy:‍:girl:

var all = [':man:', ':woman:', ':boy:', ':girl:'];
var zwj = '\u200D';
console.log(all.join(zwj));

基本上,你要加幾個人都可以!而且在這兩性平權的時代,兩個爸爸、兩個媽媽也不奇怪,想親手試試 Emoji 怎樣設定嗎?

:man:‍:man:‍:boy:‍:girl:

var all = [':man:', ':man:', ':boy:', ':girl:'];
var zwj = '\u200D';
console.log(all.join(zwj));

:woman:‍:woman:‍:boy:‍:girl:

var all = [':woman:', ':woman:', ':boy:', ':girl:'];
var zwj = '\u200D';
console.log(all.join(zwj));

喔!爸爸是巴西人、媽媽是黑人?沒問題!I got you back! :man|type_1_2:‍:woman|type_6:‍:boy:‍:girl:

var fitz1 = '\uD83C\uDFFB';
var fitz6 = '\uD83C\uDFFF';

var all = [':man:'+fitz1, ':woman:'+fitz6, ':boy:', ':girl:'];
var zwj = '\u200D';
console.log(all.join(zwj));

你是一個白人、女性、而且是一位學生?:woman|type_1_2:‍:mortar_board:

var fitz1 = '\uD83C\uDFFB';

var all = [':woman:'+fitz1, ':mortar_board:']; // 加上學士帽 Emoji 即可!
var zwj = '\u200D';
console.log(all.join(zwj));

套用 ZWJ 字元的 Emoji 完整清單可以參考 這裡

注意事項

雖然 Unicode 明確定義了許多 Emoji 的字碼,但還是有很多平台會自己定義額外的 Emoji 圖示,因此不是所有的 Emoji 大家都看的到,這點必須特別注意。

有些沒有被定義在 Emoji 的 Unicode 符號,在特定作業系統平台也會特別做成 彩色版 的 Emoji 圖示,這部分各位就不用過於擔心,就算在其他平台看不到這個圖示,還是會顯示「文字版」的符號樣式,但也就沒有顏色了。

Unicode 標準定義的 Emoji 清單,可以從 Full Emoji List, Unicode v11.0 取得!

相關連結


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

嵌入式系统开发之道

嵌入式系统开发之道

2011-12 / 69.00元

《嵌入式系统开发之道:菜鸟成长日志与项目经理的私房菜》用平易朴实的语言,以一个完整的嵌入式系统的开发流程为架构,通过一位“菜鸟”工程师与项目经理的诙谐对话,故事性地带出嵌入式系统概念及开发要素,并点出要成为一名称职的嵌入式系统工程师,在实际工作中所必须具备的各项知识及技能。 《嵌入式系统开发之道:菜鸟成长日志与项目经理的私房菜》可以分为三大部分:第1、3、4、17、18、19章和附录D为嵌入......一起来看看 《嵌入式系统开发之道》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

URL 编码/解码
URL 编码/解码

URL 编码/解码