为什么我们在项目中用canvas?(why)
产品经历的需求:做个组织架构图。
需求大致如下:公司下边有部门,部门要和负责人同级,子部门下边也会有相应的负责人和部门;如图所示
有人问了:为什么不用dom去做
这是个好问题,其实之前我们就是用dom来做组织架构图的。
用dom也有他的弊端,比如一旦涉及到2000条以上的数据,对于组织架构这种复杂业务,如果我们用dom做,渲染的时间会很长,甚至直接导致浏览器崩溃。所以这个时候canvas登场了。
g6其实是基于canvas封装的库
个人使用canvas优势: 1.渲染速度快
劣势: 1.g6的文档写的不太好,很多文档只有api使用文档但是没有当前api具体例子,导致我们在用的时候要自己去尝试踩坑。 2.跟dom不一样,每个图形的位置需要自己手动计算,在用g6画卡片的时候会有这样的一种感觉:我是在做浏览器排列dom的核心算法。因为所有的图形并不会平白无故的就按顺序排列。所以也就要我们去算每个元素所在的位置,接下来我分享以下计算文案宽度所的收获的东西。
计算文字的宽度
为什么要计算文字宽度,不计算行不行?
上边提到到了canvas的劣势:它不会平白无故的就按顺序排列元素。也就是我们如果不指定文字的位置,那么你可以看到下边话横线的文字,都会在堆叠在一个地方,而且后边的文字会覆盖前边的文字;
所以我们必须要排列文字,而排列文字就要知道当前文字的起始坐标,而第二列文字和第一列文字的长度有关系(就跟我们用dom一样,如果这是两个span标签,第一个span标签如果文字增加,那么第二个span标签的位置也会相应的增加);
V-01
之前我认为,两个英文字母和一个汉字所占的像素是一样的,但事实如此吗?
我们来验证一下;
以下两个汉字的宽度:
四个字母的宽度:
结论:通过上边三张图我们可以知道,其实一个汉字不等于两个字母的宽度,甚至字母所占的像素都是不一样的。所以用正则将 汉字转换为字母,再通过字符串数量来计算文案的长度是不正确的。
V-02
那么既然两个字母的像素宽度不等与一个汉字的宽度,那么我有了第二中方案: 手动量出每个字母所占的像素。
export const WIDTH_ALPHABET_MAP = {
// 小写
a_WIDTH: 7.83,
b_WIDTH: 8.22,
c_WIDTH: 7.67,
d_WIDTH: 8.22,
e_WIDTH: 7.78,
f_WIDTH: 5.23,
g_WIDTH: 8.28,
h_WIDTH: 7.8,
i_WIDTH: 3.59,
j_WIDTH: 3.75,
k_WIDTH: 7.41,
l_WIDTH: 3.3,
m_WIDTH: 11.98,
n_WIDTH: 7.83,
o_WIDTH: 8.22,
p_WIDTH: 8.22,
q_WIDTH: 8.22,
r_WIDTH: 5.13,
s_WIDTH: 7.08,
t_WIDTH: 4.98,
u_WIDTH: 7.84,
v_WIDTH: 6.75,
w_WIDTH: 10.58,
x_WIDTH: 7.14,
y_WIDTH: 6.95,
z_WIDTH: 6.83,
// 大写
A_WIDTH: 9.2,
B_WIDTH: 9.48,
C_WIDTH: 10.2,
D_WIDTH: 9.89,
E_WIDTH: 8.92,
F_WIDTH: 8.08,
G_WIDTH: 10.48,
H_WIDTH: 10.09,
I_WIDTH: 3.33,
J_WIDTH: 7.25,
K_WIDTH: 9.67,
L_WIDTH: 8.23,
M_WIDTH: 12.36,
N_WIDTH: 10.08,
O_WIDTH: 10.75,
P_WIDTH: 9,
Q_WIDTH: 10.75,
R_WIDTH: 9.47,
S_WIDTH: 8.86,
T_WIDTH: 8.67,
U_WIDTH: 10,
V_WIDTH: 8.95,
W_WIDTH: 13.03,
X_WIDTH: 8.92,
Y_WIDTH: 9.28,
Z_WIDTH: 8.75,
};
但是接下来问题又出现了,上边只是字母所占的宽度,那么数字呢? 之后我又测量出了每个数字所占像素的宽度;
export const WIDTH_NUMBER_MAP = {
0: 8.41,
1: 5.63,
2: 8.41,
3: 8.41,
4: 8.41,
5: 8.41,
6: 8.41,
7: 7.67,
8: 8.41,
9: 8.41,
};
特殊字符呢?
难道要每个都量出来吗?显然我走错方向了。
V-03
查找了g6的API,发现没有计算文字宽度的方法;那么直接 cavans 中的API有没有呢? 在w3schools上我找到了这样的api;
- measureText
www.w3schools.com/tags/canvas…
最后总结
- 两个英文字母和一个汉字所占的像素通常是不一样的
- 我个人在实验的过程中还发现,就算是相同的字体,fontWeight不一样,不同字符所占的像素情况也很多。比如,现在我们现在页面中只有一个span标签,只给这个span标签设置了font-size为14px,fontWeight分别设置为400和600后会发现,汉字所占像素没有变化,但英文字母前后所占像素也不一样,特殊字符前后所占像素也不一样;这次通过踩坑,个人对字体的理解更深了。
- 我们要的到画布上文字的长度的时候,measureText是最简单有效的
- 这次也对思维方式做了反思,我们在用一个新框架的时候,要对底层的了解要稍微全面才行。比如:g6是canvas的封装,在用g6之前我应该先看一遍canvas,做到心中有底才去看g6,要不然直接用g6会很虚。