我把我的Portfolio藏在漆黑中。Google Gemini帮助我点燃了火把。

发布: (2026年3月1日 GMT+8 20:15)
5 分钟阅读
原文: Dev.to

Source: Dev.to

这是对Built with Google Gemini: Writing Challenge的提交

depapp portfolio

我用 Google Gemini 构建的项目

作品集本该展示你作为工程师的独特之处。然而,随着时间的推移,我们都开始做同样的事:一个简洁的页眉、一组弹性的 CSS 网格项目卡片,以及一个巨大的“联系我”按钮。我意识到,发现工程师作品的最佳方式并不仅仅是阅读内容本身,而是发现的过程本身。

于是,我决定把我的整个简历投进漆黑之中。

我打造了 交互式手电筒作品集——一个实验性的、移动优先的单页应用(SPA),屏幕始终保持全黑。唯一阅读我的个人简介、技能或查看项目的方式,是在屏幕上拖动一个虚拟的、闪烁的“手电筒”,在黑暗中切出一块光亮的区域。

我没有使用 React、Next.js 或任何大型库,而是纯粹用 HTML、CSS 和原生 DOM 操作来实现。计算移动手电筒的物理效果并处理复杂的 HTML5 Canvas 混合模式本会是个巨大的难题——直到 Google Gemini 作为我的数学搭档程序员出现。

演示

您可以在 Google Cloud Run 部署上实时体验作品集(使用轻量级 nginx:alpine 镜像进行容器化)。无需额外设置——只需打开链接并开始拖动火把。

Source:

我学到的内容

高级 Canvas 混合模式(技术深度)

我加深了对 HTML5 Canvas API 的理解,尤其是 globalCompositeOperation。目标是渲染全黑画面,并在鼠标移动的地方“切出”一个透明孔。Gemini 帮我实现了这段逻辑,同时不影响浏览器的帧率:

// Fill the screen with darkness
ctx.fillStyle = '#050505';
ctx.globalCompositeOperation = 'source-over';
ctx.fillRect(0, 0, width, height);

// "Cut out" the darkness using the glowing gradient
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = gradient; // radial gradient for soft edges
ctx.beginPath();
ctx.arc(startX, startY, maxRadius, 0, Math.PI * 2);
ctx.fill();

掌握如何在同一个 <canvas> 元素上叠加 destination-out(手电筒光束)和 screen/lighter(环境火焰光晕)令人非常有成就感。

将物理机制转化为交互

普通的自定义光标感觉轻飘飘的。我希望我的火把感觉沉重。与 Gemini 合作让我学会如何把视觉物理学转化为可执行的提示。我描述了逻辑:“根据鼠标移动速度让火把像沉重的摆锤一样倾斜”,Gemini 生成了必要的 Math.cosMath.sin 旋转矩阵,使 SVG 火把在枢轴上真实摆动。

原生性能的力量

仅依赖 requestAnimationFrame 和 Canvas 上下文,而不使用虚拟 DOM 差分,使得应用瞬间加载,并在渲染数百个受数学驱动的火焰粒子时仍能保持流畅的 60 FPS。

Google Gemini 反馈

什么做得很出色

Gemini 在长时间的架构讨论中保持上下文的能力无与伦比。当我从现代手电筒切换到中世纪风格的木质火把时,我只需让 Gemini “将手电筒元素改为冒火的木质火把,但保留噪声叠加和我们之前讨论的物理”。它在尊重现有 z‑index 层的前提下生成了新的 SVG 坐标。将摩擦、重力和摆动等概念转化为 JavaScript 数学公式,为我节省了在 MDN 文档中查找的数小时。

我遇到的阻力

我必须明确提示 Gemini 对移动端触摸事件进行优化。火把效果最初在桌面上 mousemove 能正常工作,但在 touchmove/touchstart 上却不行,导致滚动异常。Gemini 最终提供了正确的代码(添加 { passive: true }),但我必须先发现这个问题。它有时还需要被引导使用原生 CSS Flexbox 方案,而不是立即使用 JavaScript 视口计算来实现隐藏内容的网格布局。

0 浏览
Back to Blog

相关文章

阅读更多 »

当工作成为心理健康风险时

markdown !Ravi Mishrahttps://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fu...