几何图案背景特效(Canvas 几何图形动画,5 种形状可切换)
几何图案背景特效:三角形、正方形、六边形、五角星、圆环五种形状在网格中旋转呼吸,色相缓慢漂移,形状与速度密度实时切换,Canvas 自研适配高分屏。
效果演示(真实可交互)
画布按网格排布几何图形,每个格子里的图形都在做两件事:绕自身中心匀速旋转,以及按各自相位做”呼吸式”缩放。由于每个格子的相位由行列坐标决定(r + c 的组合),相邻图形之间总是存在错位,整体看起来像一片有规律又不断变化的动态纹理。色相会随时间整体缓慢漂移,画面颜色从蓝紫到青绿再到橙红循环过渡。下拉框可以在三角形、正方形、六边形、五角星、圆环五种形状间即时切换,「旋转速度」控制整体节奏,「网格密度」改变图形大小与疏密。
完整代码
<canvas id="geo" style="width:100%;height:340px;display:block;background:radial-gradient(120% 120% at 50% 20%,#101426,#070910);"></canvas>
const canvas = document.getElementById('geo');
const ctx = canvas.getContext('2d');
let W, H, t = 0;
const cfg = { shape: 'triangle', speed: 6, density: 72 };
function resize() {
const r = canvas.getBoundingClientRect();
const dpr = window.devicePixelRatio || 1;
canvas.width = Math.round(r.width * dpr);
canvas.height = Math.round(r.height * dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
W = r.width; H = r.height;
}
function drawShape(type, x, y, s, rot, hue, alpha) {
ctx.save(); ctx.translate(x, y); ctx.rotate(rot);
ctx.strokeStyle = `hsla(${hue}, 80%, 65%, ${alpha})`;
ctx.lineWidth = 1.5;
ctx.beginPath();
if (type === 'triangle') {
ctx.moveTo(0, -s); ctx.lineTo(s * .87, s * .5); ctx.lineTo(-s * .87, s * .5); ctx.closePath();
} else if (type === 'square') {
ctx.rect(-s * .7, -s * .7, s * 1.4, s * 1.4);
} else if (type === 'hexagon') {
for (let i = 0; i < 6; i++) {
const a = i / 6 * Math.PI * 2;
i === 0 ? ctx.moveTo(Math.cos(a) * s, Math.sin(a) * s) : ctx.lineTo(Math.cos(a) * s, Math.sin(a) * s);
}
ctx.closePath();
} else if (type === 'star') {
for (let i = 0; i < 10; i++) {
const rr = i % 2 === 0 ? s : s * .45;
const a = i / 10 * Math.PI * 2 - Math.PI / 2;
i === 0 ? ctx.moveTo(Math.cos(a) * rr, Math.sin(a) * rr) : ctx.lineTo(Math.cos(a) * rr, Math.sin(a) * rr);
}
ctx.closePath();
} else {
ctx.arc(0, 0, s * .6, 0, Math.PI * 2);
}
ctx.stroke(); ctx.restore();
}
function step() {
t += .01 * cfg.speed;
ctx.clearRect(0, 0, W, H);
const cell = cfg.density;
for (let r = 0; r < Math.ceil(H / cell) + 1; r++) {
for (let c = 0; c < Math.ceil(W / cell) + 1; c++) {
const cx = c * cell + cell / 2, cy = r * cell + cell / 2;
const rot = t * .8 + (r + c) * .45;
const s = cell * .3 * (1 + .18 * Math.sin(t * 1.4 + r * .7 + c * .5));
const hue = (t * 12 + r * 14 + c * 18) % 360;
const alpha = .4 + .35 * Math.sin(t * .8 + r + c);
drawShape(cfg.shape, cx, cy, s, rot, hue, Math.max(.15, alpha));
}
}
requestAnimationFrame(step);
}
resize(); step();
window.addEventListener('resize', resize);
参数说明
| 参数 | 位置 | 说明 |
|---|---|---|
| 形状 | cfg.shape | triangle / square / hexagon / star / circle |
| 旋转速度 | cfg.speed | 0-20,0 即静止 |
| 网格密度 | cfg.density | 40-120px 格距,越小图形越多越密 |
| 相位错位 | (r + c) * .45 | 行列组合决定各格节奏差 |
| 色相漂移 | t * 12 + ... | 数值越大颜色变化越快 |
| 描边样式 | ctx.lineWidth | 可改为 fill 实现实心几何 |
兼容性与性能
- 仅使用 Canvas 2D 基础 API,兼容所有现代浏览器;HSLA 颜色 IE9+ 支持。
- 已做
devicePixelRatio适配,高分屏线条清晰。 - 密度 72px 时约 12×7 = 84 个图形,每帧 84 次 save/restore + stroke,开销很小;密度 40px 时图形数量翻倍,低端机可酌情调大。
- 所有角度计算均为纯数学,无 DOM 操作、无外部依赖,滚动页面时画布内容不受影响。
- 想要静态几何背景时把
cfg.speed设为 0 即可,图形定格但仍保留色相漂移,或一并去掉。
常见问题
Q: 为什么我的图形看起来在”抖动”而不是平滑旋转? 通常是旋转与呼吸缩放叠加后视觉上的错觉,把 s 的缩放系数(0.18)调小或把呼吸频率 t * 1.4 调低即可让运动更平缓。
Q: 如何改成实心几何图形? 把 ctx.stroke() 换成 ctx.fill(),并把 strokeStyle 改成 fillStyle,同时给 alpha 乘以一个更小的系数避免整体太亮。
Q: 想做六边形蜂巢错位排列? 默认是方形网格。要蜂巢效果,需要让奇数行整体右移半个格距(cx += (r % 2) * cell / 2),六边形旋转 30 度即可。
Q: 图案和文本叠加时对比度不够? 几何图形是描边细线,天然比实心图形更不干扰文字;若仍不够,可给文字容器加深色半透明底,或降低 alpha 的最大值。
许可与来源
- 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
- 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
- 首次发布:2026-09-01 · 最近更新:2026-09-01
- 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
- 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理
常见问题
这个组件可以商用吗?
可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。
浏览器兼容性如何?
支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。
怎么修改动画参数?
直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。