mirror of
https://github.com/2234839/web-font.git
synced 2025-04-06 05:25:44 +08:00
🔥 新增动态生成接口
This commit is contained in:
parent
2e764d73e1
commit
f40884d2ba
@ -57,7 +57,13 @@ ui 需要展现一些特定的字体,但直接引入字体包又过大,于
|
|||||||
|
|
||||||
### 动态生成字体
|
### 动态生成字体
|
||||||
|
|
||||||
http://127.0.0.1:3000/generate_fonts_dynamically/font/1584688387272/优设标题黑.ttf
|

|
||||||
|
|
||||||
|
#### 请注意
|
||||||
|
|
||||||
|
只支持生成 .ttf .eot .woff .svg 这几种格式
|
||||||
|
|
||||||
|
如果 text 参数为空将会返回整个字体包
|
||||||
|
|
||||||
## 写项目时遇到的问题
|
## 写项目时遇到的问题
|
||||||
|
|
||||||
|
BIN
doc_img/api/generate_fonts_dynamically.jpg
Normal file
BIN
doc_img/api/generate_fonts_dynamically.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
@ -11,6 +11,7 @@ import { AppService } from './app.service';
|
|||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { promises as fs } from 'fs';
|
import { promises as fs } from 'fs';
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
|
import { Stream } from 'stream';
|
||||||
@Controller()
|
@Controller()
|
||||||
export class AppController {
|
export class AppController {
|
||||||
constructor(private readonly appService: AppService) {}
|
constructor(private readonly appService: AppService) {}
|
||||||
@ -30,13 +31,28 @@ export class AppController {
|
|||||||
|
|
||||||
/** 压缩字体 */
|
/** 压缩字体 */
|
||||||
@Get('generate_fonts_dynamically*')
|
@Get('generate_fonts_dynamically*')
|
||||||
generate_fonts_dynamically(
|
async generate_fonts_dynamically(
|
||||||
@Req() req:Request,
|
@Req() req: Request,
|
||||||
|
@Res() res,
|
||||||
@Query('text') text: string,
|
@Query('text') text: string,
|
||||||
@Query('font') font: string,
|
@Query('font') font: string,
|
||||||
@Query('temp') temp: string,
|
@Query('temp') temp: string,
|
||||||
) {
|
) {
|
||||||
const format=req.url.match(/\.(.*)\?/)[1]
|
console.time()
|
||||||
return this.appService.generate_fonts_dynamically(text, font,temp,format);
|
const type = req.url.match(/\.(.*)\?/)[1];
|
||||||
|
const file = await this.appService.generate_fonts_dynamically(
|
||||||
|
text,
|
||||||
|
font,
|
||||||
|
temp,
|
||||||
|
type,
|
||||||
|
);
|
||||||
|
res.set({
|
||||||
|
'Content-Type': `font/${type}`,
|
||||||
|
});
|
||||||
|
const bufferStream = new Stream.PassThrough();
|
||||||
|
bufferStream.end(file);
|
||||||
|
bufferStream.pipe(res);
|
||||||
|
console.timeEnd()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ import { Injectable } from '@nestjs/common';
|
|||||||
import Fontmin from 'fontmin';
|
import Fontmin from 'fontmin';
|
||||||
const { zip } = require('zip-a-folder');
|
const { zip } = require('zip-a-folder');
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import crypto from 'crypto';
|
||||||
import { config } from './config';
|
import { config } from './config';
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService {
|
||||||
font_min(text: string, font: string) {
|
font_min(text: string, font: string) {
|
||||||
@ -47,12 +49,83 @@ export class AppService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_fonts_dynamically(
|
async generate_fonts_dynamically(
|
||||||
text: string,
|
text: string,
|
||||||
font: string,
|
font: string,
|
||||||
temp: string,
|
temp: string,
|
||||||
format: string,
|
type: string,
|
||||||
) {
|
) {
|
||||||
return 11;
|
const hash = crypto.createHash('md5');
|
||||||
|
hash.update(`${type}${font}${text}`);
|
||||||
|
const hash_str = hash.digest('hex');
|
||||||
|
const srcPath = `./src/font/${font}.ttf`; // 字体源文件
|
||||||
|
const outPath = `asset/dynamically/${hash_str}`;
|
||||||
|
const destPath = `./${outPath}`; // 输出路径
|
||||||
|
|
||||||
|
const full_path = join(__dirname, '../../', destPath, `${font}.${type}`);
|
||||||
|
/** 需要持久化 */
|
||||||
|
if (temp !== 'true') {
|
||||||
|
try {
|
||||||
|
return await fs.readFile(full_path);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`开始生成 ${full_path}`,error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 初始化
|
||||||
|
const fontmin = new Fontmin()
|
||||||
|
.src(srcPath) // 输入配置
|
||||||
|
.use(
|
||||||
|
Fontmin.glyph({
|
||||||
|
text, // 所需文字
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ('eot' === type) {
|
||||||
|
fontmin.use(Fontmin.ttf2eot()); // eot 转换插件
|
||||||
|
}
|
||||||
|
if ('woff' === type) {
|
||||||
|
fontmin.use(Fontmin.ttf2woff()); // eot 转换插件
|
||||||
|
}
|
||||||
|
if ('svg' === type) {
|
||||||
|
fontmin.use(Fontmin.ttf2svg()); // eot 转换插件
|
||||||
|
}
|
||||||
|
/** 缓存数据 */
|
||||||
|
if (temp !== 'true') {
|
||||||
|
fontmin.dest(destPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 执行
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fontmin.run(async function(err, files, stream) {
|
||||||
|
if (err) {
|
||||||
|
// 异常捕捉
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
const buffer = files.filter(f =>
|
||||||
|
/** 筛选需要的类型 */
|
||||||
|
(f.history[f.history.length - 1] as string).endsWith(type),
|
||||||
|
)[0]._contents;
|
||||||
|
resolve(buffer); // 成功
|
||||||
|
/** 存个日志 */
|
||||||
|
if (temp !== 'true') {
|
||||||
|
const content_path = join(
|
||||||
|
__dirname,
|
||||||
|
'../../',
|
||||||
|
destPath,
|
||||||
|
`content.txt`,
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
await fs.appendFile(
|
||||||
|
content_path,
|
||||||
|
`type:${type}\nfont:${font}\ntext:${text}`,
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`写 ${content_path} 失败`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user