利用JS將圖標(biāo)字體渲染為圖片的方法詳解
前言
在軟件開(kāi)發(fā)中肯定要用到圖標(biāo),比如下圖的 Groove 音樂(lè)中就用到了許多圖標(biāo)。一種獲取這些圖標(biāo)的方法是把 Groove 音樂(lè)截個(gè)圖,然后熟練地開(kāi)啟 Photoshop,開(kāi)始摳圖。這種方式很遜,效率也很低(雖然我剛開(kāi)始就是這么干的)。
如果打開(kāi) C:/Program File/WindowsApps(需要修改權(quán)限才能進(jìn)入),可以發(fā)現(xiàn)幾個(gè)名字里帶 ZuneMusic
的文件夾,其中的某一個(gè)文件夾中會(huì)有字體文件 SegMVR2.ttf。這是一個(gè)圖標(biāo)字體文件,雙擊安裝之后,打開(kāi) Windows 自帶的字符映射表應(yīng)用,將字體換為 Segoe MVR MDL2 Assets,可以看到里面的字符其實(shí)就是圖標(biāo)。其實(shí)可以用 Metro Studio 將這些字體導(dǎo)出為 png、svg 等格式的圖片,但是 Metro Studio 導(dǎo)出的字符看起來(lái)很細(xì),也無(wú)法分別控制上下和左右的內(nèi)邊距,所以這里改用 Javascript 操作 canvas 繪制圖標(biāo),然后導(dǎo)出為 png。
實(shí)現(xiàn)方式
在 CodePen 上已經(jīng)有人給出了將 Microsoft 開(kāi)源的 Fabric UI Icon 渲染為 png 圖片的 demo,效果很不錯(cuò)。閱讀源代碼之后可以發(fā)現(xiàn),他在 getFontIconCharacter()
先創(chuàng)建了一個(gè)臨時(shí)的元素,根據(jù)想要的圖標(biāo)的名字設(shè)置元素的 className,獲取::before
偽元素的 content 中字符的 Unicode,接著在 drawIcon()
中使用 context.fillText()
方法繪制字符,最后 canvas.toDataURL()
就能將 canvas 的內(nèi)容轉(zhuǎn)換為 base64 格式的圖片。
可以看到,對(duì)于自定義的的字體,我們只需知道字符的 Unicode,就能實(shí)現(xiàn)導(dǎo)出功能。
html
html 和 coepen 中的幾乎完全一樣,唯一不同的地方就是將 font-class
換成了 font-unicode
,因?yàn)槲覀冎挥凶址?unicode。
<html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="index.css" rel="external nofollow" > <title>iconfont to png</title> </head> <body> <div class="ms-Grid" dir="ltr"> <h1 class="ms-font-su">Render Office Fabric UI Icons into Canvas</h1> <p>This is a simple tool to render an icon from the <a class="ms-fontColor-blueLight" rel="external nofollow" >Office Fabric UI icon font</a> into an HTML <code><canvas></code> with a background color. Right-click and save the image to use it.</p> <div class="ms-Grid-row"> <div class="ms-Grid-col ms-sm12 ms-lg6"> <h2 class="ms-font-xxl">Icon/Canvas Specifications</h2> <form id="form"> <div class="ms-Grid"> <div class="ms-Grid-row"> <div class="ms-Grid-col ms-md6"> <label for="font-unicode">Icon unicode</label> <input type="text" name="fontClass" id="font-unicode" placeholder="e.g. ms-Icon ms-Icon-Warning" value="E768"> </div> <div class="ms-Grid-col ms-md6"> <label for="font-size">Font size (px)</label> <input type="number" step="1" min="1" name="fontSize" id="font-size" placeholder="e.g. 60" value="56"> </div> </div> <div class="ms-Grid-row"> <div class="ms-Grid-col ms-md6"> <label for="image-width">Image width (px)</label> <input type="number" step="1" min="0" name="imageWidth" id="image-width" placeholder="e.g. 80" value="92"> </div> <div class="ms-Grid-col ms-md6"> <label for="image-height">Image height (px)</label> <input type="number" step="1" min="0" name="imageHeight" id="image-height" placeholder="e.g. 80" value="92"> </div> </div> <div class="ms-Grid-row"> <div class="ms-Grid-col ms-md6"> <label for="left-offset">Left offset</label> <input type="number" step="1" name="leftOffset" id="left-offset" placeholder="e.g. 40" value="46"> </div> <div class="ms-Grid-col ms-md6"> <label for="top-offset">Top offset</label> <input type="number" step="1" name="topOffset" id="top-offset" placeholder="e.g. 40" value="46"> </div> </div> <div class="ms-Grid-row"> <div class="ms-Grid-col ms-md6"> <label for="bg-color">Background color</label> <input type="text" name="bgColor" id="bg-color" placeholder="e.g. #777777" value=#777777> </div> <div class="ms-Grid-col ms-md6"> <label for="icon-color">Icon color</label> <input type="text" name="iconColor" id="icon-color" placeholder="e.g. #FFFFFF" value=#FFFFFF> </div> </div> <div class="ms-Grid-row"> <div class="ms-Grid-col ms-sm12"> <label><input type="checkbox" checked name="shape" id="shape"> Use a circle as the background fill</label> </div> </div> </div> <input type="submit" class="ms-button ms-bgColor-themeDark ms-bgColor-themeDarker--hover ms-fontColor-white" value="Render Font Icon"> <p>If the icon does not render immediately, wait a few seconds and press the <b>Render</b> button again; the webfont may still be loading.</p> </form> </div> <div class="ms-Grid-col ms-sm12 ms-lg6"> <h2 class="ms-font-xxl">Result</h2> <div class="canvas-container"> <canvas id="canvas" width="92" height="92"></canvas> </div> <p><a id="download-link" class="ms-button ms-bgColor-themeDark ms-bgColor-themeDarker--hover ms-fontColor-white" target="_blank"><i class="ms-Icon ms-Icon--Download"></i> Download the image</a></p> <label for="dataURL">Data URL</label> <input id="dataURL" type="text"> </div> </div> </div> </body> <script src="index.js"></script> </html>
css
與 codepen 中的代碼相比,這里只是多了一個(gè) @font-face
聲明要使用的字體。圖標(biāo)的下載地址,提取碼:1234
@import url(https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/11.0.0/css/fabric.min.css); @font-face { font-family: 'Segoe MVR MDL2 Assets'; src: url('SegoeMVRMDL2Assets.ttf') format('truetype'); font-weight: normal; font-style: normal; } html { box-sizing: border-box; } *, *:before, *:after { box-sizing: inherit; } body { font-family: "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; background-color: #0078d4; color: white; } .ms-Grid { margin: 0 auto; padding: 0 16px; max-width: 1280px; } .ms-Grid-row { margin-left: -16px; margin-right: -16px; } .ms-Grid-col { padding: 0 16px; } label { display: block; margin-bottom: 0.5em; } input { border: none; display: block; margin-bottom: 2em; padding: 5px; width: 100%; font-size: 16px; } input[type="checkbox"] { display: inline-block; padding: 0; width: auto; } input[type="button"], input[type="submit"], .ms-button { cursor: pointer; display: inline-block; padding: 0.75em 2em; text-decoration: none; width: auto; } .ms-button .ms-Icon { transform: translateY(2px); } .canvas-container { background-color: white; display: inline-block; margin-bottom: 1em; padding: 10px; width: auto; } #canvas { color: black; font-family: FabricMDL2Icons; }
js
這里我們主要修改了 getFontIconCharacter()
函數(shù),直接根據(jù)輸入框的內(nèi)容返回字符的 Unicode。
const form = document.getElementById("form"); const canvas = document.getElementById("canvas"); const context = canvas.getContext("2d"); const download = document.getElementById("download-link"); const dataURL = document.getElementById("dataURL"); const fontFamily = "Segoe MVR MDL2 Assets"; function getFontIconCharacter(unicode) { return String.fromCharCode(parseInt(unicode, 16)); } function drawCircle() { var centerX = canvas.width / 2; var centerY = canvas.height / 2; var radius = canvas.width / 2; context.beginPath(); context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false); context.fillStyle = document.getElementById("bg-color").value || "#777777"; context.fill(); } function drawRect() { context.fillStyle = document.getElementById("bg-color").value || "#777777"; context.fillRect(0, 0, canvas.width, canvas.height); } function drawIcon() { canvas.width = parseInt(document.getElementById("image-width").value, 10) || 92; canvas.height = parseInt(document.getElementById("image-height").value, 10) || 92; context.clearRect(0, 0, canvas.width, canvas.height); if (document.getElementById("shape").checked) { drawCircle(); } else { drawRect(); } context.fillStyle = document.getElementById("icon-color").value || "#FFFFFF"; let fontUnicode = document.getElementById("font-unicode").value, fontSize = document.getElementById("font-size").value || 280, topOffset = document.getElementById("top-offset").value || 210, leftOffset = document.getElementById("left-offset").value || 210; context.font = `${fontSize}px ${fontFamily}`; context.textAlign = "center"; context.textBaseline = "middle"; context.fillText(getFontIconCharacter(fontUnicode), parseInt(leftOffset, 10), parseInt(topOffset, 10)); dataURL.value = canvas.toDataURL(); } window.addEventListener('load', function () { drawIcon(); }); document.addEventListener('DOMContentLoaded', function () { context.font = "10px " + fontFamily; context.fillText("...", 0, 0); }); form.addEventListener("submit", function (event) { event.preventDefault(); drawIcon(); }); download.addEventListener("click", function (event) { if (typeof this.download !== "undefined") { this.href = canvas.toDataURL(); this.download = `${document.getElementById("font-unicode").value}.png`; } else { event.preventDefault(); alert("Your browser does not support downloading a canvas image. Please right-click on the image to save it."); } }); dataURL.addEventListener("focus", function (event) { dataURL.select(); });
效果
打開(kāi) html 之后如下圖所示,只需修改 Icon unicode
,再點(diǎn)擊 Render Font Icon
按鈕,就能在右側(cè)的畫(huà)布中看到圖標(biāo),點(diǎn)擊 Download the image
按鈕就能下載圖標(biāo)了。
到此這篇關(guān)于利用JS將圖標(biāo)字體渲染為圖片的方法詳解的文章就介紹到這了,更多相關(guān)JS圖標(biāo)字體渲染內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript實(shí)現(xiàn)瀑布流圖片效果
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)瀑布流圖片效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06前端高頻面試題之JS中堆和棧的區(qū)別和瀏覽器的垃圾回收機(jī)制
本文給大家分享前端高頻面試題JS中堆和棧的區(qū)別和瀏覽器的垃圾回收機(jī)制,本文分文別類(lèi)給大家介紹了棧(stack)和堆(heap)的區(qū)別基本類(lèi)型和引用類(lèi)型的相關(guān)知識(shí),瀏覽器垃圾回收機(jī)制包括基本概念給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-10-10

分享一個(gè)自己寫(xiě)的table表格排序js插件(高效簡(jiǎn)潔)

es5 類(lèi)與es6中class的區(qū)別小結(jié)

Javascript中克隆一個(gè)數(shù)組的實(shí)現(xiàn)代碼

JavaScript實(shí)現(xiàn)精美個(gè)性導(dǎo)航欄筋斗云效果

微信小程序中網(wǎng)絡(luò)請(qǐng)求緩存的解決方法