Ten Years Away: Designing an Interactive Comic for Studio375’s Tenth Anniversary十年光阴:为 Studio375 十周年庆典设计交互式漫画

The story behind “Ten Years Away”, a scroll-driven interactive comic created to celebrate Studio375’s tenth anniversary, from its printed origins to its WebGL implementation.《十年光阴》(Ten Years Away)背后的故事:这是一个为庆祝 Studio375 十周年而创作的滚动交互式漫画,从最初的印刷版到最终的 WebGL 实现,记录了其创作历程。

Ready to become a GSAP expert? Access the world’s most comprehensive GSAP training with 300+ lessons. Enroll now →准备好成为 GSAP 专家了吗?获取全球最全面的 GSAP 培训课程,包含 300 多节课。立即报名 →

Ten years is a strange thing to hold. You’ve been going, head down, client after client, deadline after deadline, and then one morning someone says it’s been ten years, and you don’t quite have the words for what that means.十年是一个很奇妙的跨度。你一直埋头苦干,应对一个又一个客户,赶着一个又一个截止日期,直到某天早上有人提醒你已经过去十年了,你却不知该如何描述这段时光的意义。

We didn’t want to mark it with a new portfolio site. The usual kind: a refined grid of case studies, a clean about page, a nice animation on the hero. That felt like putting a bow on a filing cabinet. A portfolio says: here is what we have made. But an anniversary is something different. An anniversary has characters. It has chapters. It has people who arrived and changed things and eventually moved on, and a shape that only becomes visible once enough time has passed.我们不想用一个常规的展示型网站来纪念它。那种常见的:精致的案例网格、简洁的关于页面、首屏炫酷的动画。那感觉就像是给档案柜系了个蝴蝶结。作品集是在说:这是我们做过的东西。但周年纪念不同。周年纪念有角色,有章节。它记录了那些加入并改变了我们的人,以及那些最终离开的人;它呈现出一种只有经过足够的时间沉淀后,才会显现的轮廓。

So we made a comic.于是,我们做了一本漫画。

Ten chapters, one per year, illustrated by Davide Grazi, a local illustrator we know and love, who spent months working with us to give every year its own visual character. From the start, we knew we didn’t want a retrospective that felt like a press kit. Davide’s work is what made that possible. He drew the people. The actual people who showed up, who left their mark, who made each year what it was. Each chapter captures what happened: who joined the studio, who left, what the work felt like, what the vibe was like during those months. 十个章节,一年一章,由我们熟悉且喜爱的本地插画师 Davide Grazi 绘制。他花了数月时间与我们合作,为每一年赋予了独特的视觉特征。从一开始,我们就明确不想做一个像新闻通稿那样的回顾。Davide 的作品让一切成为可能。他画的是人,是那些真实出现过、留下印记并塑造了每一年的伙伴们。每一章都捕捉了当时发生的事情:谁加入了工作室,谁离开了,工作是什么感觉,那几个月的氛围如何。

The tone is funny and a little hyperbolic. Ten years of real people, with all the warmth and awkwardness that comes with that.基调是幽默且略带夸张的。这是十年来真实的人,带着那份特有的温暖与笨拙。

We also wanted it to exist as a physical object. Before a single line of WebGL was written, there was a printed version: designed, laid out, and actually printed on paper. Something about this story felt like it needed weight, not the kind that lives in a browser tab and disappears the moment you close it, but the kind that sits on a desk or in a drawer.我们还希望它能以实体形式存在。在写下第一行 WebGL 代码之前,我们先有了印刷版:经过设计、排版,并最终印制在纸上。这个故事似乎需要某种重量感,不是那种活在浏览器标签页里、一旦关闭就消失的东西,而是那种可以放在桌上或抽屉里的存在。

The interactive experience came after, as a way of sharing the same story with the rest of the world.交互式体验是在那之后制作的,作为与世界分享同一故事的媒介。

One Year Later一年之后

There’s a line on the site: one year later…网站上有一行字:一年之后……

It’s not decorative.这不是装饰。

