资讯动态

用console.log在浏览器控制台绘制嫦娥奔月字符画彩蛋

发布时间:2026/10/20 21:00:29 来源:尧图企业网站定制
中秋前一周Leader突然探过头来隔着工位丢了一句“马上中秋节了你在网站的console面板中画一个嫦娥奔月要有逼格。”我当场愣了一下反应过来后觉得这事儿挺有意思——F12控制台本来是开发者看日志的地方现在要当画布用还是给用户看的。这类“控制台彩蛋”在不少网站里出现过但真正做得优雅的很少多数是随便打一句欢迎语或者放个Logo字符画。既然Leader点题“嫦娥奔月”还要“逼格”那就不能只写一行“中秋快乐”交差。这篇文章我就把踩过的坑、选过的方案、最终能直接抄走的代码一起捋一遍。不管你是前端老手还是刚入门想给网站加点小惊喜的新人只要你需要在浏览器控制台里展示字符画、节日彩蛋、品牌信息这篇都能用上。内容不复杂核心就三件事字符画怎么生成、console怎么排版好看、怎么避免在人家控制台里翻车。1. 先搞懂Leader到底想要什么1.1 表面是字符画背后是品牌彩蛋很多人接到这种需求的第一反应是“画得越像越好”但站在使用者角度想一下谁会在普通浏览时打开控制台大部分人是开发者剩下的是一小撮好奇用户。控制台彩蛋本质上不是给“所有人”看的而是给“愿意多按一下F12的人”看的。这些人看到的不应该是一段冷冰冰的代码而是一个有惊喜感的画面。所以这个需求的核心不是“嫦娥奔月像不像”而是“用户打开控制台之后会不会觉得这个网站有点温度”。一个把中秋节祝福藏在控制台里的站点会让人觉得运营团队有小巧思。这也是为什么不能简单粗暴地打印几行字符串——画面要有视觉重心颜色要协调文字要有点仪式感。说白了逼格就是“精致感和分寸感”。我是把这个需求拆成了三步来做先确认画面形态再解决字符画来源最后优化在console里的最终展示效果。一步做扎实了再往下走避免返工。1.2 控制台画图的三个边界浏览器控制台不是一个自由画布动手之前必须清楚它的限制否则设计做得再花哨也实现不出来。第一个边界是排版能力有限。控制台只能按“文本流”来展示内容没有DOM节点没有绝对定位不能把某个字符精确放到某个像素位置。你看到的字符画本质上是把二维图形拆成一行一行带换行的纯文本。所以字符画一旦生成宽高比例就已经定死了后续能调整的只有字体、字号、颜色、背景这类CSS属性。第二个边界是样式支持有限。console.log支持用%c给字符串片段加样式这是控制台彩蛋的核心能力。但并不是所有CSS属性在控制台里都生效像position、flex这类布局属性基本不用想color、background、font-size、font-family、line-height、padding、text-shadow这些是经过验证比较好用的。注意不同浏览器对样式属性的支持不完全一样尤其是Firefox和Safari容易出现样式打了但没反应的情况。第三个边界是console输出体验。如果一次性往控制台里丢几百行字符画用户的控制台会刷得密密麻麻看起来很廉价。如果再用console.clear()来做动画那更糟糕因为它会把用户之前的所有日志都清掉极不礼貌。好的彩蛋应该是一眼能看到、不打扰、可回收的。理解了这三条边界后面的方案选择就顺理成章了。2. 怎么把“嫦娥奔月”塞进Console2.1 手工画还是图片转字符画刚开始我天真地想过自己手工排一个嫦娥奔月的文本图案毕竟网上见过不少ASCII Art好像没那么难。但真动手就发现手工排一个能看清“嫦娥”“月亮”“飘带”的图案非常考验空间想象力和耐心。字符画不是画画它是一个一个字符抠出来的稍微有一个位置偏了整个轮廓就歪。更现实的问题是就算我手工画出来了也只是“我画的这一个图案”后续想换风格、调整大小又得重新抠。这种一次性工作浪费大量时间而且效果大概率达不到Leader要求的那种“逼格”。后来我决定走“图片转字符画”的路子先找一张合适的嫦娥奔月剪影图片再用程序把图片像素映射成字符最后把生成的字符数组塞到页面的console逻辑里。这么做的好处有三个图案来自真实图片细节丰富更换图片就能更换风格代码是通用的以后圣诞节、春节、端午换个图片就能复用。2.2 图片转字符画的基本原理图片转字符画听起来有点高级其实原理特别朴素。把一张图片缩小成比如80×30的尺寸然后对每个小格子取灰度值。灰度值代表亮度从0到255。亮度高的区域用稀疏字符比如空格、点、减号表示亮度低的区域用密集字符比如、#、%等表示。这样一整张图片就变成了由字符疏密构成的“画”。实现的时候有三个核心步骤要理解第一步是把彩色图片转成灰度图。人眼对红绿蓝的敏感度不一样所以不能简单取平均值比较标准的公式是gray 0.299R 0.587G 0.114B。直接用图像处理库里的convert(L)就行。第二步是调整宽高比例。一个字符在控制台里的显示高度大约是宽度的两倍如果把一张正方形图片按照100×100转换出来的字符画会变成长方形图案被拉高。所以高度要乘一个0.5左右的压缩系数即height width * 原图高度 / 原图宽度 * 0.5。这个系数可以根据实际等宽字体微调我喜欢从0.5开始试。第三步是亮度到字符的映射。字符集要预先安排好从亮到暗或从暗到亮。常用的字符集长这样 .:-*#%越靠前的字符视觉上越“稀疏”越靠后的越“密集”。把灰度值按比例映射到这个字符集的索引上就完成了一层转换。2.3 关键参数别搞错给个我调通的参考参数输出宽度90 ~ 110 高度压缩系数0.45 ~ 0.55 字符集 .:-*#% 图片要求背景纯白或纯黑主体线条清晰对比度强输出宽度太宽手机端控制台会折行太窄嫦娥的形象会糊成一团。如果生成后发现画面偏亮、看不清轮廓多数是字符集顺序和灰度的映射方向反了。我的经验是在字符集里越靠后的字符越“重”对应图片里越暗的像素。如果图片背景是白色、主体是黑色那主体会变成密集字符背景变成空格画面清晰。3. 完整实操从嫦娥图片到Console动效3.1 准备素材做之前要准备一张合适的图片。这里提醒一下版权问题别随便扒网上的商用插画最好用自己画的、同事画的或者从免版权图库找一张“嫦娥剪影”“玉兔剪影”类的图。如果允许直接在图片处理软件里把画面处理成“黑底白图”或“白底黑图”高对比度会让字符画的轮廓干净很多。我自己用的是一张嫦娥抱兔奔月的黑色剪影背景纯白人物线条简洁。选图时注意主体不要太小周围大面积的留白会在字符画里变成大片空格浪费画布也让嫦娥显得很小。适当裁剪让人物和月亮占到画面的50%以上效果最好。3.2 用Python脚本快速生成字符画如果你电脑里装了Python直接跑一段脚本就能把图片变成字符画。需要先安装Pillow库pip install pillow脚本如下把图片路径换掉就能用from PIL import Image CHARS %#*-:. def image_to_ascii(image_path, width100): # 打开图片并转灰度 img Image.open(image_path).convert(L) # 根据字符宽高比压缩图片高度 ratio 0.5 height int(width * img.height / img.width * ratio) img img.resize((width, height), Image.Resampling.LANCZOS) pixels list(img.getdata()) lines [] for y in range(height): row pixels[y * width:(y 1) * width] line for p in row: # 灰度0是纯黑255是纯白 index min(int(p / 255 * (len(CHARS) - 1)), len(CHARS) - 1) line CHARS[index] lines.append(line) return \n.join(lines) if __name__ __main__: art image_to_ascii(change.png, width100) print(art)说明一下Image.Resampling.LANCZOS是新版Pillow的写法如果你的Pillow版本比较老就用Image.LANCZOS效果一样。生成之后你会看到一大串由%#*-:.组成的字符画。如果画面太亮就把CHARS里的顺序反过来试试如果画面变形调节ratio变量比如从0.5改成0.45。生成的字符画可以直接复制到JavaScript字符串里或者像我这样把它写到一个文本文件里让前端代码去加载。最省事的是把字符画当作模板字符串嵌在JS文件里但如果图片太复杂、输出宽度很大字符串会非常长建议按行拆成数组减少阅读压力。3.3 用console.log把它打出彩字符画有了接下来就是展示环节。很多人只会用console.log一个裸字符串那画面白底黑字说实话没啥视觉冲击。要逼格就得上%c样式。最简单的带样式输出const art %#****... ... ; console.log( %c art, color:#f9d71c; background:#0d1117; padding:12px; font-family:Courier New,monospace; font-size:12px; line-height:1.1; );这段代码核心就一个点%c art里面的%c告诉控制台“后面这段文字按我给的样式来渲染”。样式字符串里我加了字体、字号、颜色、背景、内边距和行高。实际效果是一条带深色背景的金色字符画整体观感比默认样式好很多。如果你想做出人物和背景的颜色差异可以按行输出每行单独上色。思路是把字符画切成行数组遍历每行根据这一行中字符的密集程度判断前景/背景选择不同颜色。比如上半部分是月亮用淡金色下半部分是人物剪影用银白色。代码可以这样写const CHARS %#*-:. ; const lines art.split(\n); lines.forEach((line, i) { if (line.trim().length 0) { console.log( ); return; } // 粗略计算行平均亮度 let sum 0; for (const ch of line) { const idx CHARS.indexOf(ch); sum idx; } const avg sum / line.length / (CHARS.length - 1); const color avg 0.5 ? #fff3b0 : #e0c080; console.log(%c${line}, color:${color}; background:#141618; line-height:1.1;); });这样输出会多打印很多行控制台里每条日志是一个小条目看起来可能有点碎。如果你不介意这个方案能带来一定的渐变感。如果想让画面整体统一还是建议用单次console.log配合整块背景的样式。3.4 加一点时间轴做出“有逼格”的动态纯静态字符画已经很能打了但“有逼格”还需要一点叙事感。我不推荐用setIntervalconsole.clear()做逐帧动画因为会频繁清屏严重影响控制台体验。更优雅的做法是“时间轴输出”先输出一个可折叠的分组标题用户点开之后再依次看到月亮、嫦娥、祝福语。利用console.groupCollapsed可以把整段彩蛋折叠成一个标题用户想看不看主动权在用户手里。代码如下function showMoonFestivalEgg() { console.groupCollapsed( %c 中秋彩蛋嫦娥奔月 , color:#f9d71c; font-size:16px; font-weight:bold; padding:4px 8px; ); console.log( %c art, color:#f9d71c; background:#0d1117; padding:12px; font-family:Courier New,monospace; font-size:12px; line-height:1.1; ); console.log( %c但愿人长久千里共婵娟。, color:#ecf0f1; background:#0d1117; padding:4px 12px 12px; font-size:14px; letter-spacing:2px; ); console.groupEnd(); } showMoonFestivalEgg();这一段有几个细节%c样式里加空格和全角空格能让分组标题看起来更透气console.groupCollapsed和console.groupEnd必须成对出现祝福语单独一行和字符画保持距离不会和图画抢视觉重心。如果你想再“动态”一点可以用setTimeout让三条日志分先后出现但不要在分组内等太久否则控制台的分组关系可能表现不正常。我个人的经验是同步输出三行已经足够节奏靠排版控制不一定非要动画。3.5 最终封装时别忘了防重复网站彩蛋这种东西用户打开一次是惊喜打开十次就是骚扰。所以正式发布前最好加一个“只显示一次”的开关。实现很简单用localStorage记一下状态function showMidAutumnEggOnce() { try { if (localStorage.getItem(midAutumnEggShown_v1)) return; localStorage.setItem(midAutumnEggShown_v1, 1); } catch (e) { // 无痕模式下localStorage可能不可用直接忽略 } console.groupCollapsed( %c 中秋彩蛋嫦娥奔月 , color:#f9d71c; font-size:16px; font-weight:bold; ); console.log(%c art, artStyle); console.log(%c但愿人长久千里共婵娟。, textStyle); console.groupEnd(); }注意localStorage在无痕模式或某些隐私设置下会抛异常所以要用try/catch包一层避免彩蛋逻辑影响正常页面功能。这个习惯在很多工具函数里都适用。4. 逼格藏在细节里格式、配色和文案4.1 如何让字符画在控制台里不变形字符画最容易翻车的就是变形。原因主要有两个一是字符画生成时没有做高度压缩二是在console输出时字体不是等宽或行高太大。解决方法是双管齐下。生成端的压缩公式前面已经提过。输出端在%c样式里一定要显式指定等宽字体和行高font-family:Courier New,monospace; font-size:13px; line-height:1.15;这里说个细节不同浏览器控制台默认字体不同Chrome常用MonacoWindows下可能用ConsolasFirefox又不一样。统一指定monospace会安全很多。行高不要设置成默认的1.4或1.5那会让字符画上下间距太大看起来松散。我一般从1.1开始调画面紧凑人物轮廓更完整。4.2 配色决定“逼格”的上限同样是字符画黑底白字和深蓝底金字的气质完全不同。中秋节我选的是“深空蓝”配“暖金色”既有夜晚的氛围又符合节日喜庆感。字符画主体的色值大约是#f9d71c背景色#0d1117字体阴影加上text-shadow会有一种轻微发光效果。color:#f9d71c; background:#0d1117; padding:12px; font-family:monospace; font-size:12px; line-height:1.1; text-shadow:0 0 6px rgba(250, 200, 50, 0.6);text-shadow在Chrome控制台里是生效的能让字符边缘有一点柔光月亮的感觉就出来了。如果你觉得整个画面只有金色太单调可以留一行给“文字点缀”比如在画面上方加一行小字“中秋 · 月圆”用更淡的银色#b0c4de。这种细节不会抢戏但会让人觉得你是精心设计过的。4.3 文案要有分寸感控制台彩蛋的文案不宜太长。用户打开控制台不是来看长篇大论的。一句节日祝福加一句引导性的话足够了。我常用的模板是字符画是一部分祝福语是一部分最后再给一个链接或提示。但链接在控制台里点击起来不方便所以除非必要不建议放。如果你想让用户产生互动感可以加一句“点击上方标题展开彩蛋”这里因为用了groupCollapsed交互本身就存在反而不需要额外解释。视觉上要注意祝福语不要挨着字符画留一空行文字和字符画的字体大小可以不一样祝福语稍微大一点有层次感。我用letter-spacing:2px增加一点字距文字更舒展。4.4 多浏览器调试方法开发完千万别只在Chrome里看一眼就上线。Safari和Firefox对%c样式的支持各有不同。我用下来比较稳的规则是核心颜色、背景、字体、padding、line-height这些属性各家都认text-shadow、border-radius、渐变背景这些属于“锦上添花”不生效也能接受。调试的时候直接在浏览器控制台里运行那几行代码肉眼确认效果。如果有条件开一台Windows电脑再看看Chrome和Edge的效果因为字体渲染不同字符画的整体比例可能和你Mac上看到的不太一样。必要的时候微调生成端的ratio压缩系数。5. 常见问题与Debug实录5.1 控制台不显示彩色或者样式被忽略这是最常见的问题。多数情况是console.log的第一个参数里没有%c占位符或者%c和样式字符串的数量对不上。例如console.log(嫦娥奔月, color:red);这样写样式不会生效因为color:red会作为第二个参数被直接打印出来。正确的是console.log(%c嫦娥奔月, color:red);另外%c只对它后面紧跟着的那段文本生效。如果一段字符串里插入了多个%c就要对应多个样式参数少一个都会错乱。5.2 字符画换行错乱、空格被压缩控制台展示多行字符画用模板字符串的时候要注意反引号里的换行和空格会原样保留但如果你是从别处复制过来的文本要检查是不是混入了Tab。Tab在某些控制台里会被扩展成多个空格导致画面错位。空格被压缩的问题一般不会出现在Console渲染里但如果你的字符画是放在HTML的pre标签里调试那就容易被浏览器合并空格。控制台里反而安全。唯一要注意的是字符串末尾的空格会被某些工具自动修剪所以生成字符画时最好保留行尾空格或者至少保留左边距对齐。5.3 动画卡顿或者不想清屏前面说过不推荐用console.clear()做动画。如果你非要做一个动态效果可以用“有限帧动画”替代无限循环。比如月亮从下往上移动只播放两三帧播放完就停止。思路是预生成三个版本的字符画用setTimeout依次输出不刷新页面不清理日志。这样用户能看到动感又不会被打扰。如果已经出现了卡顿先检查是不是在一个循环里执行了太多次console.log。控制台日志输出本身是有开销的几千行瞬间打出来浏览器会直接卡住。遇到这种情况把输出宽度调小或者减少字符画行数。5.4 中文宽度不对齐导致画面乱字符画里混中文是最容易翻车的。一个中文字符在等宽字体下通常占两个英文字符的宽度如果你把“嫦娥奔月”这四个字硬塞进一行ASCII字符画里右边的部分会全部错位。解决办法很粗暴字符画本画只用ASCII字符中文祝福语单独放一行别和字符画插在同一行里。如果你确实想把“嫦娥”放在画面中央生成图片时可以把“嫦娥”作为图形的一部分也就是先把文字渲染到图片上再整体转成字符画。这样能保证对齐。5.5 生产环境别误输出开发环境里调试半天一到线上就把彩蛋打到所有用户控制台这可能造成两个问题一是刷屏干扰开发者排错二是如果字符画里藏着敏感信息或奇怪的品牌文案容易被截屏传播。所以发布前记得加上环境判断。只在国际版、正式版、特定域名或指定路径下输出或者用我们前面写的localStorage一次性开关。还要注意不要在字符画里输出任何涉及用户隐私、内部系统地址、未公开功能的信息。控制台彩蛋可以被任何人打开它本质上是一个公开页面所有内容都要经得起推敲。做这个需求最大的体会是要“有逼格”不等于使劲堆技术恰恰相反是通过克制和细节让人觉得舒服。控制台彩蛋没有多高深但从图片选择、字符生成、颜色搭配到是否只显示一次每一步都影响最终体验。我后来把这套脚本整理成了一个通用方法换张图就能复用今年剩下的几个节日基本不用再临时加班。最后再分享一个小技巧字符画生成后别急着接样式先用纯文本在控制台里看一眼比例对不对再做颜色和阴影不然样式加多了比例问题反而更难查。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