前言

在软件开发中肯定要用到图标,比如下图的 Groove 音乐中就用到了许多图标。一种获取这些图标的方法是把 Groove 音乐截个图,然后熟练地开启 Photoshop,开始抠图。这种方式很逊,效率也很低(虽然我刚开始就是这么干的)。

如果打开 C:/Program Files/WindowsApps(需要修改权限才能进入),可以发现几个名字里带 ZuneMusic 的文件夹,其中的某一个文件夹中会有字体文件 SegMVR2.ttf。这是一个图标字体文件,双击安装之后,打开 Windows 自带的字符映射表应用,将字体换为 Segoe MVR MDL2 Assets,可以看到里面的字符其实就是图标。其实可以用 Metro Studio 将这些字体导出为 png、svg 等格式的图片,但是 Metro Studio 导出的字符看起来很细,也无法分别控制上下和左右的内边距,所以这里改用 Javascript 操作 canvas 绘制图标,然后导出为 png。

实现方式

在 CodePen 上已经有人给出了将 Microsoft 开源的 Fabric UI Icon 渲染为 png 图片的 demo,效果很不错。阅读源代码之后可以发现,他在 getFontIconCharacter() 先创建了一个临时的元素,根据想要的图标的名字设置元素的 className,获取::before 伪元素的 content 中字符的 Unicode,接着在 drawIcon() 中使用 context.fillText() 方法绘制字符,最后 canvas.toDataURL() 就能将 canvas 的内容转换为 base64 格式的图片。

可以看到,对于自定义的的字体,我们只需知道字符的 Unicode,就能实现导出功能。

html

html 和 coepen 中的几乎完全一样,唯一不同的地方就是将 font-class 换成了 font-unicode,因为我们只有字符的 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">
<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"
href="https://developer.microsoft.com/en-us/fabric#/styles/icons">Office Fabric UI icon font</a> into an
HTML <code>&lt;canvas&gt;</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 中的代码相比,这里只是多了一个 @font-face 声明要使用的字体。图标的下载地址在 蓝奏云,密码为 abcr

@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() 函数,直接根据输入框的内容返回字符的 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();
});

效果

打开 html 之后如下图所示,只需修改 Icon unicode,再点击 Render Font Icon 按钮,就能在右侧的画布中看到图标,点击 Download the image 按钮就能下载图标了。

如何使用 Javascript 将图标字体渲染为图片的更多相关文章

  1. 老爷车IE8如何兼容图标字体

    前言 首先这个标题再详细的说就是如何解决font-face在IE8下间歇性出现图标字体渲染失败的解决方案. 如果你还不知道什么是图标字体,可以先阅读:链接1,链接2,链接3 先看在IE8下的问题: 而 ...

  2. (转载)app ico图标字体制作

    图标字体化浅谈   在做手机端Web App项目中,经常会遇到小图标在手机上显示比较模糊的问题,经过实践发现了一种比较好的解决方案,图标字体化.在微社区项目中,有很多小的Icon(图标),如分享.回复 ...

  3. css与jquery、图标字体

    *)还能这样选择 header #search input[type="text"] *)按钮常用颜色:#008cBA(字母大小写没有区别) *)清除浮动后,text-align没 ...

  4. iconfont 图标字体

    iconfont 技术的主要是将图标转化为字体来减少应用体积.如需在项目中使用iconfont技术,图标矢量图一开始都应合并转化为字体库.   优点: 减小体积,字体文件比图片要小 图标保真缩放,解决 ...

  5. IconVault – 创建自定义图标字体的神器推荐

    图标字体简单来说就是外观呈现为图标的字体,同时具有矢量图形的特征,在不同的设备上使用图标的时候就不用加载不同尺寸的图片文件,能够减少 HTTP 请求数,提高页面加载速度. IconVault 这款在线 ...

  6. ExtJs5_使用图标字体来美化按钮

    sencha 的例子中,有使用图标字体来美化按钮的例子,这个用起来又方便风格又统一,例如下图: 上面图标字体的使用方法也很简单,只要下载Font Awesome的css和图标文件,放到项目里就可以了. ...

  7. 5、手把手教你Extjs5(五)使用图标字体来美化按钮)

    sencha 的例子中,有使用图标字体来美化按钮的例子,这个用起来又方便风格又统一,例如下图: 上面图标字体的使用方法也很简单,只要下载Font Awesome的css和图标文件,放到项目里就可以了. ...

  8. django2用模板代码图标字体丢失报404 cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff

    以前开发网站,不是用php就是用c#或java写后端,跟后端繁重麻烦的代码相比,前端的html+css+JavaScript简直就简单的不算技术,相比之下,工作量也不大. 但如果用django框架,使 ...

  9. JavaScript 如何工作:渲染引擎和性能优化技巧

    翻译自:How JavaScript works: the rendering engine and tips to optimize its performance 这是探索 JavaScript ...

随机推荐

  1. Java 死锁以及如何避免?

    Java 中的死锁是一种编程情况,其中两个或多个线程被永久阻塞,Java 死锁情况 出现至少两个线程和两个或更多资源. Java 发生死锁的根本原因是:在申请锁时发生了交叉闭环申请.

  2. 使用Servlet编写增删改查

    第一步创建一个表 1 create database liyongzhendb default character set utf8 collate utf8_bin; 2 3 CREATE TABL ...

  3. centos下安装配置maven

    下载maven安装包 wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven ...

  4. C++ - main()和_tmain(int argc, _TCHAR* argv[]) 的详细区别

    一些程序中会发现主函数不是int main(),而是int _tmain(),而且头文件也不是<iostream>而是<stdafx.h>. 首先,这个_tmain()是为了支 ...

  5. 微信小程序中涉及虚拟产品购买,ios暂不支持的相关整理意见

    这个东西呢也不能怪微信小程序,属实苹果搞的事情,那怎么小程序相关内容去通过审核呢? 首先我们要搞清楚哪些属于虚拟商品:如某某书币,某某会员,或者是提前编辑好的网课,文档等都属虚拟商品购买,简言之就是没 ...

  6. 将word文件转为excel文件

    有些word文件里的数据是有顺序或者规律,想转成表格的形式,下面就以我要转的word为例. 我的word文件是这样的 1.word转txt(文本文件) 文件--->另存为--->路径--- ...

  7. js判断输入数字是否是整数,金额、数字

    function isIntNum(strNum){//js判断输入数字是否是整数 仅供学习思想 var strCheckNum = strNum+""; if(strCheckN ...

  8. Struts bean:define标签用法

    bean:define:有三个用途 一是定义新字符串常量: <bean:define id="foo" value="This is a new String&qu ...

  9. 利用css3实现3D轮播图

    动画实现主要利用了z-index将层级关系改变,从而实现了焦点图的效果:css3属性 transform rotate 来实现图片的动画效果 .transition实现过度动画! * { margin ...

  10. 解决“WARNINGThe remote SSH server rejected X11 forwarding request.“警告

    使用xshell连接服务器时,出现了"WARNING! The remote SSH server rejected X11 forwarding request.",意思是&qu ...