The project started in 2025. We had early scroll tests, our first WebGL experiments, preliminary panel layouts. And then, as tends to happen, client work piled up, priorities shifted, and the whole thing went into a drawer.项目始于 2025 年。我们进行了早期的滚动测试、最初的 WebGL 实验和初步的版面布局。然后,正如常有的那样,客户工作堆积如山,优先级发生变化,整个项目被束之高阁。

2025 preliminary drafts2025 年初步草稿

We picked it back up in 2026. Starting again after a year is uncomfortable in a specific way: you can’t pretend the choices you made the first time were inevitable. You see them as choices. You stop justifying the early decisions and start asking whether they were actually right, and sometimes the answer is no.我们在 2026 年重新拾起它。时隔一年重新开始有一种特别的别扭感:你无法假装当初的决定是必然的。你会审视它们,不再为早期的决策辩解,而是开始质疑它们是否真的正确,有时答案是否定的。

So we put it in the copy. “One year later” is on the site because it happened, because better late than never, and because keeping a promise to yourself still counts even when it takes a year longer than planned.所以我们把它写进了文案里。“一年之后”出现在网站上,是因为它确实发生了,因为迟到总比不到好,也因为即使比计划晚了一年,对自己许下的承诺依然算数。

How the Experience Works体验是如何运作的

The site is a scroll-driven horizontal comic. As you scroll, the camera drifts through the panels of each chapter, following your progress through the year. Everything visual runs inside a fixed WebGL canvas built with React Three Fiber. Lenis handles the smooth scroll, feeding real-time position data into the scene. GSAP drives the animations, along with the layer that sits above the canvas: captions, chapter titles, and the other text elements living outside it.该网站是一个滚动驱动的横向漫画。当你滚动时,镜头会在每一章的画格间穿梭,跟随你走过那一年。所有视觉内容都在由 React Three Fiber 构建的固定 WebGL 画布中运行。Lenis 处理平滑滚动,将实时位置数据输入场景。GSAP 驱动动画,以及画布上方的层:字幕、章节标题和其他画布外的文本元素。

Content comes from a headless WordPress backend, where each year is its own custom post type. On the Three.js side, frame positions and camera targets are hard coded per year in a data file. That was partly to give us precise spatial control over how each chapter reads as a composition, and partly because we never built the scenes in Blender first. Everything was placed directly in Three.js, by feel, iterating in the browser. Hard coding the coordinates was less a design decision than a natural consequence of how we worked.内容来自 Headless WordPress 后端,每一年的内容都是一个自定义文章类型。在 Three.js 端,每年的帧位置和镜头目标都在数据文件中硬编码。这部分是为了让我们能精确控制每一章作为构图的阅读体验,部分原因是我们从未在 Blender 中预先构建场景。一切都是直接在 Three.js 中通过感觉进行放置,并在浏览器中迭代。硬编码坐标与其说是一个设计决策,不如说是我们工作方式的自然结果。

The background is a GLSL shader plane that responds to scroll velocity. The shadows themselves are generated in the fragment shader using fBm noise, layered octaves of Perlin noise that give the patches their organic, irregular quality.背景是一个响应滚动速度的 GLSL 着色器平面。阴影本身是在片段着色器中使用 fBm 噪声生成的,通过层叠的 Perlin 噪声,赋予了斑点有机且不规则的质感。

At rest, or while scrolling slowly, they spread across the plane in loose clusters, like smoke. Scroll faster, and they stretch into thin, directional, elongated streaks that blur the sense of place and push the feeling toward speed, toward time passing. It’s subtle, but it earns its place.在静止或缓慢滚动时,它们像烟雾一样散布在平面上。滚动加快时,它们会拉伸成细长、有方向性的线条,模糊了空间感,并增强了速度感和时光流逝的感觉。这很微妙,但恰到好处。

What we saw in our minds 🙂我们脑海中的景象 🙂

When you move from one year to the next, the background’s soft shadows dissolve first. Then the individual panels of the new chapter appear separately, scattered, not yet in place, and slide into alignment before merging into the full page. The year assembles itself in front of you. 当你从一年切换到下一年时,背景的柔和阴影会先消散。接着,新章节的各个画格会分别出现,四散开来,尚未就位,然后滑入对齐,最后合成为完整的一页。这一年就在你眼前逐渐拼凑而成。

