你那里下雪了吗?没下,我们在手机里下


头九不见雪,九九如六月。
——《数九歌》,春秋时期

你那里下雪了吗?
进入冬天,老一辈喜欢“数九”:
一九二九怀中插手,三九四九冻死老狗,五九六九沿河看柳。七九花开,八九燕来。九九耕牛遍地走。
所谓“九”,大致要从冬至算起。以今年为例,从2024年12月21日开始,到今天第16天,进入“二九”。按道理,应该冷得让人手揣兜。
但今年,大家普遍感觉不怎么冷(1961年来最暖的冬天),也没见到什么雪。

今年,你那里下雪了吗?


没下,我们在手机里下。

还可以跨图一起下。


制作原理详解
2.1 怎么做的?
答:用SVG动画做的。
SVG,简单来说就是一种遵循XML语言的矢量图格式,可以无损缩放图像。在公众号和网站上,多用于一些融媒体形式的动画交互和特效展示。
前面下雪的图,它其实是包了两层,一层是原图(上传后获得图片网址),一层是SVG特效。

原图+SVG动画,就得到了这样的特效动图。

2.2 SVG代码怎么写?
答:交给LLM。
原则上,所有推理模型都可以写SVG代码,比如:
  • Kimi的视觉思考板(K1模型)
  • DeepSeek的深度思考(R1模型)
  • 通义的代码模式
  • 智谱的Zero推理模型
  • 天工的o1模型
  • 以及国外的o1、Artifacts、canva等
今天,我们用的是智谱的推理模型——GLM-Zero预览版
上周,给大家介绍了GLM-Zero预览版。当时只体验了他们家的数理计算和推理能力,还没有体验代码能力。

今天,我们就用这个Case来体验下智谱的代码能力。这是生成SVG动画代码的提示词,作者@赛博禅心

绘制一个SVG飘雪动画:
1. 背景- 使用给定图片作为底图- 通过image标签引入
2. 雪花效果- 白色圆点(r=1.5)表示雪花- 10-15个雪花同时飘落,从左到右散落- 每个雪花需要有: * 从 SVG 外进入(y=-10~-50),均匀散落(x=0~400) * 淡入淡出效果(opacity: 0 -> 0.8 -> 0) * 随机的开始时间(0-2.5s不等) * 不同的下落速度(3.5-5.5s一个周期) * 随机的水平偏移(25-60px) * 使用独立<g>,不要使用 <defs>每组示例:<g><circle cx="50" cy="-10" r="2" fill="white"/><animateMotion dur="4s" repeatCount="indefinite" path="M50 -10 C55 80,45 150,50 400"/><animate attributeName="opacity" from="1" to="0" dur="4s" repeatCount="indefinite"/></g>
3. 动画实现要点- 使用animateMotion设置运动路径- 通过不同的begin时间错开雪花出现时机- 运动路径从顶部到底部(400px距离)输出<svg>
将提示词发给智谱Zero推理模型后,等待1-2分钟的深度思考,就会得到一段SVG代码。其中”background.png”,即你的底图。
Ps.通过文章预览版,可以获得微信图片网址。
微信图片全段网址很长,只需要复制“appmsg”前的链接就行。

