<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>Valen</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <icon>https://blog.talentstore.cn/favicon.png</icon>
  <id>https://blog.talentstore.cn/</id>
  <link href="https://blog.talentstore.cn/" rel="alternate"/>
  <link href="https://blog.talentstore.cn/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, Valen</rights>
  <subtitle>技术 · 设计 · 生活</subtitle>
  <title>Valen's Blog</title>
  <updated>2026-07-25T10:54:20.813Z</updated>
  <entry>
    <author>
      <name>Valen</name>
    </author>
    <category term="前端开发" scheme="https://blog.talentstore.cn/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
    <category term="Hexo" scheme="https://blog.talentstore.cn/tags/Hexo/"/>
    <category term="教程" scheme="https://blog.talentstore.cn/tags/%E6%95%99%E7%A8%8B/"/>
    <content>
      <![CDATA[<p>Hexo 是一款基于 Node.js 的静态博客框架，凭借极快的生成速度和丰富的主题生态，成为众多开发者搭建个人博客的首选。它将 Markdown 文件编译为静态 HTML，既轻量又安全，配合 GitHub Pages 即可实现零成本托管。本文将从安装配置到部署上线，带你完整走一遍 Hexo 博客的搭建流程。</p><h2 id="为什么选择-Hexo"><a href="#为什么选择-Hexo" class="headerlink" title="为什么选择 Hexo"></a>为什么选择 Hexo</h2><p>在众多静态站点生成器（Hugo、Jekyll、VuePress）中，Hexo 依然有它独特的优势：</p><ul><li>生成速度快：几百篇文章仅需数秒即可完成编译</li><li>主题生态丰富：官方主题市场收录了数百款风格各异的主题</li><li>插件系统完善：支持代码高亮、搜索、RSS、SEO 优化等扩展</li><li>GitHub Pages 零成本托管：无需服务器，一次配置即可永久运行</li></ul><h2 id="安装与配置"><a href="#安装与配置" class="headerlink" title="安装与配置"></a>安装与配置</h2><p>开始之前，请确保本机已安装 Node.js（建议 LTS 版本）和 Git。然后全局安装 Hexo 命令行工具：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">npm install -g hexo-cli</span><br><span class="line">hexo init my-blog</span><br><span class="line"><span class="built_in">cd</span> my-blog</span><br><span class="line">npm install</span><br></pre></td></tr></table></figure><p>初始化完成后，目录结构如下：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">my-blog/</span><br><span class="line">├── _config.yml        # 站点配置文件</span><br><span class="line">├── package.json</span><br><span class="line">├── scaffolds/         # 模板文件</span><br><span class="line">├── source/</span><br><span class="line">│   ├── _posts/        # 文章目录</span><br><span class="line">│   └── _drafts/       # 草稿目录</span><br><span class="line">└── themes/            # 主题目录</span><br></pre></td></tr></table></figure><blockquote><p>提示：推荐使用 VS Code 配合 Markdown All in One 插件进行写作，可获得实时预览、快捷键加粗、自动补全等便利。在 <code>scaffolds/</code> 中自定义模板，可以让 <code>hexo new</code> 生成的文章自带预设的 Front-matter。</p></blockquote><h2 id="主题定制"><a href="#主题定制" class="headerlink" title="主题定制"></a>主题定制</h2><p>Hexo 主题基于 EJS 模板引擎渲染，样式则使用 Stylus 或 Sass 预处理器编写。你可以在 <code>themes/</code> 目录下克隆或修改主题：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/theme-author/hexo-theme-valencheng themes/valencheng</span><br></pre></td></tr></table></figure><p>修改主题时，重点关注 <code>layout/</code> 下的 EJS 模板与 <code>source/css/</code> 下的样式文件。定制颜色、字体、布局通常只需调整这几个变量文件。</p><h3 id="常用配置项"><a href="#常用配置项" class="headerlink" title="常用配置项"></a>常用配置项</h3><p>在站点 <code>_config.yml</code> 中，以下三项最为关键：</p><ul><li><strong>permalink</strong>：控制文章 URL 格式，如 <code>:year/:month/:day/:title/</code> 或更简洁的 <code>:title/</code></li><li><strong>theme</strong>：指定当前使用的主题名称，需与 <code>themes/</code> 下的目录名一致</li><li><strong>deploy</strong>：部署插件配置，决定博客推送到哪里</li></ul><h2 id="部署到-GitHub-Pages"><a href="#部署到-GitHub-Pages" class="headerlink" title="部署到 GitHub Pages"></a>部署到 GitHub Pages</h2><p>首先安装部署插件：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-deployer-git --save</span><br></pre></td></tr></table></figure><p>然后在 <code>_config.yml</code> 中配置 deploy 字段：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="attr">type:</span> <span class="string">git</span></span><br><span class="line">  <span class="attr">repo:</span> <span class="string">https://github.com/yourname/yourname.github.io.git</span></span><br><span class="line">  <span class="attr">branch:</span> <span class="string">main</span></span><br></pre></td></tr></table></figure><p>执行 <code>hexo clean &amp;&amp; hexo g &amp;&amp; hexo d</code> 即可一键生成并部署。稍等片刻，访问 <code>https://yourname.github.io</code> 就能看到你的博客上线了。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>Hexo 的上手门槛低，但扩展性很强。从安装、目录结构、主题定制到 GitHub Pages 部署，整套流程不到半小时即可跑通。掌握之后，你可以进一步探索插件开发、多语言支持、CI&#x2F;CD 自动部署等进阶玩法，让博客真正成为你的个人技术名片。</p>]]>
    </content>
    <id>https://blog.talentstore.cn/2026/07/20/hexo-blog-guide/</id>
    <link href="https://blog.talentstore.cn/2026/07/20/hexo-blog-guide/"/>
    <published>2026-07-20T02:00:00.000Z</published>
    <summary>
      <![CDATA[<p>Hexo 是一款基于 Node.js 的静态博客框架，凭借极快的生成速度和丰富的主题生态，成为众多开发者搭建个人博客的首选。它将 Markdown 文件编译为静态 HTML，既轻量又安全，配合 GitHub Pages]]>
    </summary>
    <title>使用 Hexo 搭建个人博客的完整指南</title>
    <updated>2026-07-25T10:54:20.813Z</updated>
  </entry>
  <entry>
    <author>
      <name>Valen</name>
    </author>
    <category term="设计" scheme="https://blog.talentstore.cn/categories/%E8%AE%BE%E8%AE%A1/"/>
    <category term="CSS" scheme="https://blog.talentstore.cn/tags/CSS/"/>
    <category term="设计" scheme="https://blog.talentstore.cn/tags/%E8%AE%BE%E8%AE%A1/"/>
    <content>
      <![CDATA[<p>玻璃拟态（Glassmorphism）是近年来备受推崇的 UI 设计趋势，它通过模糊、透明和细腻的边框，模拟出真实玻璃的通透质感，让界面呈现出层次分明的空间深度。这种风格在 macOS、iOS 以及各类现代 Web 应用中随处可见。本文将从核心属性出发，带你打造一套完整的玻璃质感界面。</p><h2 id="backdrop-filter-基础"><a href="#backdrop-filter-基础" class="headerlink" title="backdrop-filter 基础"></a>backdrop-filter 基础</h2><p><code>backdrop-filter</code> 是玻璃拟态的灵魂。它对元素背后的内容应用滤镜效果，从而产生磨砂玻璃的视觉感受：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.glass-panel</span> &#123;</span><br><span class="line">  <span class="attribute">backdrop-filter</span>: <span class="built_in">blur</span>(<span class="number">34px</span>) <span class="built_in">saturate</span>(<span class="number">180%</span>);</span><br><span class="line">  -webkit-<span class="attribute">backdrop-filter</span>: <span class="built_in">blur</span>(<span class="number">34px</span>) <span class="built_in">saturate</span>(<span class="number">180%</span>);</span><br><span class="line">  <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.55</span>);</span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">16px</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>blur</code> 控制模糊半径，<code>saturate</code> 提升饱和度让色彩更通透。记得同时写上 <code>-webkit-</code> 前缀以兼容 Safari。</p><h2 id="色彩与透明度"><a href="#色彩与透明度" class="headerlink" title="色彩与透明度"></a>色彩与透明度</h2><p>玻璃效果的精髓在于「半透明背景 + 模糊」的组合。背景色通常使用 <code>rgba</code> 设置在 <code>0.4 ~ 0.7</code> 之间：太透明会失去玻璃感，太不透明又像普通卡片。深色模式下，可将背景改为 <code>rgba(30, 30, 30, 0.5)</code>，并搭配浅色文字。</p><h2 id="边框与阴影"><a href="#边框与阴影" class="headerlink" title="边框与阴影"></a>边框与阴影</h2><p>真实的玻璃边缘有微妙的高光，单靠背景色无法表现。需要叠加边框与多层阴影：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.glass-panel</span> &#123;</span><br><span class="line">  <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.35</span>);</span><br><span class="line">  <span class="attribute">box-shadow</span>:</span><br><span class="line">    <span class="number">0</span> <span class="number">8px</span> <span class="number">32px</span> <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.12</span>),</span><br><span class="line">    inset <span class="number">0</span> <span class="number">1px</span> <span class="number">0</span> <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.6</span>);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p><code>inset</code> 高光模拟顶部受光，外层阴影营造悬浮感，两者缺一不可。</p><h2 id="实际应用案例"><a href="#实际应用案例" class="headerlink" title="实际应用案例"></a>实际应用案例</h2><p>下面是一个 macOS 风格的毛玻璃通知面板：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.notification</span> &#123;</span><br><span class="line">  <span class="attribute">position</span>: fixed;</span><br><span class="line">  <span class="attribute">top</span>: <span class="number">24px</span>;</span><br><span class="line">  <span class="attribute">right</span>: <span class="number">24px</span>;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">320px</span>;</span><br><span class="line">  <span class="attribute">padding</span>: <span class="number">16px</span> <span class="number">20px</span>;</span><br><span class="line">  <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.6</span>);</span><br><span class="line">  <span class="attribute">backdrop-filter</span>: <span class="built_in">blur</span>(<span class="number">34px</span>) <span class="built_in">saturate</span>(<span class="number">180%</span>);</span><br><span class="line">  -webkit-<span class="attribute">backdrop-filter</span>: <span class="built_in">blur</span>(<span class="number">34px</span>) <span class="built_in">saturate</span>(<span class="number">180%</span>);</span><br><span class="line">  <span class="attribute">border</span>: <span class="number">1px</span> solid <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.35</span>);</span><br><span class="line">  <span class="attribute">border-radius</span>: <span class="number">14px</span>;</span><br><span class="line">  <span class="attribute">box-shadow</span>: <span class="number">0</span> <span class="number">8px</span> <span class="number">32px</span> <span class="built_in">rgba</span>(<span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0.12</span>);</span><br><span class="line">  <span class="attribute">color</span>: <span class="number">#1d1d1f</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>将其悬浮于彩色背景之上，即可看到通透而精致的磨砂质感。</p><h2 id="兼容性与降级"><a href="#兼容性与降级" class="headerlink" title="兼容性与降级"></a>兼容性与降级</h2><p><code>backdrop-filter</code> 在部分旧浏览器中不被支持。推荐使用 <code>@supports</code> 进行渐进增强：检测到不支持时，退回为不透明背景，保证可读性。</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.glass-panel</span> &#123;</span><br><span class="line">  <span class="attribute">background</span>: <span class="number">#f5f5f7</span>;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">@supports</span> (<span class="attribute">backdrop-filter</span>: blur(<span class="number">10px</span>)) &#123;</span><br><span class="line">  <span class="selector-class">.glass-panel</span> &#123;</span><br><span class="line">    <span class="attribute">background</span>: <span class="built_in">rgba</span>(<span class="number">255</span>, <span class="number">255</span>, <span class="number">255</span>, <span class="number">0.55</span>);</span><br><span class="line">    <span class="attribute">backdrop-filter</span>: <span class="built_in">blur</span>(<span class="number">34px</span>) <span class="built_in">saturate</span>(<span class="number">180%</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>如此一来，新浏览器享受玻璃质感，旧浏览器也不会出现透明文字叠在杂乱背景上的可读性问题。</p>]]>
    </content>
    <id>https://blog.talentstore.cn/2026/07/15/css-glassmorphism/</id>
    <link href="https://blog.talentstore.cn/2026/07/15/css-glassmorphism/"/>
    <published>2026-07-15T06:30:00.000Z</published>
    <summary>
      <![CDATA[<p>玻璃拟态（Glassmorphism）是近年来备受推崇的 UI 设计趋势，它通过模糊、透明和细腻的边框，模拟出真实玻璃的通透质感，让界面呈现出层次分明的空间深度。这种风格在 macOS、iOS 以及各类现代 Web]]>
    </summary>
    <title>CSS 玻璃拟态设计实践</title>
    <updated>2026-07-25T10:54:20.813Z</updated>
  </entry>
  <entry>
    <author>
      <name>Valen</name>
    </author>
    <category term="设计" scheme="https://blog.talentstore.cn/categories/%E8%AE%BE%E8%AE%A1/"/>
    <category term="设计系统" scheme="https://blog.talentstore.cn/tags/%E8%AE%BE%E8%AE%A1%E7%B3%BB%E7%BB%9F/"/>
    <content>
      <![CDATA[<p>当产品线逐渐壮大，页面越来越多，团队成员不断扩张，设计稿与代码之间的不一致就开始频频出现：按钮圆角一会儿是 4px 一会儿是 6px，主色调在不同页面存在微妙偏差。设计系统（Design System）正是为解决这类问题而生。它不仅是组件库，更是一套让设计与开发协同工作的语言和规则。</p><h2 id="设计令牌"><a href="#设计令牌" class="headerlink" title="设计令牌"></a>设计令牌</h2><p>设计令牌（Design Tokens）是设计系统的原子，它把视觉决策抽象为与平台无关的键值对：</p><ul><li><strong>颜色</strong>：<code>color-brand-primary: #3B82F6</code></li><li><strong>间距</strong>：<code>spacing-md: 16px</code></li><li><strong>字体</strong>：<code>font-size-body: 14px</code></li><li><strong>圆角</strong>：<code>radius-sm: 4px</code></li></ul><p>令牌集中管理后，一次修改即可全局生效，天然支持多主题与深色模式切换。</p><h2 id="组件库"><a href="#组件库" class="headerlink" title="组件库"></a>组件库</h2><p>借鉴原子设计理论，组件按层级递进组织：</p><ul><li><strong>原子</strong>：按钮、输入框、图标等最小元素</li><li><strong>分子</strong>：搜索栏、表单项等组合</li><li><strong>有机体</strong>：导航栏、卡片列表等区块</li><li><strong>模板</strong>：整页布局结构</li></ul><p>每一层都建立在下一层之上，保证视觉与交互的一致性，同时兼顾复用性。</p><h2 id="文档与规范"><a href="#文档与规范" class="headerlink" title="文档与规范"></a>文档与规范</h2><p>组件库若没有文档，就只是代码仓库。一份好的文档应包含：</p><ul><li>使用指南：何时使用、何时不使用</li><li>代码示例：可直接复制粘贴的片段</li><li>设计原则：解释「为什么这样设计」背后的取舍</li></ul><p>文档让规范可被查阅、可被遵循，也让新人快速上手。</p><h2 id="工具链"><a href="#工具链" class="headerlink" title="工具链"></a>工具链</h2><p>现代设计系统的工具链已相当成熟：</p><ul><li><strong>Figma</strong>：设计师维护视觉组件与变量</li><li><strong>Style Dictionary</strong>：把设计令牌编译为各平台（CSS &#x2F; SCSS &#x2F; iOS &#x2F; Android）产物</li><li><strong>Storybook</strong>：为组件提供独立的可视化沙盒与交互文档</li></ul><p>三者串联，可实现「设计稿改令牌 → 自动生成代码 → 文档同步更新」的闭环。</p><h2 id="团队协作"><a href="#团队协作" class="headerlink" title="团队协作"></a>团队协作</h2><p>设计系统的成功不只在于工具，更在于流程。设计师与开发者应共同维护令牌与组件，建立变更评审机制，避免一方擅自修改导致不一致。定期同步会议、版本化的变更日志，能让系统持续进化而不失控。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>设计系统是一项长期投资。从令牌、组件到文档与工具链，它把分散的视觉决策收敛为统一的工程化产物。短期内看似增加了维护成本，但长远看，它显著降低了沟通损耗和重复劳动，让团队把精力真正聚焦在产品体验上。</p>]]>
    </content>
    <id>https://blog.talentstore.cn/2026/06/28/design-system-zero-to-one/</id>
    <link href="https://blog.talentstore.cn/2026/06/28/design-system-zero-to-one/"/>
    <published>2026-06-28T03:20:00.000Z</published>
    <summary>
      <![CDATA[<p>当产品线逐渐壮大，页面越来越多，团队成员不断扩张，设计稿与代码之间的不一致就开始频频出现：按钮圆角一会儿是 4px 一会儿是 6px，主色调在不同页面存在微妙偏差。设计系统（Design]]>
    </summary>
    <title>设计系统从零到一</title>
    <updated>2026-07-25T10:54:20.813Z</updated>
  </entry>
  <entry>
    <author>
      <name>Valen</name>
    </author>
    <category term="前端开发" scheme="https://blog.talentstore.cn/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
    <category term="SVG" scheme="https://blog.talentstore.cn/tags/SVG/"/>
    <category term="动画" scheme="https://blog.talentstore.cn/tags/%E5%8A%A8%E7%94%BB/"/>
    <content>
      <![CDATA[<p>SVG 是矢量图形的天然载体，无论放大多少倍都不会失真，且每个元素都可被 CSS 和 JavaScript 独立控制。这让 SVG 成为制作轻量、流畅动画的理想选择。相比 GIF 和视频，SVG 动画体积更小、可交互、可主题化。本文将带你掌握 SVG 动画的几种核心实现方式。</p><h2 id="SVG-动画基础"><a href="#SVG-动画基础" class="headerlink" title="SVG 动画基础"></a>SVG 动画基础</h2><p>SVG 动画主要有三种实现路径：</p><ul><li><strong>SMIL</strong>：SVG 原生的 <code>&lt;animate&gt;</code> 标签，语法直观但已被标记为废弃，不推荐新项目使用</li><li><strong>CSS</strong>：通过 <code>@keyframes</code> 和 <code>transform</code> 控制 SVG 元素，性能好、易维护，是首选方案</li><li><strong>JavaScript</strong>：借助 GSAP、anime.js 等库实现复杂时间轴与路径动画，适合高级场景</li></ul><p>日常需求中，CSS 方案覆盖了 80% 的场景，且性能最优。</p><h2 id="CSS-动画-SVG"><a href="#CSS-动画-SVG" class="headerlink" title="CSS 动画 SVG"></a>CSS 动画 SVG</h2><p>直接用 CSS 给 SVG 内部元素添加动画即可。下面的代码让一个圆形持续旋转：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.spinner</span> &#123;</span><br><span class="line">  <span class="attribute">animation</span>: spin <span class="number">1.2s</span> linear infinite;</span><br><span class="line">  <span class="attribute">transform-origin</span>: center;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">@keyframes</span> spin &#123;</span><br><span class="line">  <span class="selector-tag">to</span> &#123; <span class="attribute">transform</span>: <span class="built_in">rotate</span>(<span class="number">360deg</span>); &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>注意 <code>transform-origin</code> 必须设为 <code>center</code>，否则旋转中心会偏移。使用 <code>transform-box: fill-box</code> 可确保原点作用于元素自身。</p><h2 id="路径动画"><a href="#路径动画" class="headerlink" title="路径动画"></a>路径动画</h2><p><code>stroke-dasharray</code> 与 <code>stroke-dashoffset</code> 是绘制「线条逐渐画出」效果的经典组合：</p><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.path-draw</span> &#123;</span><br><span class="line">  <span class="attribute">stroke-dasharray</span>: <span class="number">1000</span>;</span><br><span class="line">  <span class="attribute">stroke-dashoffset</span>: <span class="number">1000</span>;</span><br><span class="line">  <span class="attribute">animation</span>: draw <span class="number">2s</span> ease forwards;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">@keyframes</span> draw &#123;</span><br><span class="line">  <span class="selector-tag">to</span> &#123; <span class="attribute">stroke-dashoffset</span>: <span class="number">0</span>; &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure><p>原理是先用虚线把整条路径隐藏，再通过动画将偏移量归零，制造出笔尖沿路径移动的视觉。常用于数据图表、流程图的入场动效。</p><h2 id="形态变化"><a href="#形态变化" class="headerlink" title="形态变化"></a>形态变化</h2><p>通过改变 <code>&lt;path&gt;</code> 的 <code>d</code> 属性，可以实现图形之间的平滑变形（morphing）。原生的 CSS 无法直接过渡 <code>d</code>，需要借助 JavaScript 库，如 flubber 或 GSAP MorphSVG：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 使用 flubber 在两个路径间插值</span></span><br><span class="line"><span class="keyword">const</span> interpolator = flubber.<span class="title function_">interpolate</span>(circlePath, starPath);</span><br><span class="line">element.<span class="title function_">setAttribute</span>(<span class="string">&#x27;d&#x27;</span>, <span class="title function_">interpolator</span>(t));</span><br></pre></td></tr></table></figure><p>形态变化在加载动画、图标切换中表现力极强，但要注意两个路径的节点数尽量接近，过渡才会自然。</p><h2 id="性能注意事项"><a href="#性能注意事项" class="headerlink" title="性能注意事项"></a>性能注意事项</h2><p>SVG 动画若使用不当也会掉帧：</p><ul><li><strong>优先 transform 与 opacity</strong>：这两个属性可由 GPU 合成，不触发重排</li><li><strong>will-change 提示</strong>：对动画元素加 <code>will-change: transform</code>，让浏览器提前创建合成层</li><li><strong>避免 animate 属性</strong>：频繁修改 <code>width</code>、<code>height</code>、<code>fill</code> 会触发重绘，性能较差</li></ul><h2 id="实战案例"><a href="#实战案例" class="headerlink" title="实战案例"></a>实战案例</h2><p>加载动画与图标动效是 SVG 最常见的用武之地。一个旋转的环形 spinner 只需几行 CSS；图标的 hover 切换则可用路径动画让线条优雅地勾勒出来。把这些微动效融入界面，能显著提升产品的精致感与反馈感，而付出的体积成本几乎可以忽略。</p>]]>
    </content>
    <id>https://blog.talentstore.cn/2026/06/20/svg-animation-guide/</id>
    <link href="https://blog.talentstore.cn/2026/06/20/svg-animation-guide/"/>
    <published>2026-06-20T05:45:00.000Z</published>
    <summary>
      <![CDATA[<p>SVG 是矢量图形的天然载体，无论放大多少倍都不会失真，且每个元素都可被 CSS 和 JavaScript 独立控制。这让 SVG 成为制作轻量、流畅动画的理想选择。相比 GIF 和视频，SVG 动画体积更小、可交互、可主题化。本文将带你掌握 SVG]]>
    </summary>
    <title>SVG 动画实战指南</title>
    <updated>2026-07-25T10:54:20.813Z</updated>
  </entry>
  <entry>
    <author>
      <name>Valen</name>
    </author>
    <category term="前端开发" scheme="https://blog.talentstore.cn/categories/%E5%89%8D%E7%AB%AF%E5%BC%80%E5%8F%91/"/>
    <category term="DevOps" scheme="https://blog.talentstore.cn/tags/DevOps/"/>
    <content>
      <![CDATA[<p>每次提交代码后手动构建、手动部署，既繁琐又容易出错。CI&#x2F;CD 流水线能把这些重复劳动自动化：你只需 push 代码，系统就会自动完成检查、测试、构建和发布。GitHub Actions 是目前门槛最低、与代码仓库集成最紧密的方案，本文将以它为例，带你从零搭建一套前端 CI&#x2F;CD 流水线。</p><h2 id="CI-CD-概念"><a href="#CI-CD-概念" class="headerlink" title="CI&#x2F;CD 概念"></a>CI&#x2F;CD 概念</h2><p>CI&#x2F;CD 是两个阶段的组合：</p><ul><li><strong>持续集成（CI）</strong>：每次提交自动运行 lint、测试、构建，尽早发现问题</li><li><strong>持续部署（CD）</strong>：构建通过后自动部署到测试或生产环境，缩短交付周期</li></ul><p>两者的目标都是让代码从提交到上线的过程「快且可靠」。</p><h2 id="GitHub-Actions-基础"><a href="#GitHub-Actions-基础" class="headerlink" title="GitHub Actions 基础"></a>GitHub Actions 基础</h2><p>GitHub Actions 的核心是 workflow 文件，放在仓库的 <code>.github/workflows/</code> 目录下，使用 YAML 描述：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">CI</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="attr">branches:</span> [<span class="string">main</span>]</span><br><span class="line">  <span class="attr">pull_request:</span></span><br><span class="line">    <span class="attr">branches:</span> [<span class="string">main</span>]</span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">build:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v4</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">run:</span> <span class="string">echo</span> <span class="string">&quot;Hello CI&quot;</span></span><br></pre></td></tr></table></figure><p><code>on</code> 定义触发时机，<code>jobs</code> 定义任务，<code>steps</code> 是任务内的执行步骤。<code>uses</code> 引用官方或社区的 Action，<code>run</code> 执行普通 shell 命令。</p><h2 id="前端-CI-流水线"><a href="#前端-CI-流水线" class="headerlink" title="前端 CI 流水线"></a>前端 CI 流水线</h2><p>一个标准的前端 CI 流程包含安装依赖、代码检查、测试和构建：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">ci:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v4</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Setup</span> <span class="string">Node.js</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/setup-node@v4</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">node-version:</span> <span class="number">20</span></span><br><span class="line">          <span class="attr">cache:</span> <span class="string">npm</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Install</span> <span class="string">dependencies</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">npm</span> <span class="string">ci</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Lint</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">npm</span> <span class="string">run</span> <span class="string">lint</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Test</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">npm</span> <span class="string">test</span></span><br><span class="line"></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Build</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">npm</span> <span class="string">run</span> <span class="string">build</span></span><br></pre></td></tr></table></figure><p><code>npm ci</code> 比 <code>npm install</code> 更快更严格，适合 CI 环境。任何一步失败都会中断流水线，防止有问题的代码进入下一阶段。</p><h2 id="自动部署到-GitHub-Pages"><a href="#自动部署到-GitHub-Pages" class="headerlink" title="自动部署到 GitHub Pages"></a>自动部署到 GitHub Pages</h2><p>构建通过后，用一个独立的 deploy job 将产物发布到 GitHub Pages：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">deploy:</span></span><br><span class="line">  <span class="attr">needs:</span> <span class="string">ci</span></span><br><span class="line">  <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">  <span class="attr">permissions:</span></span><br><span class="line">    <span class="attr">contents:</span> <span class="string">read</span></span><br><span class="line">    <span class="attr">pages:</span> <span class="string">write</span></span><br><span class="line">    <span class="attr">id-token:</span> <span class="string">write</span></span><br><span class="line">  <span class="attr">environment:</span></span><br><span class="line">    <span class="attr">name:</span> <span class="string">github-pages</span></span><br><span class="line">    <span class="attr">url:</span> <span class="string">$&#123;&#123;</span> <span class="string">steps.deployment.outputs.page_url</span> <span class="string">&#125;&#125;</span></span><br><span class="line">  <span class="attr">steps:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/checkout@v4</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/setup-node@v4</span></span><br><span class="line">      <span class="attr">with:</span></span><br><span class="line">        <span class="attr">node-version:</span> <span class="number">20</span></span><br><span class="line">        <span class="attr">cache:</span> <span class="string">npm</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">run:</span> <span class="string">npm</span> <span class="string">ci</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">run:</span> <span class="string">npm</span> <span class="string">run</span> <span class="string">build</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Upload</span> <span class="string">artifact</span></span><br><span class="line">      <span class="attr">uses:</span> <span class="string">actions/upload-pages-artifact@v3</span></span><br><span class="line">      <span class="attr">with:</span></span><br><span class="line">        <span class="attr">path:</span> <span class="string">./public</span></span><br><span class="line"></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Deploy</span> <span class="string">to</span> <span class="string">GitHub</span> <span class="string">Pages</span></span><br><span class="line">      <span class="attr">id:</span> <span class="string">deployment</span></span><br><span class="line">      <span class="attr">uses:</span> <span class="string">actions/deploy-pages@v4</span></span><br></pre></td></tr></table></figure><p><code>needs: ci</code> 确保只有 CI 通过才部署，<code>permissions</code> 授予 Pages 写入权限。配置完成后，每次合并到 main 分支就会自动上线。</p><h2 id="缓存优化"><a href="#缓存优化" class="headerlink" title="缓存优化"></a>缓存优化</h2><p>CI 的最大开销在于重复安装依赖。利用 <code>actions/setup-node</code> 的 <code>cache: npm</code> 可缓存 npm 全局目录，二次构建能快上数倍。此外可缓存 <code>node_modules</code> 或构建产物，用 <code>actions/cache</code> 配合唯一 key 实现：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">uses:</span> <span class="string">actions/cache@v4</span></span><br><span class="line">  <span class="attr">with:</span></span><br><span class="line">    <span class="attr">path:</span> <span class="string">~/.npm</span></span><br><span class="line">    <span class="attr">key:</span> <span class="string">$&#123;&#123;</span> <span class="string">runner.os</span> <span class="string">&#125;&#125;-npm-$&#123;&#123;</span> <span class="string">hashFiles(&#x27;**/package-lock.json&#x27;)</span> <span class="string">&#125;&#125;</span></span><br></pre></td></tr></table></figure><p>当 <code>package-lock.json</code> 未变时命中缓存，跳过重新下载。</p><h2 id="通知与集成"><a href="#通知与集成" class="headerlink" title="通知与集成"></a>通知与集成</h2><p>流水线运行结果应及时通知团队。通过 webhook 可将构建状态推送到 Slack、钉钉或飞书：</p><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Notify</span> <span class="string">on</span> <span class="string">failure</span></span><br><span class="line">  <span class="attr">if:</span> <span class="string">failure()</span></span><br><span class="line">  <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">    curl -X POST $&#123;&#123; secrets.WEBHOOK_URL &#125;&#125; \</span></span><br><span class="line"><span class="string">      -H &#x27;Content-Type: application/json&#x27; \</span></span><br><span class="line"><span class="string">      -d &#x27;&#123;&quot;text&quot;:&quot;CI 构建失败，请检查！&quot;&#125;&#x27;</span></span><br></pre></td></tr></table></figure><p><code>if: failure()</code> 保证仅在失败时触发，避免成功消息打扰。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>一套完整的 CI&#x2F;CD 流水线，能让团队专注于写代码，把检查、构建、部署交给机器。从 GitHub Actions 入门，逐步加入缓存优化和通知集成，你会发现交付效率与代码质量都在同步提升。当自动化成为习惯，发布新版本就不再是令人紧张的事件，而是一次平淡的 push。</p>]]>
    </content>
    <id>https://blog.talentstore.cn/2026/06/10/cicd-pipeline/</id>
    <link href="https://blog.talentstore.cn/2026/06/10/cicd-pipeline/"/>
    <published>2026-06-10T07:00:00.000Z</published>
    <summary>
      <![CDATA[<p>每次提交代码后手动构建、手动部署，既繁琐又容易出错。CI&#x2F;CD 流水线能把这些重复劳动自动化：你只需 push 代码，系统就会自动完成检查、测试、构建和发布。GitHub Actions]]>
    </summary>
    <title>从零搭建 CI/CD 流水线</title>
    <updated>2026-07-25T10:54:20.813Z</updated>
  </entry>
</feed>
