Graph
图像相关的包
pdf2image ---> pdf 转为图片
将 pdf 转为图片的库
import { fromPath } from "pdf2pic";
const options = {
density: 100,
saveFilename: "untitled",
savePath: "./images",
format: "png",
width: 600,
height: 600
};
const convert = fromPath("/path/to/pdf/sample.pdf", options);
const pageToConvertAsImage = 1;
convert(pageToConvertAsImage, { responseType: "image" })
.then((resolve) => {
console.log("Page 1 is now converted as image");
return resolve;
});pixijs ---> WebGL 2D
import { Application, Sprite, Assets } from 'pixi.js';
// The application will create a renderer using WebGL, if possible,
// with a fallback to a canvas render. It will also setup the ticker
// and the root stage PIXI.Container
const app = new Application();vis-network ---> 创建网络视图
Case 参考 antfu 的项目:https://yak.antfu.me
import { DataSet } from 'vis-data'
import { Network } from 'vis-network'
var nodes = new DataSet([
{ id: 1, label: "Node 1" },
{ id: 2, label: "Node 2" },
{ id: 3, label: "Node 3" },
{ id: 4, label: "Node 4" },
{ id: 5, label: "Node 5" },
]);
// create an array with edges
var edges = new DataSet([
{ from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 2, to: 5 },
{ from: 3, to: 3 },
]);
// create a network
var container = document.getElementById("mynetwork");
var data = {
nodes: nodes,
edges: edges,
};
var options = {};
var network = new Network(container, data, options);blurhash ---> 图片模糊
显示一张模糊后的 canvas
使用方式为例如后端除了返回图片的 URL,还需要返回一个由 blurhash 为图片生成的简短字符串
前端根据这个字符串渲染一个 canvas, 用来优化图片加载时的体验
import { decode } from "blurhash";
const pixels = decode("LEHV6nWB2yk8pyo0adR*.7kCMdnj", 32, 32);
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
const imageData = ctx.createImageData(width, height);
imageData.data.set(pixels);
ctx.putImageData(imageData, 0, 0);
document.body.append(canvas);pngjs ---> 在浏览器和 NodeJs 处理 png
import { PNG } from 'pngjs/browser';
fs.createReadStream("in.png")
.pipe(
new PNG({
filterType: 4,
})
)
.on("parsed", function () {
for (var y = 0; y < this.height; y++) {
for (var x = 0; x < this.width; x++) {
var idx = (this.width * y + x) << 2;
// invert color
this.data[idx] = 255 - this.data[idx];
this.data[idx + 1] = 255 - this.data[idx + 1];
this.data[idx + 2] = 255 - this.data[idx + 2];
// and reduce opacity
this.data[idx + 3] = this.data[idx + 3] >> 1;
}
}
this.pack().pipe(fs.createWriteStream("out.png"));
});penrose ---> 通过普通文本生成图表
type Set
predicate NotIntersecting(Set s1, Set s2)
predicate Intersecting(Set s1, Set s2)
predicate IsSubset(Set s1, Set s2)Set A, B, C, D, E, F, G
IsSubset(B, A)
IsSubset(C, A)
IsSubset(D, B)
IsSubset(E, B)
IsSubset(F, C)
IsSubset(G, C)
NotIntersecting(E, D)
NotIntersecting(F, G)
NotIntersecting(B, C)
AutoLabel Allcanvas {
width = 800
height = 700
}
forall Set x {
shape x.icon = Circle { }
shape x.text = Equation {
string : x.label
fontSize : "32px"
}
ensure contains(x.icon, x.text)
encourage norm(x.text.center - x.icon.center) == 0
layer x.text above x.icon
}
forall Set x; Set y
where IsSubset(x, y) {
ensure disjoint(y.text, x.icon, 10)
ensure contains(y.icon, x.icon, 5)
layer x.icon above y.icon
}
forall Set x; Set y
where NotIntersecting(x, y) {
ensure disjoint(x.icon, y.icon)
}
forall Set x; Set y
where Intersecting(x, y) {
ensure overlapping(x.icon, y.icon)
ensure disjoint(y.text, x.icon)
ensure disjoint(x.text, y.icon)
}svgo ---> 优化 SVG
SVG 文件,尤其是从矢量编辑器导出的文件,通常包含大量冗余信息。这包括编辑器元数据、注释、隐藏元素、默认值或次优值以及可以安全删除或转换而不影响渲染的其他内容
svgo 去除这些数据,以此来缩小 SVG 体积大小
import { optimize } from 'svgo';
const result = optimize(svgString, {
path: 'path-to.svg', // recommended
multipass: true, // all other config fields are available here
});
const optimizedSvgString = result.data;iconify ---> 集大成图标库
超级海量的图标库,可以通过如下用法,使用 CDN 加载,所有的 name 可以在这里找到
// https://api.iconify.design/${name}.svg?color=%23${logoColor}
// https://api.iconify.design/material-symbols:wifi-rounded.svg<template>
<Icon :icon="areaChartOutlined" height="24" />
</template>
<script lang="ts" setup>
import { Icon } from '@iconify/vue';
import areaChartOutlined from '@iconify-icons/ant-design/area-chart-outlined';
</script>如果你想使用这里面的图标,我建议可以使用 unplugin/unplugin-icons 这个库,帮助你自动导入
simple-icons ---> 图标库
支持直接 CDN 使用:simple-icons,自定义颜色等
// 官方 CDN:
// https://cdn.simpleicons.org/simpleicons/00ccff99
// jsdelivr:
// https://cdn.jsdelivr.net/npm/simple-icons/icons/${logoName}.svg<!-- -->
<img height="32" width="32" src="https://cdn.simpleicons.org/simpleicons/hotpink" />也支持 NodeJs:
import { siActigraph, siSimpleicons } from 'simple-icons'
console.log(siSimpleicons);
/*
{
title: 'Simple Icons',
slug: 'simpleicons',
hex: '111111',
source: 'https://simpleicons.org/',
svg: '<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">...</svg>',
path: 'M12 12v-1.5c-2.484 ...',
guidelines: 'https://simpleicons.org/styleguide',
license: {
type: '...',
url: 'https://example.com/'
}
}satori ---> React 组件到 SVG
可以用于用于生成 OG 图片
// api.jsx
import satori from 'satori'
const svg = await satori(
<div style={{ color: 'black' }}>hello, world</div>,
{
width: 600,
height: 400,
fonts: [
{
name: 'Roboto',
// Use `fs` (Node.js only) or `fetch` to read the font as Buffer/ArrayBuffer and provide `data` here.
data: robotoArrayBuffer,
weight: 400,
style: 'normal',
},
],
},
)