更新文章

This commit is contained in:
lsy 2025-05-18 01:40:15 +08:00
parent 32ca728974
commit a690864864
4 changed files with 247 additions and 69 deletions

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect, useCallback, useRef } from 'react';
import React, { useState, useEffect, useCallback, useRef, useMemo } from 'react';
import ReactMasonryCss from 'react-masonry-css';
interface DoubanItem {
@ -35,6 +35,26 @@ const DoubanCollection: React.FC<DoubanCollectionProps> = ({ type, doubanId, cla
const abortControllerRef = useRef<AbortController | null>(null);
const isMountedRef = useRef(true);
// 标题文本
const titleText = useMemo(() =>
type === 'movie' ? '观影记录' : '读书记录',
[type]);
// 加载动画组件
const LoadingSpinner = useCallback(() => (
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
), []);
// 公共标题组件
const Title = useCallback(() => (
<h2 className="text-2xl font-bold mb-6 text-primary-700 dark:text-primary-400">
{titleText}
</h2>
), [titleText]);
const fetchData = useCallback(async (start = 0) => {
// 如果已经有一个请求在进行中,取消它
if (abortControllerRef.current) {
@ -127,10 +147,6 @@ const DoubanCollection: React.FC<DoubanCollectionProps> = ({ type, doubanId, cla
current: page
}));
// 清空当前项目,显示加载状态
setItems([]);
setLoading(true);
// 获取新页面的数据
fetchData(start);
}, [fetchData, isPageChanging]);
@ -158,29 +174,31 @@ const DoubanCollection: React.FC<DoubanCollectionProps> = ({ type, doubanId, cla
1100: 2,
700: 1
};
// 渲染内容的容器
const Container = useCallback(({ children }: { children: React.ReactNode }) => (
<div className={`douban-collection ${className}`}>
<Title />
{children}
</div>
), [className, Title]);
// 加载中状态
if (loading && items.length === 0) {
return (
<div className={`douban-collection ${className}`}>
<h2 className="text-2xl font-bold mb-6 text-primary-700 dark:text-primary-400">
{type === 'movie' ? '观影记录' : '读书记录'}
</h2>
<Container>
<div className="flex justify-center items-center p-8">
<div className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-r-transparent align-[-0.125em] motion-reduce:animate-[spin_1.5s_linear_infinite]"></div>
<p className="ml-2 text-gray-600 dark:text-gray-400">...</p>
</div>
</div>
</Container>
);
}
// 错误状态
if (error) {
return (
<div className={`douban-collection ${className}`}>
<h2 className="text-2xl font-bold mb-6 text-primary-700 dark:text-primary-400">
{type === 'movie' ? '观影记录' : '读书记录'}
</h2>
<Container>
<div className="bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 p-4 rounded-lg border border-red-200 dark:border-red-800">
<div className="flex items-center">
<svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
@ -195,30 +213,52 @@ const DoubanCollection: React.FC<DoubanCollectionProps> = ({ type, doubanId, cla
</button>
</div>
</div>
</Container>
);
}
// 数据为空状态
if (items.length === 0) {
return (
<div className={`douban-collection ${className}`}>
<h2 className="text-2xl font-bold mb-6 text-primary-700 dark:text-primary-400">
{type === 'movie' ? '观影记录' : '读书记录'}
</h2>
<Container>
<div className="text-center p-8 text-gray-500 dark:text-gray-400">
{type === 'movie' ? '观影' : '读书'}
</div>
</div>
</Container>
);
}
return (
<div className={`douban-collection ${className}`}>
<h2 className="text-2xl font-bold mb-6 text-primary-700 dark:text-primary-400">
{type === 'movie' ? '观影记录' : '读书记录'}
</h2>
// 渲染分页按钮
const renderPaginationButton = useCallback((
direction: 'prev' | 'next',
onClick: () => void,
disabled: boolean
) => {
const buttonText = direction === 'prev' ? '上一页' : '下一页';
const buttonClass = `px-4 py-2 rounded ${disabled
? 'bg-secondary-200 dark:bg-secondary-700 text-secondary-500 dark:text-secondary-500 cursor-not-allowed'
: 'bg-primary-600 text-white hover:bg-primary-700 dark:bg-primary-700 dark:hover:bg-primary-600'}`;
return (
<button
onClick={onClick}
disabled={disabled}
className={buttonClass}
aria-label={buttonText}
>
{isPageChanging ? (
<span className="flex items-center">
<LoadingSpinner />
</span>
) : buttonText}
</button>
);
}, [isPageChanging, LoadingSpinner]);
return (
<Container>
<ReactMasonryCss
breakpointCols={breakpointColumnsObj}
className="flex -ml-4 w-auto"
@ -260,50 +300,24 @@ const DoubanCollection: React.FC<DoubanCollectionProps> = ({ type, doubanId, cla
{/* 分页 */}
{pagination.total > 1 && (
<div className="flex justify-center mt-8 space-x-2">
<button
onClick={() => handlePageChange(pagination.current - 1)}
disabled={!pagination.hasPrev || pagination.current <= 1 || isPageChanging}
className={`px-4 py-2 rounded ${!pagination.hasPrev || pagination.current <= 1 || isPageChanging
? 'bg-secondary-200 dark:bg-secondary-700 text-secondary-500 dark:text-secondary-500 cursor-not-allowed'
: 'bg-primary-600 text-white hover:bg-primary-700 dark:bg-primary-700 dark:hover:bg-primary-600'}`}
aria-label="上一页"
>
{isPageChanging ? (
<span className="flex items-center">
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</span>
) : '上一页'}
</button>
{renderPaginationButton(
'prev',
() => handlePageChange(pagination.current - 1),
!pagination.hasPrev || isPageChanging
)}
<span className="px-4 py-2 bg-secondary-100 dark:bg-secondary-800 rounded">
{pagination.current} / {pagination.total}
</span>
<button
onClick={() => handlePageChange(pagination.current + 1)}
disabled={!pagination.hasNext || pagination.current >= pagination.total || isPageChanging}
className={`px-4 py-2 rounded ${!pagination.hasNext || pagination.current >= pagination.total || isPageChanging
? 'bg-secondary-200 dark:bg-secondary-700 text-secondary-500 dark:text-secondary-500 cursor-not-allowed'
: 'bg-primary-600 text-white hover:bg-primary-700 dark:bg-primary-700 dark:hover:bg-primary-600'}`}
aria-label="下一页"
>
{isPageChanging ? (
<span className="flex items-center">
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</span>
) : '下一页'}
</button>
{renderPaginationButton(
'next',
() => handlePageChange(pagination.current + 1),
!pagination.hasNext || isPageChanging
)}
</div>
)}
</div>
</Container>
);
};

View File

@ -12,7 +12,7 @@ summary : "常用的应用合集"
- **开发软件:**
- [JetBrains 全家桶](https://www.jetbrains.com/zh-cn/products/)
- [JetBrains 破解软件](https://linux.do/t/topic/115562)
- [JetBrains 破解软件](https://linux.do/t/topic/653353)
- **压缩软件:** [NanaZIP](https://github.com/M2Team/NanaZip) (应用商店可下载)
- **办公软件:**
@ -25,12 +25,7 @@ summary : "常用的应用合集"
- **卸载工具:** [Geek](https://geekuninstaller.com/)
- **文件搜索工具:** [Everything](https://www.voidtools.com/downloads/)
- **电脑硬件检测:** [图吧工具箱](http://www.tbtool.cn/)
- **浏览器:**
- [chrome](https://www.google.com/chrome/)
- [Arc](https://arc.net/)
- [百分浏览器](https://www.centbrowser.cn/)
- **浏览器:** [chrome](https://www.google.com/chrome/)
- **ssh 工具:**
- [tabby](https://github.com/Eugeny/tabby/tree/master)
@ -186,3 +181,11 @@ summary : "常用的应用合集"
- [土豆资源库](http://tdtd.chat/index)
- [3DMGAME](https://bbs.3dmgame.com/forum.php)
### 常用镜像站
---
- [中国科学技术大学](https://chinanet.mirrors.ustc.edu.cn/)
- [清华大学](https://mirrors.tuna.tsinghua.edu.cn/)
- [阿里云](https://developer.aliyun.com/mirror/)

View File

@ -0,0 +1,47 @@
.animated-text path {
fill: transparent;
stroke: currentColor;
stroke-width: 2;
stroke-dasharray: var(--path-length);
stroke-dashoffset: var(--path-length);
animation: logo-anim 10s ease-in-out infinite;
}
@keyframes logo-anim {
0% {
stroke-dashoffset: var(--path-length);
fill: transparent;
opacity: 0;
}
10% {
opacity: 1;
stroke-dashoffset: var(--path-length);
}
50% {
stroke-dashoffset: 0;
fill: transparent;
}
60% {
stroke-dashoffset: 0;
fill: currentColor;
}
80% {
stroke-dashoffset: 0;
fill: currentColor;
}
90% {
stroke-dashoffset: var(--path-length);
fill: transparent;
}
100% {
stroke-dashoffset: var(--path-length);
fill: transparent;
opacity: 0;
}
}
@media (prefers-color-scheme: dark) {
.animated-text path {
stroke: currentColor;
}
}

View File

@ -0,0 +1,114 @@
---
title: "svg文字动画"
date: 2025-05-17T19:34:23+08:00
tags: []
---
import './svg文字动画.css'
## 演示效果
<svg class="animated-text" preserveAspectRatio="xMidYMid meet" style="width: 100%; height: 100%;" viewBox="30.8 49.400005 495 94" xmlns="http://www.w3.org/2000/svg">
<path d="M 49.7 133.40001 Q 46.6 133.40001 44.15 131.85 Q 41.7 130.3 40.9 127.200005 Q 40.8 127.00001 40.8 126.700005 Q 40.8 126.40001 40.8 126.200005 Q 40.8 124.700005 41.5 124.700005 Q 42.1 124.700005 42.6 126.600006 Q 43.5 129.1 45.55 129.85 Q 47.6 130.6 49.9 130.6 Q 54.2 130.6 58.2 127.850006 Q 62.2 125.100006 65.65 120.65001 Q 69.1 116.200005 71.95 111.100006 Q 74.8 106.00001 76.9 101.25001 Q 79 96.50001 80.3 93.200005 Q 79 93.00001 77.7 92.950005 Q 76.4 92.90001 75.1 92.8 Q 74.4 92.8 73.8 92.75001 Q 73.2 92.700005 72.5 92.700005 Q 69.3 92.700005 66.15 93.350006 Q 63 94.00001 60.55 95.75001 Q 58.1 97.50001 56.9 100.90001 Q 56.4 102.100006 56.4 103.00001 Q 56.4 103.8 56.9 104.80001 Q 57.2 105.200005 57.2 105.600006 Q 57.2 106.40001 56.2 106.40001 Q 55.5 106.40001 55.1 105.700005 Q 54.6 104.600006 54.3 102.950005 Q 54 101.3 54.1 99.50001 Q 54.5 94.90001 56.55 92.450005 Q 58.6 90.00001 61.75 89.100006 Q 64.9 88.200005 68.5 88.200005 Q 71.8 88.200005 75.1 88.600006 Q 78.4 89.00001 81.7 89.50001 Q 83.4 85.00001 84.8 80.55 Q 86.2 76.100006 87.4 72.3 Q 84.600006 74.90001 81.05 76.20001 Q 77.5 77.50001 74.4 77.90001 L 74.3 77.90001 Q 73.4 77.90001 73.4 77.20001 Q 73.4 76.3 74.6 76.20001 Q 77.5 75.90001 80.5 73.95001 Q 83.5 72.00001 86.15 68.95001 Q 88.8 65.90001 90.3 62.300007 Q 90.5 61.800007 91.7 61.45001 Q 92.9 61.100006 94.100006 61.100006 Q 95.2 61.100006 96 61.400005 Q 96.8 61.70001 96.600006 62.300007 Q 94.7 67.100006 91.9 74.55 Q 89.100006 82.00001 85.600006 90.3 Q 91.7 91.50001 97.8 92.90001 Q 103.9 94.3 109.600006 95.00001 Q 111.600006 90.700005 113.7 86.40001 Q 115.8 82.100006 117.5 77.600006 Q 118 76.600006 118.1 75.90001 Q 118.200005 75.20001 118.200005 74.8 Q 118.200005 74.3 118.15 74.05 Q 118.1 73.8 118 73.600006 Q 118.1 72.40001 119.200005 70.40001 Q 120.3 68.40001 122.1 66.40001 Q 123.9 64.40001 126 63.050007 Q 128.1 61.70001 130 61.70001 Q 130.6 61.70001 132.1 62.150005 Q 133.6 62.600006 134.9 63.550007 Q 136.20001 64.50001 136.1 66.100006 Q 135.8 66.00001 135.45001 65.8 Q 135.1 65.600006 134.9 65.600006 Q 132.70001 65.600006 130.20001 68.00001 Q 127.700005 70.40001 125.200005 74.20001 Q 122.700005 78.00001 120.450005 82.15001 Q 118.200005 86.3 116.5 89.850006 Q 114.8 93.40001 113.9 95.40001 Q 115.6 95.40001 117.9 95.100006 Q 120.200005 94.8 122.3 94.05 Q 124.4 93.3 125.4 91.8 Q 125.700005 91.40001 126 91.40001 Q 126.4 91.40001 126.6 91.850006 Q 126.8 92.3 126.4 92.90001 Q 125.200005 94.8 122.8 95.75001 Q 120.4 96.700005 117.8 96.950005 Q 115.200005 97.200005 113.100006 97.200005 Q 112.100006 99.600006 111 102.8 Q 109.9 106.00001 109.15 109.200005 Q 108.4 112.40001 108.4 114.90001 Q 108.4 116.80001 109.05 118.05001 Q 109.7 119.30001 111.3 119.30001 Q 113.4 119.30001 116.200005 117.55001 Q 119 115.80001 121.75 113.200005 Q 124.5 110.600006 126.85 108.05001 Q 129.20001 105.50001 130.4 103.90001 Q 130.6 103.700005 131 103.700005 Q 131.3 103.700005 131.55 103.950005 Q 131.8 104.200005 131.6 104.80001 Q 131.4 105.200005 129.70001 107.50001 Q 128 109.80001 125 113.00001 Q 122.200005 116.200005 118.35 118.700005 Q 114.5 121.200005 110.100006 121.200005 Q 106.7 121.200005 105.4 119.100006 Q 104.100006 117.00001 104.100006 114.100006 Q 104.100006 110.90001 105.100006 107.40001 Q 106.100006 103.90001 106.8 102.00001 Q 107.3 100.700005 107.850006 99.450005 Q 108.4 98.200005 108.9 96.90001 Q 102.600006 96.40001 96.5 95.40001 Q 90.4 94.40001 84.2 93.700005 Q 82.5 97.40001 80.05 102.55 Q 77.6 107.700005 74.4 113.05001 Q 71.2 118.40001 67.35 123.05001 Q 63.5 127.700005 59.05 130.55 Q 54.6 133.40001 49.7 133.40001 Z" fill="currentColor" style="--path-length: 597.99115;"/>
<path d="M 138.1 121.50001 Q 133.6 121.50001 130.3 119.40001 Q 127 117.30001 127 113.00001 Q 127 110.700005 128.4 107.40001 Q 129.4 105.100006 132.1 102.100006 Q 134.8 99.100006 138.4 96.25001 Q 142 93.40001 145.7 91.55 Q 149.4 89.700005 152.4 89.700005 Q 153.5 89.700005 154.4 90.00001 Q 156.1 90.600006 156.75 91.90001 Q 157.4 93.200005 157.4 94.600006 Q 157.4 95.90001 157 97.100006 Q 156.6 98.3 156 99.200005 Q 154.2 101.90001 150.85 104.00001 Q 147.5 106.100006 144.05 107.30001 Q 140.6 108.50001 138.4 108.700005 L 138.2 108.700005 Q 136.9 108.700005 136.9 107.90001 Q 136.9 107.40001 137.7 107.40001 Q 140.1 107.200005 143.75 105.15001 Q 147.4 103.100006 150.2 100.90001 Q 151.4 99.90001 153.05 98.100006 Q 154.7 96.3 154.7 94.600006 Q 154.7 92.8 153 92.8 Q 152.1 92.8 151.15 93.200005 Q 150.2 93.600006 149.6 93.8 Q 146.7 95.200005 143.2 98.15001 Q 139.7 101.100006 136.85 104.75001 Q 134 108.40001 132.9 112.100006 Q 132.6 112.90001 132.5 113.65001 Q 132.4 114.40001 132.4 115.100006 Q 132.4 117.50001 133.95 118.50001 Q 135.5 119.50001 137.7 119.50001 Q 141 119.50001 144.5 118.05001 Q 148 116.600006 151.3 114.30001 Q 154.6 112.00001 157.35 109.350006 Q 160.1 106.700005 162 104.200005 Q 162.3 103.8 162.7 103.75001 Q 163.1 103.700005 163.2 103.90001 Q 163.6 104.00001 163.6 104.450005 Q 163.6 104.90001 163.4 105.30001 Q 160.6 109.200005 156.65 112.90001 Q 152.7 116.600006 147.95 119.05001 Q 143.2 121.50001 138.1 121.50001 Z" fill="currentColor" style="--path-length: 234.90639;"/>
<path d="M 167.29999 121.00001 Q 163.09999 121.00001 161.45 118.90001 Q 159.79999 116.80001 159.79999 113.700005 Q 159.79999 110.80001 161.15 106.40001 Q 162.5 102.00001 164.7 96.90001 Q 166.9 91.8 169.45 86.75001 Q 172 81.70001 174.54999 77.45001 Q 177.09999 73.20001 179 70.600006 Q 180.9 68.100006 183.09999 65.600006 Q 185.29999 63.100006 188 61.400005 Q 190.7 59.70001 194.09999 59.70001 Q 196.4 59.70001 198.04999 60.95001 Q 199.7 62.20001 199.7 64.70001 Q 199.7 65.70001 199.34999 67.00001 Q 199 68.3 198.2 69.70001 Q 192.09999 80.3 183.65 89.3 Q 175.2 98.3 165.79999 106.00001 Q 165.4 107.50001 165.04999 108.700005 Q 164.7 109.90001 164.5 110.600006 Q 164.4 111.100006 164.4 111.65001 Q 164.4 112.200005 164.4 112.700005 Q 164.4 115.100006 165.2 116.90001 Q 166 118.700005 167.9 118.700005 Q 169.7 118.700005 172.34999 116.950005 Q 175 115.200005 177.7 112.65001 Q 180.4 110.100006 182.59999 107.700005 Q 184.79999 105.30001 185.7 104.00001 Q 186 103.700005 186.29999 103.700005 Q 186.7 103.700005 186.95 104.100006 Q 187.2 104.50001 186.9 105.100006 Q 185.9 106.80001 183.7 109.30001 Q 181.5 111.80001 178.79999 114.350006 Q 176.09999 116.90001 173.59999 118.80001 Q 170.5 121.00001 167.29999 121.00001 ZM 167.2 102.00001 Q 171 99.40001 175.09999 95.25001 Q 179.2 91.100006 183.15 86.20001 Q 187.09999 81.3 190.34999 76.50001 Q 193.59999 71.70001 195.59999 67.8 Q 196.2 66.70001 196.45 65.850006 Q 196.7 65.00001 196.7 64.3 Q 196.7 62.400005 195.09999 62.400005 Q 193.7 62.400005 191.59999 63.900005 Q 186.2 68.100006 181.59999 74.65001 Q 177 81.20001 173.4 88.40001 Q 169.79999 95.600006 167.2 102.00001 Z" fill="currentColor" style="--path-length: 344.0267;"/>
<path d="M 190.69998 121.00001 Q 186.49998 121.00001 184.84999 118.90001 Q 183.19998 116.80001 183.19998 113.700005 Q 183.19998 110.80001 184.54999 106.40001 Q 185.9 102.00001 188.09999 96.90001 Q 190.29999 91.8 192.84999 86.75001 Q 195.4 81.70001 197.94998 77.45001 Q 200.49998 73.20001 202.4 70.600006 Q 204.29999 68.100006 206.49998 65.600006 Q 208.69998 63.100006 211.4 61.400005 Q 214.09999 59.70001 217.49998 59.70001 Q 219.79999 59.70001 221.44998 60.95001 Q 223.09999 62.20001 223.09999 64.70001 Q 223.09999 65.70001 222.74998 67.00001 Q 222.4 68.3 221.59999 69.70001 Q 215.49998 80.3 207.04999 89.3 Q 198.59999 98.3 189.19998 106.00001 Q 188.79999 107.50001 188.44998 108.700005 Q 188.09999 109.90001 187.9 110.600006 Q 187.79999 111.100006 187.79999 111.65001 Q 187.79999 112.200005 187.79999 112.700005 Q 187.79999 115.100006 188.59999 116.90001 Q 189.4 118.700005 191.29999 118.700005 Q 193.09999 118.700005 195.74998 116.950005 Q 198.4 115.200005 201.09999 112.65001 Q 203.79999 110.100006 205.99998 107.700005 Q 208.19998 105.30001 209.09999 104.00001 Q 209.4 103.700005 209.69998 103.700005 Q 210.09999 103.700005 210.34999 104.100006 Q 210.59999 104.50001 210.29999 105.100006 Q 209.29999 106.80001 207.09999 109.30001 Q 204.9 111.80001 202.19998 114.350006 Q 199.49998 116.90001 196.99998 118.80001 Q 193.9 121.00001 190.69998 121.00001 ZM 190.59999 102.00001 Q 194.4 99.40001 198.49998 95.25001 Q 202.59999 91.100006 206.54999 86.20001 Q 210.49998 81.3 213.74998 76.50001 Q 216.99998 71.70001 218.99998 67.8 Q 219.59999 66.70001 219.84999 65.850006 Q 220.09999 65.00001 220.09999 64.3 Q 220.09999 62.400005 218.49998 62.400005 Q 217.09999 62.400005 214.99998 63.900005 Q 209.59999 68.100006 204.99998 74.65001 Q 200.4 81.20001 196.79999 88.40001 Q 193.19998 95.600006 190.59999 102.00001 Z" fill="currentColor" style="--path-length: 344.0267;"/>
<path d="M 215.49998 121.100006 Q 212.69998 121.100006 210.59998 119.80001 Q 207.09998 117.700005 207.09998 112.200005 Q 207.09998 109.90001 207.89998 106.90001 Q 208.59998 104.40001 210.39998 101.450005 Q 212.19998 98.50001 214.64998 95.8 Q 217.09998 93.100006 219.99998 91.40001 Q 222.89998 89.700005 225.79999 89.700005 Q 226.99998 89.700005 227.89998 90.00001 Q 229.09998 90.40001 229.94998 91.450005 Q 230.79999 92.50001 230.79999 94.100006 Q 230.79999 95.8 229.94998 96.00001 Q 229.09998 96.200005 229.09998 95.600006 Q 229.09998 95.40001 229.14998 95.200005 Q 229.19998 95.00001 229.19998 94.90001 Q 229.19998 94.100006 228.74998 93.450005 Q 228.29999 92.8 227.09998 92.8 Q 225.49998 92.8 223.14998 94.50001 Q 220.79999 96.200005 218.34998 99.05 Q 215.89998 101.90001 214.04999 105.30001 Q 212.19998 108.700005 211.59998 112.100006 Q 211.49998 112.600006 211.44998 113.05001 Q 211.39998 113.50001 211.39998 114.00001 Q 211.39998 116.30001 212.44998 117.850006 Q 213.49998 119.40001 215.79999 119.40001 Q 218.59998 119.40001 221.19998 117.25001 Q 223.79999 115.100006 225.84998 112.100006 Q 227.89998 109.100006 228.89998 106.80001 Q 229.69998 105.00001 229.99998 103.700005 Q 230.29999 102.40001 230.29999 101.50001 Q 230.29999 100.700005 230.14998 100.100006 Q 229.99998 99.50001 229.79999 99.100006 Q 229.59998 98.50001 229.59998 98.200005 Q 229.59998 97.40001 230.24998 96.90001 Q 230.89998 96.40001 231.59998 96.40001 Q 232.19998 96.40001 232.89998 96.8 Q 233.69998 97.00001 235.09998 97.100006 Q 236.49998 97.200005 238.09998 97.200005 Q 239.79999 97.200005 241.54999 97.100006 Q 243.29999 97.00001 244.59998 96.700005 Q 244.79999 96.600006 245.19998 96.600006 Q 245.89998 96.600006 245.89998 97.00001 Q 245.89998 97.40001 245.19998 97.700005 Q 241.69998 99.3 238.94998 99.40001 Q 236.19998 99.50001 234.19998 99.50001 Q 234.39998 102.00001 233.09998 104.850006 Q 231.79999 107.700005 230.39998 109.90001 Q 228.69998 112.40001 226.49998 115.00001 Q 224.29999 117.600006 221.59998 119.350006 Q 218.89998 121.100006 215.49998 121.100006 Z" fill="currentColor" style="--path-length: 200.83989;"/>
<path d="M 269.59998 127.90001 Q 265.3 127.90001 263.44998 126.350006 Q 261.59998 124.80001 261.59998 122.30001 Q 261.59998 120.30001 262.59998 117.80001 Q 263.59998 115.30001 265.19998 112.600006 Q 268.69998 106.600006 273.15 100.05 Q 277.59998 93.50001 281.9 87.100006 Q 284.19998 83.600006 286.75 79.95001 Q 289.3 76.3 291.55 72.850006 Q 293.8 69.40001 295.09998 66.600006 Q 294.09998 66.50001 293.09998 66.50001 Q 292.09998 66.50001 291 66.50001 Q 286.69998 66.50001 282.09998 67.15001 Q 277.5 67.8 273.55 69.20001 Q 269.59998 70.600006 267.19998 72.850006 Q 264.8 75.100006 264.8 78.3 Q 264.8 80.3 265.94998 81.50001 Q 267.09998 82.70001 268.55 83.40001 Q 270 84.100006 270.69998 84.600006 Q 271.5 85.100006 271.5 85.40001 Q 271.5 85.600006 271.09998 85.600006 Q 270.3 85.600006 268.25 84.55 Q 266.19998 83.50001 264.5 81.600006 Q 262.8 79.70001 262.69998 77.20001 Q 262.69998 77.00001 262.5 76.600006 Q 262.3 76.20001 262.3 75.90001 Q 262.09998 72.100006 264.19998 69.50001 Q 266.3 66.90001 269.94998 65.25001 Q 273.59998 63.600006 278.09998 62.850006 Q 282.59998 62.100006 287.09998 62.100006 Q 292.09998 62.100006 296.59998 62.900005 Q 296.69998 62.500008 296.75 62.20001 Q 296.8 61.900005 296.8 61.600006 Q 296.8 61.100006 296.59998 60.70001 Q 296.5 60.500008 296.5 60.20001 Q 296.5 59.400005 297.4 59.400005 Q 297.9 59.400005 298.44998 59.750008 Q 299 60.100006 299.3 61.000008 Q 299.4 61.20001 299.4 61.70001 Q 299.4 62.500008 299.09998 63.400005 Q 300.3 63.800007 301.25 64.20001 Q 302.19998 64.600006 303.09998 65.00001 Q 303.9 65.3 304.9 66.25001 Q 305.9 67.20001 305.9 67.8 Q 305.9 68.3 305.09998 68.3 Q 304.69998 68.3 304.09998 68.20001 Q 303.5 68.100006 302.69998 67.8 Q 301.69998 67.50001 300.59998 67.25001 Q 299.5 67.00001 298.3 66.8 Q 296.69998 71.100006 293.5 76.95001 Q 290.3 82.8 286.59998 88.3 Q 283.3 93.3 279.94998 98.50001 Q 276.59998 103.700005 273.84998 108.700005 Q 271.09998 113.700005 269.5 118.200005 Q 269.09998 119.50001 268.9 120.55001 Q 268.69998 121.600006 268.69998 122.40001 Q 268.69998 125.600006 271.8 125.600006 Q 274.5 125.600006 278.9 123.50001 Q 283.3 121.40001 287.9 118.30001 Q 296.19998 112.50001 303.65 105.200005 Q 311.09998 97.90001 316.9 89.700005 Q 316.8 88.50001 316.75 87.15001 Q 316.69998 85.8 316.69998 84.3 Q 316.69998 81.90001 316.84998 79.40001 Q 317 76.90001 317.4 75.00001 Q 317.5 74.20001 318.34998 72.850006 Q 319.19998 71.50001 320.34998 70.40001 Q 321.5 69.3 322.4 69.3 Q 323.3 69.3 323.84998 70.50001 Q 324.4 71.70001 324.4 74.70001 Q 324.4 77.600006 323.84998 81.45001 Q 323.3 85.3 321.5 89.00001 Q 321.4 94.8 322.65 100.25001 Q 323.9 105.700005 326.25 110.00001 Q 328.59998 114.30001 331.59998 116.75001 Q 334.59998 119.200005 338 119.100006 Q 341.8 119.00001 344.84998 116.350006 Q 347.9 113.700005 350.15 109.25001 Q 352.4 104.80001 353.59998 99.50001 Q 354.8 94.200005 354.8 88.90001 Q 354.8 83.600006 353.44998 78.850006 Q 352.09998 74.100006 349.19998 71.00001 Q 346 67.600006 341 67.600006 Q 340.59998 67.600006 340.15 67.600006 Q 339.69998 67.600006 339.19998 67.70001 Q 336.69998 68.00001 334.8 69.50001 Q 334.4 69.70001 334.09998 69.70001 Q 332.9 69.70001 332.9 68.70001 Q 332.9 68.3 333.3 68.00001 Q 338.8 64.20001 344.09998 64.20001 Q 348 64.20001 351.19998 66.3 Q 355.3 68.90001 357.15 74.00001 Q 359 79.100006 359 85.20001 Q 359 91.50001 357.19998 98.15001 Q 355.4 104.80001 352.19998 110.40001 Q 349 116.00001 344.59998 119.450005 Q 340.19998 122.90001 335.09998 122.90001 Q 331.19998 122.90001 327.65 120.75001 Q 324.09998 118.600006 321.5 114.700005 Q 318.9 110.80001 317.55 105.700005 Q 316.19998 100.600006 316.59998 94.8 Q 313.4 98.8 308.94998 103.350006 Q 304.5 107.90001 299.65 112.15001 Q 294.8 116.40001 290.4 119.600006 Q 285.3 123.200005 280.15 125.55001 Q 275 127.90001 269.59998 127.90001 Z" fill="currentColor" style="--path-length: 695.4092;"/>
<path d="M 369.59998 121.100006 Q 366.8 121.100006 364.69998 119.80001 Q 361.19998 117.700005 361.19998 112.200005 Q 361.19998 109.90001 362 106.90001 Q 362.69998 104.40001 364.5 101.450005 Q 366.3 98.50001 368.75 95.8 Q 371.19998 93.100006 374.09998 91.40001 Q 377 89.700005 379.9 89.700005 Q 381.09998 89.700005 382 90.00001 Q 383.19998 90.40001 384.05 91.450005 Q 384.9 92.50001 384.9 94.100006 Q 384.9 95.8 384.05 96.00001 Q 383.19998 96.200005 383.19998 95.600006 Q 383.19998 95.40001 383.25 95.200005 Q 383.3 95.00001 383.3 94.90001 Q 383.3 94.100006 382.84998 93.450005 Q 382.4 92.8 381.19998 92.8 Q 379.59998 92.8 377.25 94.50001 Q 374.9 96.200005 372.44998 99.05 Q 370 101.90001 368.15 105.30001 Q 366.3 108.700005 365.69998 112.100006 Q 365.59998 112.600006 365.55 113.05001 Q 365.5 113.50001 365.5 114.00001 Q 365.5 116.30001 366.55 117.850006 Q 367.59998 119.40001 369.9 119.40001 Q 372.69998 119.40001 375.3 117.25001 Q 377.9 115.100006 379.94998 112.100006 Q 382 109.100006 383 106.80001 Q 383.8 105.00001 384.09998 103.700005 Q 384.4 102.40001 384.4 101.50001 Q 384.4 100.700005 384.25 100.100006 Q 384.09998 99.50001 383.9 99.100006 Q 383.69998 98.50001 383.69998 98.200005 Q 383.69998 97.40001 384.34998 96.90001 Q 385 96.40001 385.69998 96.40001 Q 386.3 96.40001 387 96.8 Q 387.8 97.00001 389.19998 97.100006 Q 390.59998 97.200005 392.19998 97.200005 Q 393.9 97.200005 395.65 97.100006 Q 397.4 97.00001 398.69998 96.700005 Q 398.9 96.600006 399.3 96.600006 Q 400 96.600006 400 97.00001 Q 400 97.40001 399.3 97.700005 Q 395.8 99.3 393.05 99.40001 Q 390.3 99.50001 388.3 99.50001 Q 388.5 102.00001 387.19998 104.850006 Q 385.9 107.700005 384.5 109.90001 Q 382.8 112.40001 380.59998 115.00001 Q 378.4 117.600006 375.69998 119.350006 Q 373 121.100006 369.59998 121.100006 Z" fill="currentColor" style="--path-length: 200.83995;"/>
<path d="M 409.7 121.200005 Q 408 121.200005 406.7 120.450005 Q 405.4 119.700005 404.9 117.600006 Q 404.6 116.50001 404.6 115.40001 Q 404.6 112.40001 406.15 109.55001 Q 407.7 106.700005 409.8 104.25001 Q 411.9 101.8 413.4 100.100006 Q 414.2 99.3 415.25 98.00001 Q 416.3 96.700005 416.3 95.40001 Q 416.3 94.600006 415.5 93.850006 Q 414.7 93.100006 412.6 92.8 Q 411.4 92.600006 410.35 92.450005 Q 409.3 92.3 408.2 92.3 Q 405.4 96.100006 402.75 99.950005 Q 400.1 103.8 397.1 107.50001 Q 396.4 108.200005 395.9 108.200005 Q 395.3 108.200005 395.3 107.600006 Q 395.3 107.00001 395.9 106.40001 Q 401.3 99.8 405.2 92.3 Q 404.7 92.3 403.7 92.25001 Q 402.7 92.200005 402.1 92.100006 Q 401.4 91.90001 401 91.50001 Q 400.6 91.100006 400.6 90.700005 Q 400.6 90.100006 401.1 90.00001 Q 402.4 89.600006 403.9 88.8 Q 405.4 88.00001 406.7 86.70001 Q 408.1 85.3 409.3 83.75001 Q 410.5 82.20001 411.2 81.40001 Q 411.9 80.90001 412.7 80.90001 Q 413.2 80.90001 413.65 81.20001 Q 414.1 81.50001 414.1 82.100006 Q 414.1 82.8 413.5 83.90001 Q 412.6 85.3 411.55 87.00001 Q 410.5 88.700005 409.6 90.100006 Q 411.4 90.200005 413.2 90.3 Q 415 90.40001 416.9 90.40001 Q 417.9 90.40001 418.85 90.350006 Q 419.8 90.3 420.8 90.3 Q 423.8 90.3 423.8 91.8 Q 423.8 92.8 422.75 94.25001 Q 421.7 95.700005 420.2 97.40001 Q 416.8 101.3 414.4 105.600006 Q 412 109.90001 411.2 112.200005 Q 410.4 114.600006 410.4 115.80001 Q 410.4 118.200005 412.3 118.200005 Q 414 118.200005 416.45 116.50001 Q 418.9 114.80001 421.5 112.350006 Q 424.1 109.90001 426.2 107.55001 Q 428.3 105.200005 429.2 104.00001 Q 429.4 103.700005 429.8 103.700005 Q 430.2 103.700005 430.5 104.05001 Q 430.8 104.40001 430.5 104.90001 Q 429.4 106.600006 427.3 109.15001 Q 425.2 111.700005 422.6 114.200005 Q 420 116.700005 417.5 118.50001 Q 416.2 119.50001 413.95 120.350006 Q 411.7 121.200005 409.7 121.200005 Z" fill="currentColor" style="--path-length: 233.69101;"/>
<path d="M 434.3 121.00001 Q 430.1 121.00001 428.44998 118.90001 Q 426.8 116.80001 426.8 113.700005 Q 426.8 110.80001 428.15 106.40001 Q 429.5 102.00001 431.69998 96.90001 Q 433.9 91.8 436.44998 86.75001 Q 439 81.70001 441.55 77.45001 Q 444.1 73.20001 446 70.600006 Q 447.9 68.100006 450.1 65.600006 Q 452.3 63.100006 455 61.400005 Q 457.69998 59.70001 461.1 59.70001 Q 463.4 59.70001 465.05 60.95001 Q 466.69998 62.20001 466.69998 64.70001 Q 466.69998 65.70001 466.35 67.00001 Q 466 68.3 465.19998 69.70001 Q 459.1 80.3 450.65 89.3 Q 442.19998 98.3 432.8 106.00001 Q 432.4 107.50001 432.05 108.700005 Q 431.69998 109.90001 431.5 110.600006 Q 431.4 111.100006 431.4 111.65001 Q 431.4 112.200005 431.4 112.700005 Q 431.4 115.100006 432.19998 116.90001 Q 433 118.700005 434.9 118.700005 Q 436.69998 118.700005 439.35 116.950005 Q 442 115.200005 444.69998 112.65001 Q 447.4 110.100006 449.6 107.700005 Q 451.8 105.30001 452.69998 104.00001 Q 453 103.700005 453.3 103.700005 Q 453.69998 103.700005 453.94998 104.100006 Q 454.19998 104.50001 453.9 105.100006 Q 452.9 106.80001 450.69998 109.30001 Q 448.5 111.80001 445.8 114.350006 Q 443.1 116.90001 440.6 118.80001 Q 437.5 121.00001 434.3 121.00001 ZM 434.19998 102.00001 Q 438 99.40001 442.1 95.25001 Q 446.19998 91.100006 450.15 86.20001 Q 454.1 81.3 457.35 76.50001 Q 460.6 71.70001 462.6 67.8 Q 463.19998 66.70001 463.44998 65.850006 Q 463.69998 65.00001 463.69998 64.3 Q 463.69998 62.400005 462.1 62.400005 Q 460.69998 62.400005 458.6 63.900005 Q 453.19998 68.100006 448.6 74.65001 Q 444 81.20001 440.4 88.40001 Q 436.8 95.600006 434.19998 102.00001 Z" fill="currentColor" style="--path-length: 344.02676;"/>
<path d="M 478.09998 130.90001 Q 475.5 130.5 474.4 128.40001 Q 473.3 126.30001 473.3 123.200005 Q 473.3 119.50001 474.34998 115.200005 Q 475.4 110.90001 476.8 107.100006 Q 478.19998 103.3 479 101.3 Q 476.69998 104.00001 473.75 107.200005 Q 470.8 110.40001 467.59998 113.30001 Q 464.4 116.200005 461.44998 118.05001 Q 458.5 119.90001 456.3 119.90001 Q 454.69998 119.90001 452.9 118.950005 Q 451.09998 118.00001 450 116.50001 Q 448.5 114.50001 448.5 112.40001 Q 448.5 109.700005 450.34998 106.80001 Q 452.19998 103.90001 455.15 101.15001 Q 458.09998 98.40001 461.44998 96.15001 Q 464.8 93.90001 467.84998 92.350006 Q 470.9 90.8 472.8 90.3 Q 473.8 90.100006 474.9 89.90001 Q 476 89.700005 477.19998 89.700005 Q 478.69998 89.700005 480.19998 90.05 Q 481.69998 90.40001 482.69998 91.200005 L 483.09998 91.50001 Q 485.5 86.00001 488.4 80.350006 Q 491.3 74.70001 494.59998 70.00001 Q 497.9 65.3 501.59998 62.45001 Q 505.3 59.600006 509.3 59.600006 Q 509.8 59.600006 510.3 59.650005 Q 510.8 59.70001 511.19998 59.800007 Q 513.7 60.300007 514.75 61.550007 Q 515.8 62.800007 515.8 64.50001 Q 515.8 65.70001 515.35 67.05 Q 514.89996 68.40001 514.1 69.70001 Q 511.9 73.600006 508.34998 77.40001 Q 504.8 81.20001 500.59998 84.75001 Q 496.4 88.3 492.25 91.600006 Q 488.09998 94.90001 484.69998 97.8 Q 483.19998 101.3 481.69998 106.00001 Q 480.19998 110.700005 479.19998 114.00001 Q 478.59998 116.40001 478.25 118.50001 Q 477.9 120.600006 477.9 122.40001 Q 477.9 125.700005 479.09998 127.80001 Q 480.09998 129.40001 481.59998 129.40001 Q 482.69998 129.40001 483.59998 128.6 Q 484 128.40001 484.34998 128.1 Q 484.69998 127.80001 485.19998 127.50001 Q 485.8 127.200005 486.19998 127.200005 Q 486.9 127.200005 486.3 128.3 Q 486 128.6 485.59998 129.05 Q 485.19998 129.5 484.69998 130 Q 484 130.5 482.59998 130.8 Q 481.19998 131.1 479.8 131.1 Q 479.4 131.1 478.94998 131.05 Q 478.5 131 478.09998 130.90001 ZM 487.69998 92.100006 Q 491.69998 89.40001 496.4 85.350006 Q 501.09998 81.3 505.19998 76.65001 Q 509.3 72.00001 511.5 67.8 Q 512.8 65.40001 512.8 64.00001 Q 512.8 62.300007 511.3 62.300007 Q 509.9 62.300007 507.59998 63.900005 Q 500.9 69.100006 496.3 76.25001 Q 491.69998 83.40001 487.69998 92.100006 ZM 453.5 117.50001 Q 454 118.100006 454.8 118.100006 Q 456.3 118.100006 458.34998 116.80001 Q 460.4 115.50001 461.09998 114.80001 Q 466.19998 110.700005 471.34998 105.950005 Q 476.5 101.200005 481 96.40001 Q 481.4 95.50001 481.69998 94.65001 Q 482 93.8 482.4 93.00001 Q 480.9 92.40001 478.9 92.40001 Q 474.9 92.40001 470.09998 95.00001 Q 465.3 97.600006 461.5 101.100006 Q 460.3 102.100006 458.25 104.55001 Q 456.19998 107.00001 454.5 109.90001 Q 452.8 112.80001 452.8 115.200005 Q 452.8 116.50001 453.5 117.50001 Z" fill="currentColor" style="--path-length: 523.96173;"/>
</svg>
## 准备 SVG 文字
动态文字动画需要一个包含文字路径的 SVG使用 `<path>` 元素定义文字形状。以下是一个典型的 SVG 结构:
```html
<svg class="animated-text" preserveAspectRatio="xMidYMid meet" style="width: 100%; height: 100%;" viewBox="0 0 300 100" xmlns="http://www.w3.org/2000/svg">
<path d="M10 80 Q 95 10 180 80" fill="currentColor" style="--path-length: 200;"/>
</svg>
```
### SVG `<path>` 属性定义
以下是 `<path>` 元素中与动画相关的关键属性的说明:
- **`fill` 属性**:控制路径填充颜色。
- **作用**:决定路径内部颜色,动画中常用于填充效果。
- **推荐值**`fill="currentColor"` 使填充与父元素颜色一致;`fill="transparent"` 用于描边阶段。
- **生成方式**Rust 代码中通过 `Path::new().set("fill", "currentColor")` 设置。
- **注意**:动画初期通常设为 `transparent`,后期切换到 `currentColor`。
- **`style` 属性**:设置 CSS 自定义属性。
- **作用**:定义 `--path-length`,表示路径长度,用于 CSS 动画。
- **生成方式**Rust 代码通过 `PathBuilder` 计算路径长度(`calculate_distance` 和 `calculate_curve_length`),设置如 `style="--path-length: 200;"`。
- **示例**`style="--path-length: 200;"` 表示路径长 200 单位。
- **注意**:长度需精确,可用 JavaScript 的 `path.getTotalLength()` 验证。
### SVG 配置
- **类名**:为 `<svg>` 设置 `class="animated-text"`。
- **视图框**:使用 `viewBox="0 0 300 100"` 适配内容。
- **比例**`preserveAspectRatio="xMidYMid meet"` 确保居中缩放。
## 编写 CSS 动画
CSS 动画通过 `stroke-dasharray` 和 `stroke-dashoffset` 实现描边效果,结合 `fill` 切换填充。以下是完整代码:
```css
.animated-text path {
fill: transparent;
stroke: currentColor;
stroke-width: 2;
stroke-dasharray: var(--path-length);
stroke-dashoffset: var(--path-length);
animation: logo-anim 10s ease-in-out infinite;
}
@keyframes logo-anim {
0% {
stroke-dashoffset: var(--path-length);
fill: transparent;
opacity: 0;
}
10% {
opacity: 1;
stroke-dashoffset: var(--path-length);
}
50% {
stroke-dashoffset: 0;
fill: transparent;
}
60% {
stroke-dashoffset: 0;
fill: currentColor;
}
80% {
stroke-dashoffset: 0;
fill: currentColor;
}
90% {
stroke-dashoffset: var(--path-length);
fill: transparent;
}
100% {
stroke-dashoffset: var(--path-length);
fill: transparent;
opacity: 0;
}
}
@media (prefers-color-scheme: dark) {
.animated-text path {
stroke: currentColor;
}
}
```
- **说明**
- **样式**`fill: transparent` 初始无填充,`stroke: currentColor` 描边与父元素颜色一致,`stroke-width: 2` 设置描边粗细。
- **动画**`stroke-dasharray` 和 `stroke-dashoffset` 使用 `--path-length` 控制虚线和偏移。
- **流程**0%-10% 淡入50% 描边完成60%-80% 填充颜色90%-100% 描边退回并淡出。
- **参数**`10s` 持续时间,`ease-in-out` 缓动,`infinite` 循环。
- **暗色模式**:确保描边颜色适配主题。