It’s meant to feel less like a page load and more like something arriving.它给人的感觉不像是在加载页面,更像是一种事物的到来。

The Book Navigation书本导航

This page shows a different experience: a 3D flipbook, rendered entirely in Three.js. Each sheet of the book is a BoxGeometry. Drag left, and the page turns forward; drag right, and it turns back. Gesture handling runs through @use-gesture/react, while GSAP drives the actual flip animations. Page turns are accompanied by sound. The book slides in from off-screen on entry, rotates into place, and exits the same way when you navigate to a different year.这一页展示了另一种体验:完全在 Three.js 中渲染的 3D 翻页书。书的每一页都是一个 BoxGeometry。向左拖动,页面向前翻;向右拖动,页面向后翻。手势处理通过 @use-gesture/react 运行,而 GSAP 驱动实际的翻页动画。翻页伴随着音效。书本在进入时从屏幕外滑入,旋转到位,并在你导航到不同年份时以同样的方式退出。

Mouse Trail鼠标轨迹

We kept asking ourselves: how do you make a webpage feel like a comic without leaning on illustration alone?我们一直在问自己:如何在不单纯依赖插画的情况下,让网页感觉像一本漫画?

When you move the mouse, it leaves a trail. Under the hood, it’s a two-pass WebGL effect: the first pass accumulates the movement into a render texture that slowly fades, and the second converts it into a halftone dot pattern. But the reason we built it isn’t technical. It’s that the benday dot, the grid of tiny circles that gives offset printing its texture, is one of the most recognizable marks of the medium.当你移动鼠标时,它会留下轨迹。在底层,这是一个两遍 WebGL 特效:第一遍将运动累积到一张缓慢淡出的渲染纹理中,第二遍将其转换为半色调圆点图案。我们这样做的原因并非出于技术,而是因为本戴圆点(Benday dots)——那种赋予胶印质感的微小圆点网格——是该媒介最显著的特征之一。

We wanted that reference to live in the interaction itself, not just in the illustrations. The dots follow you across the page, bleed onto the panels, and shrink quietly when you hover over something clickable. A small thing, but it mattered to us that the comic logic ran all the way through, not just in the artwork, but in how you move through the experience.我们希望这种参考存在于交互本身,而不仅仅是在插画中。圆点跟随你穿过页面,渗入画格,并在你悬停在可点击元素上时悄然缩小。这是一个微小的细节,但对我们来说,漫画的逻辑必须贯穿始终,不仅在艺术作品中,更在于你如何在体验中穿行。

Optimizations优化

For the panel textures, we used KTX2 compression via useKTX2 from React Three Fiber’s drei library. The format is interesting because it skips CPU decoding before upload entirely: the GPU reads it directly, in its native compressed format. We’d seen it used on projects we admired and wanted to understand how it worked in practice.对于画格纹理,我们使用了 React Three Fiber 的 drei 库中的 useKTX2 进行 KTX2 压缩。这种格式很有意思,因为它完全跳过了上传前的 CPU 解码:GPU 直接以其原生的压缩格式读取。我们曾在钦佩的项目中见过它,并想了解它在实践中是如何运作的。

We put real thought into keeping things light. All the comic panels share a single PlaneGeometry instance rather than allocating new geometry per mesh. We capped the device pixel ratio at 1.5 and disabled WebGL features the scene doesn’t use, like the stencil buffer and shadow maps. AdaptiveDpr drops the resolution further if the framerate falls. Materials and GSAP timelines are explicitly disposed of on unmount, so nothing accumulates across navigation. And textures for the next chapter are preloaded during the page transition, so the wait when moving between years is as short as possible.我们非常用心地保持轻量化。所有漫画画格共享一个 PlaneGeometry 实例,而不是为每个网格分配新的几何体。我们将设备像素比限制在 1.5,并禁用了场景中未使用的 WebGL 功能,如模板缓冲区和阴影贴图。如果帧率下降,AdaptiveDpr 会进一步降低分辨率。材质和 GSAP 时间轴在卸载时会被显式销毁,因此导航过程中不会有任何累积。下一章的纹理会在页面过渡期间预加载,从而尽可能缩短切换年份时的等待时间。

Is it perfect? No, there are things we’d do differently. 它完美吗?不,有些地方我们本可以做得不同。

