欢迎关注微信公众号:前端阅读室
问题
之前在知乎上看到一个问题:把所有汉字叠写起来最后会留下空白吗?今天我们就用前端技术来研究一下这个问题。
思路
- 所有汉字
所有字符都可以用 Unicode 编码,汉字也不例外。我们查到基本汉字的 Unicode 编码范围是:4E00-9FA5,共 20902 个。
- 如何叠写
叠写其实就是图形的绘制,HTML5 的 <canvas>
标签是用于绘制图像的,它本身支持在画布上绘制文本,所以使用 canvas 来实现文字叠写再合适不过了。
- 会留下空白吗?
看实验结果。(这里不会花精力使用 context.getImageData 方法获取画布上的像素数据做精确的判断,只凭肉眼得出一个大致结论即可)。
实验
有了思路以后,我们就可以编写代码了。代码我们会放到后面讲解,先直接看下绘制的结果。
前 10 个汉字
前 50 个汉字
前 100 个汉字
前 200 个汉字
前 500 个汉字
全部汉字(20902 个)
结论:可以看到所有汉字叠写起来不会占满整个方块,边缘会有空白,但中间没有空白。
彩蛋版
定时器版本
热力图版本
基础版本代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>把所有汉字叠写起来最后会留下空白吗?</title>
<style>
.note {
font-size: 50px;
}
</style>
</head>
<body>
<div class="note">前<span id="count">0</span>个汉字</div>
<canvas id="canvas"></canvas>
<script>
// 获取 canvas 的 dom 元素
const canvas = document.getElementById("canvas");
// 尺寸常量
const SIZE = 500;
// 设置 canvas 宽度和高度(比字体大 100px)
const INCRE = 80;
canvas.setAttribute("width", SIZE + INCRE);
canvas.setAttribute("height", SIZE + INCRE);
// 获取绘图环境
const ctx = canvas.getContext("2d");
// 字体设置
ctx.font = `${SIZE}px Arial`;
// 透明度设置(汉字太多了,字的透明度低便于叠写后观察)
ctx.globalAlpha = 0.1;
// 字的数量计数
let count = 0;
// 字的数量限制。基本汉字总数:20902
const LIMIT = 100;
// 获取显示字的数量的元素
const countElment = document.getElementById("count");
// 设置字的数量
countElment.innerText = LIMIT;
// 遍历汉字的 Unicode 编码
for (let i = 0x4e00; i <= 0x9fa5; i++) {
// 将 Unicode 编码转换为字符
const text = String.fromCharCode(i);
// 在 canvas 上绘制字符
ctx.fillText(text, 0, SIZE);
// 字的数量计数及数量限制
count++;
if (count >= LIMIT) {
break;
}
}
</script>
</body>
</html>
复制代码
欢迎关注微信公众号:前端阅读室