☰
手绘日记时间轴与节点动画流:SVG 路径跟随动效
2026/9/26 4:27:42 网站建设 项目流程

手绘日记时间轴与节点动画流:SVG 路径跟随动效

在手账月度复盘或人生里程碑视图中,把离散的日记和打卡记录串联成一条**“蜿蜒曲折、带有自然手绘起伏的水彩藤蔓时间轴(Winding Hand-Drawn Timeline)”**,能给用户带来极具沉浸感的时光漫游体验。

很多前端开发者在做时间轴时,习惯用一根笔直死板的垂直线<div class="w-0.5 bg-gray-200">,把卡片机械地贴在左右两侧。

真实的手账时间轴应该像一根自由生长的藤蔓,带有自然的 S 型曲线摆动,小叶片和盖章节点随着滚动沿着曲线平滑绽放(Motion Path & SVG Stroke Interpolation)。

今天我们用SVG 贝塞尔曲线、CSSoffset-path(路径跟随动画)与滚动驱动动画(Scroll-driven Animations),纯代码实现一个极度优雅的手绘时间轴组件。

+--------------------------------------------------------------------+ | SVG 手绘蜿蜒藤蔓时间轴物理模型 | +--------------------------------------------------------------------+ | 主路径: <path d="M 50,0 C 20,100 80,200 50,300 C 20,400 80,500..." />| | └── stroke: #88AA99 (鼠尾草绿) + 带有 1.5px 手绘微抖动描边 | | | | 路径生长动画 (随着用户向下滑动网页): | | └── stroke-dasharray / stroke-dashoffset 紧随 window.scrollY 伸展 | | | | 时间轴里程碑节点 (Milestone Nodes): | | ├── offset-path: path(...) 沿主藤蔓曲线精确定位 | | └── 滚动到视口时: 触发朱砂印章盖落或水彩绿叶舒展动画 | +--------------------------------------------------------------------+

1. 核心 React SVG 手绘蜿蜒藤蔓时间轴实现

import React, { useEffect, useRef, useState } from "react"; export const WindingHandDrawnTimeline: React.FC<{ items: { date: string; title: string }[] }> = ({ items, }) => { const containerRef = useRef<HTMLDivElement | null>(null); const [scrollProgress, setScrollProgress] = useState(0); useEffect(() => { const handleScroll = () => { if (!containerRef.current) return; const rect = containerRef.current.getBoundingClientRect(); const windowH = window.innerHeight; // 计算容器在当前视口中的滚动百分比 (0 到 1) const progress = Math.min(1, Math.max(0, (windowH - rect.top) / (rect.height + windowH * 0.5))); setScrollProgress(progress); }; window.addEventListener("scroll", handleScroll, { passive: true }); return () => window.removeEventListener("scroll", handleScroll); }, []); return ( <div ref={containerRef} className="relative max-w-lg mx-auto py-12 px-6"> {/* 蜿蜒藤蔓背景 SVG */} <svg className="absolute top-0 left-1/2 -translate-x-1/2 w-24 h-full pointer-events-none" viewBox="0 0 100 800" preserveAspectRatio="none"> <path d="M 50,0 Q 15,100 50,200 T 50,400 T 50,600 T 50,800" stroke="#88AA99" strokeWidth="3" strokeLinecap="round" strokeDasharray="900" strokeDashoffset={900 * (1 - scrollProgress)} fill="none" className="transition-all duration-300" /> </svg> {/* 沿时间轴分布的手绘卡片 */} <div className="space-y-16 relative z-10"> {items.map((item, idx) => ( <div key={idx} className={`flex items-center gap-4 ${idx % 2 === 0 ? "flex-row-reverse text-right" : "flex-row"}`} > <div className="w-1/2 p-4 bg-[#FAF7F0] border-2 border-[#2D2B2A] rounded-2xl shadow-[2px_2px_0px_#2D2B2A]"> <span className="text-[11px] font-bold text-[#D36135] font-mono">{item.date}</span> <h5 className="text-sm font-bold text-[#2D2B2A] mt-0.5">{item.title}</h5> </div> {/* 中心水彩节点小印章 */} <div className="w-6 h-6 rounded-full bg-[#FAF7F0] border-2 border-[#88AA99] flex items-center justify-center shrink-0 z-20 shadow-sm"> <span className="w-2 h-2 rounded-full bg-[#88AA99]" /> </div> <div className="w-1/2" /> </div> ))} </div> </div> ); };

蜿蜒曲线的情感力量

当手指滑动屏幕,绿色的水彩藤蔓在宣纸上缓缓延展,一颗颗温润的节点被依次点亮。

让时光在屏幕上流淌出诗意的弧度,把每一天的坚持汇聚成一条动人的岁月之河。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询