然后,替换掉”background.png”,就得到了完整的SVG动画代码(有经过微调)。
<section style="margin: 8px;">
<svg viewBox="0 0 400 400" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<image href="https://mmbiz.qpic.cn/mmbiz_jpg/NX4HOlP6ibCicFia0wg3CAUd5iaI97MNZZCWMWF3EORuD2n51xfB9ka0Tgs24YZSVcPT3eUtFu5V95gN8vaYUnPrzQ/640?wx_fmt=jpeg&from=appmsg" width="400" height="400"></image>
<g><circle cx="50" cy="-10" r="2" fill="white"></circle><animateMotion dur="4s" repeatCount="indefinite" path="M50 -10 C40 60,60 140,50 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="4s" repeatCount="indefinite"></animate></g>
<g><circle cx="100" cy="-20" r="3" fill="white"></circle><animateMotion dur="5s" repeatCount="indefinite" path="M100 -20 C90 80,110 200,100 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="5s" repeatCount="indefinite"></animate></g>
<g><circle cx="150" cy="-30" r="4" fill="white"></circle><animateMotion dur="3.5s" repeatCount="indefinite" path="M150 -30 C140 50,160 200,150 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="3.5s" repeatCount="indefinite"></animate></g>
<g><circle cx="200" cy="-40" r="2" fill="white"></circle><animateMotion dur="4.5s" repeatCount="indefinite" path="M200 -40 C190 70,210 200,200 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="4.5s" repeatCount="indefinite"></animate></g>
<g><circle cx="250" cy="-50" r="3" fill="white"></circle><animateMotion dur="5s" repeatCount="indefinite" path="M250 -50 C240 80,260 210,250 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="5s" repeatCount="indefinite"></animate></g>
<g><circle cx="300" cy="-10" r="4" fill="white"></circle><animateMotion dur="4s" repeatCount="indefinite" path="M300 -10 C290 100,310 220,300 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="4s" repeatCount="indefinite"></animate></g>
<g><circle cx="350" cy="-30" r="3" fill="white"></circle><animateMotion dur="3.8s" repeatCount="indefinite" path="M350 -30 C340 90,360 220,350 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="3.8s" repeatCount="indefinite"></animate></g>
<g><circle cx="60" cy="-15" r="2" fill="white"></circle><animateMotion dur="4.2s" repeatCount="indefinite" path="M60 -15 C50 80,70 210,60 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="4.2s" repeatCount="indefinite"></animate></g>
<g><circle cx="120" cy="-5" r="4" fill="white"></circle><animateMotion dur="4.5s" repeatCount="indefinite" path="M120 -5 C110 120,130 230,120 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="4.5s" repeatCount="indefinite"></animate></g>
<g><circle cx="180" cy="-40" r="3" fill="white"></circle><animateMotion dur="5s" repeatCount="indefinite" path="M180 -40 C170 80,190 250,180 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="5s" repeatCount="indefinite"></animate></g>
<g><circle cx="280" cy="-30" r="2" fill="white"></circle><animateMotion dur="4.3s" repeatCount="indefinite" path="M280 -30 C270 50,290 200,280 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="4.3s" repeatCount="indefinite"></animate></g>
<g><circle cx="330" cy="-50" r="4" fill="white"></circle><animateMotion dur="5.5s" repeatCount="indefinite" path="M330 -50 C320 120,340 220,330 400"></animateMotion><animate attributeName="opacity" values="0.6;0.8;0.2" dur="5.5s" repeatCount="indefinite"></animate></g>
</svg>
<br></section>
2.3 怎么放进公众号文章里?
答:复制粘贴。

因为公众号的编辑器不支持svg插入,所以我们是手动粘贴。

  • 复制前面完整的SVG代码
  • 在编辑器里空一行
  • 打开浏览器的控制台(console),Windows按F12(Mac按Option+Command+I),选中这一行
  • 右键“Edit as HTML”,将原代码全部替换成SVG代码

这是演示视频:

2.4 跨图下雪怎么做的?
hh,其实它是假跨图。只需要让SVG动画的刷新时间略长于页面内刷屏的运动时间,它看起来就是在跨图下雪了。
使用上面代码,将多张图放在一起,自然就能实现雪花在多图上的一致性。

实际上,除了可以下雪,也可以下雨、放烟花(从下往上运动)和下红包……

写在最后
推理模型可以用来做什么?
除了计算、推理外,对于写代码也是很有裨益。2023年,GitHub曾做过统计,92%的开发者都用过AI写代码。
来到现在,这个数字注定有增无减。Claude的Artifacts功能让很多人爱不释手,ChatGPT 4o紧急推出canva功能,包括通义也有了自己的「代码模式」,以及如今智谱的GLM-Zero推理模型。
应用开发可视化,真就一夜之间进入了“人人”系列。
我们来看看智谱Zero模型的推理过程,我觉得可以用“深思熟虑”这个词来评价。
生成后的SVG代码,可以直接使用,无需再改。
当然,唯一缺点就是还不能直接预览。希望智谱快快上线预览功能~

(文:沃垠AI)

发表评论