Skip to content

Commit 67ad325

Browse files
committed
fix: 修复 lint 错误和微信群图片本地化
- 将微信群二维码图片从外部CDN改为本地静态资源 - 重构 TrieCanvas.tsx,将辅助函数移到 useEffect 内部避免依赖问题 - 优化 PlaybackControls.tsx 中的 updateProgress 函数依赖
1 parent fb24080 commit 67ad325

4 files changed

Lines changed: 89 additions & 88 deletions

File tree

public/wechat-qr.png

328 KB
Loading

src/components/PlaybackControls.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ const PlaybackControls: React.FC<PlaybackControlsProps> = ({
8181
setShowSpeedMenu(false);
8282
};
8383

84+
// 更新进度
85+
const updateProgress = useCallback((e: React.MouseEvent | MouseEvent) => {
86+
if (!progressRef.current || playbackState.totalSteps === 0) return;
87+
88+
const rect = progressRef.current.getBoundingClientRect();
89+
const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
90+
const percentage = x / rect.width;
91+
const step = Math.round(percentage * (playbackState.totalSteps - 1));
92+
onSeek(step);
93+
}, [playbackState.totalSteps]);
94+
8495
// 进度条拖拽
8596
const handleProgressMouseDown = (e: React.MouseEvent) => {
8697
setIsDragging(true);
@@ -108,16 +119,6 @@ const PlaybackControls: React.FC<PlaybackControlsProps> = ({
108119
};
109120
}, [isDragging, handleProgressMouseMove, handleProgressMouseUp]);
110121

111-
const updateProgress = (e: React.MouseEvent | MouseEvent) => {
112-
if (!progressRef.current || playbackState.totalSteps === 0) return;
113-
114-
const rect = progressRef.current.getBoundingClientRect();
115-
const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
116-
const percentage = x / rect.width;
117-
const step = Math.round(percentage * (playbackState.totalSteps - 1));
118-
onSeek(step);
119-
};
120-
121122
const progress = playbackState.totalSteps > 0
122123
? (playbackState.currentStep / (playbackState.totalSteps - 1)) * 100
123124
: 0;

src/components/TrieCanvas.tsx

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useEffect, useState, useCallback } from 'react';
1+
import React, { useRef, useEffect, useState } from 'react';
22
import * as d3 from 'd3';
33
import type { VisualNode, AlgorithmStep, Annotation } from '../types';
44
import './TrieCanvas.css';
@@ -24,81 +24,6 @@ const TrieCanvas: React.FC<TrieCanvasProps> = ({ currentStep }) => {
2424
const [isDragging, setIsDragging] = useState(false);
2525
const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
2626

27-
// 计算树的布局
28-
const calculateLayout = useCallback((node: VisualNode | null, depth: number = 0, index: number = 0, siblingCount: number = 1): TreeNode | null => {
29-
if (!node) return null;
30-
31-
const horizontalSpacing = 70;
32-
const verticalSpacing = 80;
33-
34-
// 计算子节点
35-
const children: TreeNode[] = [];
36-
node.children.forEach((child, i) => {
37-
const childNode = calculateLayout(child, depth + 1, i, node.children.length);
38-
if (childNode) children.push(childNode);
39-
});
40-
41-
// 计算当前节点位置
42-
let x = 0;
43-
if (children.length > 0) {
44-
// 父节点居中于子节点
45-
const leftMost = children[0].x;
46-
const rightMost = children[children.length - 1].x;
47-
x = (leftMost + rightMost) / 2;
48-
} else {
49-
x = (index - (siblingCount - 1) / 2) * horizontalSpacing;
50-
}
51-
52-
return {
53-
id: node.id,
54-
char: node.char,
55-
isEnd: node.isEnd,
56-
x,
57-
y: depth * verticalSpacing,
58-
children,
59-
highlighted: currentStep?.highlightedNodes.includes(node.id) || false,
60-
};
61-
}, [currentStep]);
62-
63-
// 调整树的位置避免重叠
64-
const adjustTreePositions = useCallback((root: TreeNode | null): TreeNode | null => {
65-
if (!root) return null;
66-
67-
const nodePositions: Map<number, number[]> = new Map();
68-
69-
const collectPositions = (node: TreeNode) => {
70-
const level = Math.round(node.y / 80);
71-
if (!nodePositions.has(level)) {
72-
nodePositions.set(level, []);
73-
}
74-
nodePositions.get(level)!.push(node.x);
75-
node.children.forEach(collectPositions);
76-
};
77-
78-
const adjustNode = (node: TreeNode, offset: number): TreeNode => {
79-
return {
80-
...node,
81-
x: node.x + offset,
82-
children: node.children.map(child => adjustNode(child, offset)),
83-
};
84-
};
85-
86-
collectPositions(root);
87-
88-
// 找到最小x值,确保树居中
89-
let minX = Infinity;
90-
let maxX = -Infinity;
91-
nodePositions.forEach(positions => {
92-
positions.forEach(x => {
93-
minX = Math.min(minX, x);
94-
maxX = Math.max(maxX, x);
95-
});
96-
});
97-
98-
const centerOffset = -(minX + maxX) / 2;
99-
return adjustNode(root, centerOffset);
100-
}, []);
101-
10227
// 渲染树
10328
useEffect(() => {
10429
if (!svgRef.current || !containerRef.current) return;
@@ -125,6 +50,81 @@ const TrieCanvas: React.FC<TrieCanvasProps> = ({ currentStep }) => {
12550
return;
12651
}
12752

53+
// 计算树的布局 - 内联函数避免依赖问题
54+
const calculateLayout = (node: VisualNode | null, depth: number = 0, index: number = 0, siblingCount: number = 1): TreeNode | null => {
55+
if (!node) return null;
56+
57+
const horizontalSpacing = 70;
58+
const verticalSpacing = 80;
59+
60+
// 计算子节点
61+
const children: TreeNode[] = [];
62+
node.children.forEach((child, i) => {
63+
const childNode = calculateLayout(child, depth + 1, i, node.children.length);
64+
if (childNode) children.push(childNode);
65+
});
66+
67+
// 计算当前节点位置
68+
let x = 0;
69+
if (children.length > 0) {
70+
// 父节点居中于子节点
71+
const leftMost = children[0].x;
72+
const rightMost = children[children.length - 1].x;
73+
x = (leftMost + rightMost) / 2;
74+
} else {
75+
x = (index - (siblingCount - 1) / 2) * horizontalSpacing;
76+
}
77+
78+
return {
79+
id: node.id,
80+
char: node.char,
81+
isEnd: node.isEnd,
82+
x,
83+
y: depth * verticalSpacing,
84+
children,
85+
highlighted: currentStep.highlightedNodes.includes(node.id),
86+
};
87+
};
88+
89+
// 调整树的位置避免重叠 - 内联函数避免依赖问题
90+
const adjustTreePositions = (root: TreeNode | null): TreeNode | null => {
91+
if (!root) return null;
92+
93+
const nodePositions: Map<number, number[]> = new Map();
94+
95+
const collectPositions = (node: TreeNode) => {
96+
const level = Math.round(node.y / 80);
97+
if (!nodePositions.has(level)) {
98+
nodePositions.set(level, []);
99+
}
100+
nodePositions.get(level)!.push(node.x);
101+
node.children.forEach(collectPositions);
102+
};
103+
104+
const adjustNode = (node: TreeNode, offset: number): TreeNode => {
105+
return {
106+
...node,
107+
x: node.x + offset,
108+
children: node.children.map(child => adjustNode(child, offset)),
109+
};
110+
};
111+
112+
collectPositions(root);
113+
114+
// 找到最小x值,确保树居中
115+
let minX = Infinity;
116+
let maxX = -Infinity;
117+
nodePositions.forEach(positions => {
118+
positions.forEach(x => {
119+
minX = Math.min(minX, x);
120+
maxX = Math.max(maxX, x);
121+
});
122+
});
123+
124+
const centerOffset = -(minX + maxX) / 2;
125+
return adjustNode(root, centerOffset);
126+
};
127+
128128
let root = calculateLayout(currentStep.trieSnapshot, 0, 0, 1);
129129
root = adjustTreePositions(root);
130130

@@ -269,7 +269,7 @@ const TrieCanvas: React.FC<TrieCanvasProps> = ({ currentStep }) => {
269269
});
270270
}
271271

272-
}, [currentStep, transform, calculateLayout, adjustTreePositions]);
272+
}, [currentStep, transform]);
273273

274274
// 鼠标拖拽
275275
const handleMouseDown = (e: React.MouseEvent) => {

src/components/WeChatFloat.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const WeChatFloat: React.FC = () => {
2121
<div className="qr-popup">
2222
<div className="qr-content">
2323
<img
24-
src="https://cdn.jsdelivr.net/gh/JSREI/.github/profile/README.assets/image-20231030132026541-7614065.png"
24+
src="/leetcode-208-implement-trie-prefix-tree/wechat-qr.png"
2525
alt="微信交流群"
2626
className="qr-image"
2727
/>

0 commit comments

Comments
 (0)