尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

兔年新年红包HTML源码解析:从SVG兔子到CSS3D翻转与烟花动效

兔年新年红包HTML源码解析:从SVG兔子到CSS3D翻转与烟花动效 简介一套以兔年新春为主题的HTML互动页面源码模拟微信红包点击开奖效果适合前端入门学习者与需要快速搭建节日活动页的开发者参考。页面将HTML结构、CSS样式与JavaScript动画结合通过按钮触发、随机金额生成及过渡动画还原拆红包体验能直观学习DOM操作、事件监听与前端动效实现思路。资源包共1771个文件压缩后仅6.6MB以1751个svg矢量图标为主辅以css样式表、js交互脚本、woff2/ttf字体、gif动效等。svg提供丰富的兔年与节日元素css负责布局、配色与红包开合过渡js处理点击逻辑、随机金额与requestAnimationFrame动画整体目录清晰可直接浏览器运行调试。目前已有6935人学习使用。下载后可获得完整可运行的兔年新年红包源码并可从代码中提炼出事件绑定、CSS keyframes动画、帧率控制等通用技巧便于迁移至其他H5活动或营销页面对前端综合实践很有帮助。1. HTML新年快乐2023的落地方式一个兔年红包文件跑通全场除夕前夜我在群里收到一个链接点开是红底金边的兔年贺卡点击封面后整张卡翻转过来屏幕底部升起烟花祝福语一个字一个字往外蹦。那不是视频也不是小程序而是一个纯粹的 index.html。标题里提到的「HTML新年快乐2023源代码兔年新年红包代码」指的就是这种用一个文件搞定封面、兔子、开红包和烟花动效的制作方式。它不需要 Node不需要构建工具编辑器加浏览器就能改、能跑。适合刚开始接触 HTML 的人当作第一个完整作品来抄也适合前端熟手在节日活动页里复用这套「拆红包」交互。下面我按一个红包页面从骨架到发布的真实顺序把这份源码拆开讲透。2. 兔年红包页面的 HTML 骨架DOCTYPE、meta 与双面卡片分区2.1 为什么这种节日页用原生 HTML 就够节日红包页的生命周期很短通常春节前三天上线、元宵后下线访问峰值集中在除夕晚上。这种场景最忌讳引入构建链和重框架——一次npm install的时间页面可能都已经发出去了。原生 HTML CSS 少量 JavaScript 的优势在于没有任何外部依赖不会出现 CDN 挂掉导致页面白屏文件可以被直接传给同事双击就能打开预览部署时扔到任意静态服务器上就是完整站点。标题里的「源代码」三个字说明读者要的不是思路而是能直接落地的文件。我的做法是保持三个文件的结构index.html管内容、style.css管外观、main.js管交互。这样改文案时不用翻样式调动画时不用动结构。下文按这三个文件逐一说明参数和理由。2.2 head 里的参数HTML 能否正常渲染全看这里很多搜「HTML新年快乐2023源代码」的人拿到代码后双击打开发现页面是乱码问题八成出在 head 里少了编码声明。下面是红包页 head 的完整写法!doctype html html langzh-cn head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1.0, viewport-fitcover meta namedescription content2023兔年新年快乐红包点击拆开领取祝福 meta nametheme-color content#c7000b title2023 兔年红包 · 新年快乐/title link relstylesheet hrefstyle.css /headcharsetutf-8解决中文乱码这是 HTML 文件最先被解析的声明。viewport里的widthdevice-width让页面在手机上按设备宽度渲染viewport-fitcover是针对 iPhone 刘海屏的适配缺了它红包底部可能被 Home 指示条遮住。theme-color控制 Android Chrome 地址栏颜色取值和红包主色一致视觉上更完整。description虽然在页面上不可见但如果这个页面被部署到服务器上它会成为搜索引擎结果里显示的摘要也就是「源代码」类搜索词命中率的一个重要因素。2.3 红包卡片的双面结构封面与内页的 HTML 分区红包的本质是一张「可翻转的卡片」HTML 结构要按这个逻辑来分。封面是用户看到的第一面内页是翻转后才出现的祝福内容。代码如下body main classenvelope-scene div classredpacket idredpacket section classface aria-label红包封面 div classface-head span classseal2023/span h1 classslogan新年快乐/h1 /div !-- SVG 兔子内联放置避免多余的图片请求 -- svg idrabbit-face viewBox0 0 160 120 roleimg aria-label兔年吉祥兔子 !-- 兔子图形在第 3 章展开 -- /svg p classhint点击拆开红包/p /section section classinner aria-label红包内容 svg idrabbit-inner viewBox0 0 160 120 roleimg aria-label内页兔子 !-- 兔子图形在第 3 章展开 -- /svg p classgreeting idgreeting/p button typebutton idagain再拆一次/button /section /div /main canvas idfireworks aria-hiddentrue/canvas script srcmain.js/script /body.face和.inner是同一坐标系下的两个绝对定位层后续用 CSS 的transform: rotateY(180deg)控制翻转。main.js放在 body 末尾是因为脚本要操作的redpacket、greeting、fireworks此时已经在 DOM 里就绪不需要再监听DOMContentLoaded。canvas用来承载烟花粒子它盖不住红包的原因在于后续样式里会给它设置pointer-events: none。代码里我把兔子做成了内联 SVG而不是img srcrabbit.png。原因很实际图片文件一旦丢失或路径写错红包页面上就会出现一个破图图标节日场景里这是致命伤。SVG 内联后整个页面只有一个 HTML 文件加一个 CSS 加一个 JS互相之间的依赖关系简单到了不会出错的程度。3. 兔年视觉内联 SVG 兔子、剪纸兔字与红包封面的 CSS 实现3.1 用 SVG 画一只兔子坐标、颜色与可调参数兔年红包的核心视觉符号是兔子。网上有现成的兔年插画素材但那些大多是 PNG 或 JPG放大模糊、还牵扯版权。我一般会直接用内联 SVG 画一只极简兔子代码在下面svg viewBox0 0 160 120 roleimg aria-label兔年兔子 !-- 左耳 -- ellipse cx58 cy26 rx15 ry36 fill#f8e0d4 stroke#e0a98f stroke-width3/ ellipse cx58 cy26 rx6 ry22 fill#f4b8c8/ !-- 右耳 -- ellipse cx102 cy26 rx15 ry36 fill#f8e0d4 stroke#e0a98f stroke-width3/ ellipse cx102 cy26 rx6 ry22 fill#f4b8c8/ !-- 头 -- ellipse cx80 cy72 rx42 ry36 fill#fdf0e7 stroke#e0a98f stroke-width3/ !-- 腮红 -- circle cx54 cy78 r9 fill#ffb3a7 opacity0.7/ circle cx106 cy78 r9 fill#ffb3a7 opacity0.7/ !-- 眼睛 -- circle cx68 cy68 r4 fill#4a2e1d/ circle cx92 cy68 r4 fill#4a2e1d/ !-- 鼻子 -- ellipse cx80 cy80 rx5 ry3.5 fill#e8836f/ /svgSVG 的viewBox0 0 160 120定义了一个 160×120 的逻辑坐标系之后所有图形都按这个坐标画页面缩放时不变形。兔子的结构分四层耳朵用瘦长椭圆脑袋用扁椭圆腮红和眼睛用正圆。耳朵内部的粉色小椭圆是耳廓fill#f4b8c8让兔子从侧面看有层次感。眼睛的#4a2e1d是深咖啡色而不是纯黑目的是让整体视觉柔和一些和红包的金色元素更搭。如果想把兔子换成其他形象只需要改这些椭圆和圆形的cx、cy、rx、ry数值。比如把耳朵的ry从 36 改成 20兔子就变成了圆脸的猫咪把腮红去掉再加一对角就成了生肖牛。这套参数化画法对不擅长设计的人是最友好的调整数值即可出效果。3.2 红包封面的 CSS渐变、烫金与背景暗纹封面要让用户第一眼认出「这是红包」而不是一张普通的红卡片。红色要有层次金色要能作为点缀但不喧宾夺主。下面是style.css中封面和整体布局的关键部分:root { --red-main: #c7000b; --red-dark: #8f0508; --red-light: #e83a3a; --gold: #f2c46d; --paper: #fdf6ec; } * { margin: 0; padding: 0; box-sizing: border-box; } html, body { height: 100%; } body { display: flex; align-items: center; justify-content: center; background: radial-gradient(circle at 50% 30%, #fdf0e7 0%, #f3d9b8 100%); font-family: PingFang SC, Microsoft YaHei, sans-serif; overflow: hidden; } .redpacket { position: relative; width: min(320px, 86vw); height: min(440px, 74vh); transform-style: preserve-3d; transition: transform 0.7s cubic-bezier(0.2, 0.7, 0.3, 1.1); cursor: pointer; } .face, .inner { position: absolute; inset: 0; border-radius: 18px; backface-visibility: hidden; overflow: hidden; } .face { background: repeating-linear-gradient(45deg, rgba(255, 255, 255, 0.04) 0px, rgba(255, 255, 255, 0.04) 6px, transparent 6px, transparent 12px), linear-gradient(160deg, var(--red-light) 0%, var(--red-main) 45%, var(--red-dark) 100%); box-shadow: 0 12px 40px rgba(140, 20, 10, 0.35); display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 28px 20px; } .seal { display: inline-block; padding: 6px 16px; border: 2px solid var(--gold); border-radius: 8px; color: var(--gold); font-size: 20px; font-weight: 700; letter-spacing: 4px; } .slogan { color: var(--gold); font-size: 34px; letter-spacing: 8px; text-shadow: 0 2px 6px rgba(0, 0, 0, 0.25); }CSS 变量统一放在:root方便替换主题色。如果明年不是兔年而是龙年你只需要把--gold换成更适合的青色把--red-main调暗一点整套页面的气质就变了。background上叠加了两层repeating-linear-gradient生成斜向暗纹模拟红包纸的编织纹理linear-gradient从亮红到暗红过渡让红包有立体感而不是一块纯色。width: min(320px, 86vw)和height: min(440px, 74vh)是响应式的关键小屏手机上红包宽度不超过视口的 86%高度不超过视口的 74%保证拆红包时内页文字不会被挤出屏幕。整套布局用flex居中无论横屏竖屏红包始终在正中间。3.3 剪纸「兔」字与印章效果的替代实现生肖元素除了画兔子还可以在红包封面上放一个剪纸风格的「兔」字。如果引入剪纸图片又回到了图片依赖的问题上。我的做法是用 CSS 的text-shadow模拟剪纸的层叠感.cut-rabbit { font-size: 72px; font-weight: 900; color: var(--red-main); text-shadow: 2px 0 0 var(--gold), -2px 0 0 var(--gold), 0 2px 0 var(--gold), 0 -2px 0 var(--gold); } .rabbit-char { display: inline-block; background: var(--red-main); color: var(--gold); font-size: 26px; font-weight: 700; padding: 8px 14px; border-radius: 50%; border: 3px solid var(--gold); }.cut-rabbit的四个方向的阴影组合起来相当于给文字描了一圈金边视觉上接近剪纸的镂空感。.rabbit-char则是圆形印章配合.face-head里已有的2023方块印章形成「方块印章 圆形生肖章」的组合这是传统红包封面上最常见的元素排布。如果你觉得 CSS 剪纸字不够精细可以把第 3.1 节的 SVG 兔子直接复制一份放在.cut-rabbit的位置再把字号去掉。两种方案并存的好处是你可以按当天手头的素材灵活切换而不需要重新设计布局。4. 兔年红包开合与烟花CSS 3D 翻转、Web Audio 音效和 canvas 粒子4.1 拆红包的翻转交互两个 class 控制完整动效红包从「未拆」到「已拆」的状态切换核心是一段 CSS transition。.redpacket默认rotateY(0deg)展示封面加上.open类后旋转 180 度露出内页。完整代码如下.redpacket.open { transform: rotateY(180deg); } .inner { transform: rotateY(180deg); background: linear-gradient(160deg, var(--paper) 0%, #f7e8d5 100%); display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px; padding: 24px; }.face和.inner都设置了backface-visibility: hidden意思是「背面不可见」。封面默认朝前内页预先旋转 180 度藏在后面当父容器旋转 180 度后封面转到背面隐藏内页转到正面显示。transition的cubic-bezier(0.2, 0.7, 0.3, 1.1)是一个先慢后快再轻微回弹的缓动曲线比默认的ease更有「拆红包」的手感。注意.inner的gap: 16px它控制内页里兔子、祝福文案、按钮三者之间的间距。如果以后要加一张二维码或一张合影只需要改这个值就能调整整体疏密不需要逐个元素去加margin。4.2 用 Web Audio 合成新春音效不需要任何音频文件红包打开时最好有一声音效但audio srcting.mp3在本地文件协议下经常加载失败而且大部分浏览器会拦截未经过用户交互就自动播放的音频。更稳的方案是用 Web Audio API 在浏览器里现场合成音效——零外部文件完全绕开加载和跨域问题。let audioStarted false; function playChime() { if (audioStarted) return; audioStarted true; const ctx new AudioContext(); const master ctx.createGain(); master.gain.value 0.35; master.connect(ctx.destination); // 第一声高音“叮” playTone(ctx, master, 1318.5, 0, 0.8, sine); // 第二声低音“当”延迟 0.18 秒模拟敲锣 playTone(ctx, master, 196, 0.18, 1.4, triangle); } function playTone(ctx, dest, freq, delay, duration, type) { const osc ctx.createOscillator(); const gain ctx.createGain(); const t0 ctx.currentTime delay; osc.type type; osc.frequency.value freq; gain.gain.setValueAtTime(0.0001, t0); gain.gain.exponentialRampToValueAtTime(0.5, t0 0.02); gain.gain.exponentialRampToValueAtTime(0.0001, t0 duration); osc.connect(gain); gain.connect(dest); osc.start(t0); osc.stop(t0 duration 0.1); }AudioContext必须在用户点击之后创建所以我把playChime()放在点击事件里调用。createGain是一个音量控制节点master.gain.value 0.35把整体音量压到 35%避免突然出声吓到用户。playTone里用exponentialRampToValueAtTime控制音量从极低升到峰值再衰减模拟出「叮——」的自然余音而不是简单粗暴的方波爆音。振荡器类型上sine干净适合高音triangle柔和适合低频锣声。这套合成音效完全依赖浏览器能力不会产生任何网络请求因此在file://协议下双击打开 HTML 文件时依然能正常出声。4.3 canvas 烟花粒子参数与发射逻辑烟花是本页最复杂的部分但核心逻辑也就是「生成粒子、给初速度、每一帧更新位置、绘制、衰减」。代码如下const canvas document.getElementById(fireworks); const ctx canvas.getContext(2d); canvas.width window.innerWidth; canvas.height window.innerHeight; const particles []; const COLORS [#f2c46d, #e83a3a, #fff2c8, #ff8a5c]; function launchFirework() { const x window.innerWidth * (0.2 Math.random() * 0.6); const y window.innerHeight * (0.15 Math.random() * 0.4); const color COLORS[Math.floor(Math.random() * COLORS.length)]; const count 70 Math.floor(Math.random() * 40); for (let i 0; i count; i) { const angle (Math.PI * 2 * i) / count; const speed 1.5 Math.random() * 2.5; particles.push({ x, y, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed, life: 1, decay: 0.012 Math.random() * 0.015, color }); } } function drawParticles() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (let i particles.length - 1; i 0; i--) { const p particles[i]; p.x p.vx; p.y p.vy; p.vy 0.045; // 模拟重力 p.vx * 0.985; // 空气阻力 p.life - p.decay; if (p.life 0) { particles.splice(i, 1); continue; } ctx.globalAlpha p.life; ctx.fillStyle p.color; ctx.beginPath(); ctx.arc(p.x, p.y, 2.2, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha 1; requestAnimationFrame(drawParticles); } function startFireworks() { launchFirework(); setInterval(() { if (document.hidden) return; launchFirework(); }, 900); }粒子属性里有几个值得调的参数。decay是粒子寿命衰减速度0.012 到 0.027 之间的随机值让每个粒子的消失时间不一致炸开后会有先后掉落的感觉。p.vy 0.045是重力加速度数值越大烟花越早往下坠想要「高开花、慢下落」就调小到 0.02 左右。vx * 0.985是空气阻力让粒子慢慢减速而不是匀速飘走。document.hidden的检查是防止页面切到后台时定时器还在白白跑粒子消耗手机电量。4.4 开红包的完整事件时序交互的时序决定了「拆红包」的节奏感。事件被整理如下时间点触发动作对应代码0ms用户点击红包封面packet.classList.add(open)0ms播放合成音效playChime()180ms封面开始翻转音效第二声响起CSS transition 执行中900ms翻转完成内页完全可见transition 结束900ms触发第一朵烟花startFireworks()900ms 起每 900ms 追加一朵烟花setInterval1200ms祝福文案逐字出现typeGreeting()const MSG 兔年大吉万事顺遂; function tieUp() { const packet document.getElementById(redpacket); const againBtn document.getElementById(again); let isOpening false; packet.addEventListener(click, () { if (isOpening) return; isOpening true; packet.classList.add(open); playChime(); startFireworks(); typeGreeting(); }); againBtn.addEventListener(click, (e) { e.stopPropagation(); packet.classList.remove(open); document.getElementById(greeting).textContent ; isOpening false; audioStarted false; }); } function typeGreeting() { const el document.getElementById(greeting); let i 0; const timer setInterval(() { el.textContent MSG.slice(0, i 1); i; if (i MSG.length) clearInterval(timer); }, 90); } tieUp();isOpening标志位防止用户在翻转动画未完成时反复点击导致动画错乱。againBtn上的stopPropagation很关键按钮本身在.inner里面点击「再拆一次」如果冒泡到父容器会立刻重新触发open红包还没合上又被打开了。audioStarted false的重置让「再拆一次」后音效可以重新播放同时每次点击都会创建新的 AudioContext旧的会被浏览器自动回收。5. 把 HTML 源码真正发出去本地验证、单文件合并与改动技巧5.1 双击打不开或样式丢失时的排查顺序搜「HTML新年快乐2023源代码」的人最常见的困境不是代码不对而是拿到了代码却跑不起来。双击 index.html 出现乱码检查 head 里有没有meta charsetutf-8样式完全没有生效说明style.css的路径不对确认index.html里link的href和 css 文件在同一目录点击红包没反应打开浏览器控制台F12看main.js有没有报错最常见的错误是document.getElementById拿不到元素——这通常是因为 script 标签写到了 head 里而 body 还没加载完。cd rabbit-redpacket python3 -m http.server 8080本地起一个静态服务能解决file://协议下的部分兼容问题。上面代码在项目目录执行后浏览器打开http://localhost:8080即可访问。不想装 Python 的可以用npx serve .一样的效果。5.2 合并成单个 HTML把样式和脚本内联回去如果想把页面作为单个 HTML 文件发给同事直接把style.css的内容用style标签包起来放进 head把main.js用script标签包起来放回 body 末尾即可。合并后代码结构如下!doctype html html langzh-cn head meta charsetutf-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title2023 兔年红包/title style /* 原 style.css 全部内容 */ /style /head body !-- 原 body 结构 -- script // 原 main.js 全部内容 /script /body /html内联之后文件体积会上升到 20KB 左右对静态页面没有影响。但要留意script 必须放在 body 最后否则getElementById在 DOM 未就绪时拿不到元素。5.3 改动技巧年份、生肖与文案的替换入口想让这个红包明年继续用翻到第 3.2 节的:root把--red-main从红色换成青色把--gold从金色换成银色一份「青蛇年红包」的主题就出来了。SVG 兔子的耳朵椭圆如果改成细长的等腰三角形再拉长头部就是蛇的抽象造型。祝福文案在main.js顶部的MSG常量里改一次性把「兔年大吉」换成「龙行龘龘」这类当年热词即可。如果要把红包发给别人并引导对方扫码领奖把第 2.3 节.inner里的p classgreeting后面直接插入img srcqrcode.png即可但注意图片要走相对路径不要用本地绝对路径C:/Users/...否则别人打开时图片必挂。打开控制台确认 Network 面板里没有红色 404 记录再在手机浏览器里跑一遍完整拆封流程确认音效在「用户点击后」才初始化——这个红包页面就能稳定跑完整个打开过程了。本文还有配套的精品资源点击获取
返回列表