前言

在软件开发中肯定要用到图标,比如下图的 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 中,受检查异常 和 不受检查异常的区别?

    受检查异常编译器在编译期间检查.对于这种异常,方法强制处理或者通过 throws 子句声明.其中一种情况是 Exception 的子类但不是 RuntimeException 的子类.非受检查是 Ru ...

  2. 数据库遇到的问题之“datetime设置默认为CURRENT_TIMESTAMP时报无效默认问题”和“时区问题”

    一.问题1 问题描述: 今日加入创建时间和修改时间,并设置为默认CURRENT_TIMESTAMP时,出现错误,指向sql中的datetime字段,查了一下,发现是版本问题 立马查询自己的MySQL版 ...

  3. 记MyBaits-Plus 实现菜单的无限层关系

    Mybatis-Plus父子菜单 首先来看一下实现的效果 pojo层 @Data @TableName("platform_role") public class Role imp ...

  4. JQuery基础修炼-样式篇

    jQuery对象转化成DOM对象 jQuery库本质上还是JavaScript代码,它只是对JavaScript语言进行包装处理,为了是提供更好更方便快捷的DOM处理与开发常见中经常使用的功能.我们可 ...

  5. jq easyui数据网络的分页过程

    第一次写技术方面的文章,有点忐忑,总怕自己讲的不对误导别人.但是万事总有个开头,有不足错误之处,请各位读者老爷指出. 言归正传,最近刚进新公司,上头要求我先熟悉熟悉easyui这个组件库.在涉及到da ...

  6. 【Android开发】【数据库】Realm For Android

    目录 1.Realm简介 2.环境配置 3.初始化Realm 4.创建实体 5.增 6.删 7.改 8.查 9.异步操作 10.数据库数据更新监听 11.json转对象,插入数据库 12.Demo地址 ...

  7. nginx之配置文件公用抽取

    nginx之配置文件公用抽取 因为某些原因,需要同时部署同一应用两个不同分支的代码,而配置文件存在较大重复,因此有此篇. 最近构建的过程中遇到了一些跟nginx配置相关的问题,记录下. 简单说下构建的 ...

  8. BootstrapBlazor 使用模板创建项目

    原文连接:https://www.cnblogs.com/ysmc/p/16101157.html BootstrapBlazor 官网地址:https://www.blazor.zone Boots ...

  9. Python入门-面向对象-特殊方法

    调用拦截功能 class Message: def send(self,info): print("消息发送:",info) class Me: def __getattribut ...

  10. Redis 未授权访问漏洞【原理扫描】修复方法

    漏洞类型 主机漏洞 漏洞名称/检查项 Redis 配置不当可直接导致服务器被控制[原理扫描] 漏洞名称/检查项 Redis 未授权访问漏洞[原理扫描] 加固建议 防止这个漏洞需要修复以下三处问题 第一 ...