But it’s ours, and that counts for something.但它是属于我们的,这就很有意义。

Sound as a Chapter作为章节的音频

Each year has its own audio track, chosen to match the mood of that chapter’s narrative, not to fill silence. It’s a small editorial decision that ends up mattering more than you’d expect: the right piece of music changes how you read a page.每一年都有自己的音轨,选择它是为了匹配该章节叙事的氛围,而不是为了填补寂静。这是一个小小的编辑决策,但最终产生的影响比你预期的要大:合适的音乐会改变你阅读页面的方式。

Under the hood, audio is managed via Howler.js. Tracks crossfade as you move between years. On desktop, scroll velocity nudges the playback rate slightly: scroll faster, and the music accelerates with you.在底层,音频通过 Howler.js 管理。当你切换年份时,曲目会交叉淡入淡出。在桌面上,滚动速度会轻微改变播放速率:滚动越快,音乐也随之加速。

We also skip audio entirely on slow connections. Before anything plays, we check the Network Information API for saveData, 2G, or 3G signals. If the connection looks slow, the music simply doesn’t start. It’s not a dramatic optimization, but it felt like the right call: audio was the heaviest asset on mobile, and forcing it on a weak connection would have been worse than silence.我们还在网络连接缓慢时完全跳过音频。在播放任何内容之前,我们会通过 Network Information API 检查 saveData、2G 或 3G 信号。如果连接看起来很慢,音乐就不会启动。这不是什么戏剧性的优化,但我们觉得这是正确的做法:音频是移动端最重的资源,在弱网环境下强行加载音频比静音更糟糕。

What Building for Yourself Feels Like为自己创作的感觉

This is the part that surprised us most.这是最让我们感到惊讶的部分。

We build things for clients all the time. There’s always a brief. There’s always someone else’s judgment to factor in, someone to push back if you’re going wrong. Building something to celebrate yourself, with no client in the picture, is a different kind of pressure. The only person who can tell you whether it’s good enough is you, and it turns out that’s not as freeing as it sounds.我们一直在为客户制作项目。总有简报,总有他人的评判需要考量,如果方向错了总有人会提出异议。为了庆祝自己而创作,没有客户在场,这是一种不同类型的压力。唯一能告诉你它是否足够好的人就是你自己,事实证明,这并不像听起来那么自由。

What we didn’t expect was how much we’d learn about what the studio actually is by trying to tell its story. You spend ten years inside something and you don’t always see it clearly. Making a comic about those years forces a kind of reckoning: really thinking about each one, choosing what to show and what to leave out, figuring out who the characters actually are. It’s worth it.我们没想到的是,通过讲述自己的故事,我们对工作室的本质有了如此深刻的认识。你在一个地方待了十年,并不总是能看清它。制作一部关于这些年的漫画迫使我们进行了一种清算:真正思考每一年,选择展示什么、舍弃什么,弄清楚角色到底是谁。这一切都是值得的。

For a small studio, getting to ten years isn’t nothing. 对于一个小工作室来说,走到十年并不容易。

We’ve made it with a lot of help from a lot of people, and this project was our attempt to say that out loud instead of just feeling it privately.我们是在许多人的帮助下走到这一步的,这个项目是我们试图大声说出这份感激,而不是仅仅将其埋藏在心底。

Thank you谢谢

This wouldn’t exist without our team, and without everyone, no exceptions, who has passed through Studio375 at any point over the past ten years.没有我们的团队,没有过去十年中任何一位曾在 Studio375 驻足过的人(无一例外),这一切都不会存在。

We’re still going.我们仍在前行。

If you found this useful, or just enjoyed the read, you can follow our work here: InstagramLinkedIn, 375.studio如果你觉得这有帮助,或者只是喜欢阅读,欢迎在这里关注我们的工作:Instagram, LinkedIn, 375.studio

Creative Spotlights

Inside the journeys and portfolios of today's most inspiring designers and developers.

Studio Stories

Discover how studios & agencies started, how they work, and what they've built.

Case Studies

Discover the ideas, design, and craft behind today’s most inspiring web experiences.

Learn with Tutorials

Level up your front-end skills with practical, step-by-step tutorials.