feat: 添加预览效果页面并优化交互效果
refactor: 优化代码健壮性和类型安全 style: 更新字体样式和全局CSS fix: 修复IntersectionObserver潜在空引用问题 chore: 更新依赖和ESLint配置 build: 更新构建ID和路由配置
This commit is contained in:
@@ -342,7 +342,7 @@ export function CountUp({ end, duration = 2000, delay = 0, prefix = '', suffix =
|
||||
const hasAnimated = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInView || hasAnimated.current) return;
|
||||
if (!isInView || hasAnimated.current) {return;}
|
||||
|
||||
hasAnimated.current = true;
|
||||
|
||||
@@ -398,12 +398,12 @@ interface TypewriterProps {
|
||||
|
||||
export function Typewriter({ text, delay = 0, speed = 50, className = '', cursorClassName = '' }: TypewriterProps) {
|
||||
const [displayText, setDisplayText] = useState('');
|
||||
const [isTyping, setIsTyping] = useState(false);
|
||||
const [_isTyping, setIsTyping] = useState(false);
|
||||
const ref = useRef<HTMLSpanElement>(null);
|
||||
const isInView = useInView(ref, { once: true });
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInView) return;
|
||||
if (!isInView) {return;}
|
||||
|
||||
const startTyping = setTimeout(() => {
|
||||
setIsTyping(true);
|
||||
@@ -605,13 +605,13 @@ export function SplitText({ text, className = '', delay = 0, staggerDelay = 0.03
|
||||
initial="hidden"
|
||||
animate={isInView ? 'visible' : 'hidden'}
|
||||
className={className}
|
||||
style={{ display: 'inline-block' }}
|
||||
style={{ display: 'inline-block', fontFamily: 'inherit' }}
|
||||
>
|
||||
{text.split('').map((char, index) => (
|
||||
<motion.span
|
||||
key={index}
|
||||
variants={child}
|
||||
style={{ display: 'inline-block' }}
|
||||
style={{ display: 'inline-block', fontFamily: 'inherit' }}
|
||||
>
|
||||
{char === ' ' ? '\u00A0' : char}
|
||||
</motion.span>
|
||||
@@ -659,7 +659,7 @@ export function MagneticButton({ children, className = '', strength = 0.3, onCli
|
||||
const [position, setPosition] = useState({ x: 0, y: 0 });
|
||||
|
||||
const handleMouseMove = (e: React.MouseEvent<HTMLDivElement>) => {
|
||||
if (!ref.current) return;
|
||||
if (!ref.current) {return;}
|
||||
const rect = ref.current.getBoundingClientRect();
|
||||
const centerX = rect.left + rect.width / 2;
|
||||
const centerY = rect.top + rect.height / 2;
|
||||
@@ -886,13 +886,13 @@ export function CounterWithEffect({
|
||||
effect = 'bounce'
|
||||
}: CounterWithEffectProps) {
|
||||
const [count, setCount] = useState(0);
|
||||
const [prevCount, setPrevCount] = useState(0);
|
||||
const [_prevCount, setPrevCount] = useState(0);
|
||||
const ref = useRef<HTMLSpanElement>(null);
|
||||
const isInView = useInView(ref, { once: true, margin: '-100px' });
|
||||
const hasAnimated = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isInView || hasAnimated.current) return;
|
||||
if (!isInView || hasAnimated.current) {return;}
|
||||
hasAnimated.current = true;
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Company Information
|
||||
export const COMPANY_INFO = {
|
||||
name: '四川睿新致远科技有限公司',
|
||||
shortName: '睿新致远',
|
||||
shortName: '睿新致遠',
|
||||
slogan: '专注科技创新,驱动智慧未来',
|
||||
description: '专注于信息技术服务与解决方案,为企业提供全方位的数字化转型支持',
|
||||
founded: '2026',
|
||||
|
||||
+1
-1
@@ -38,5 +38,5 @@ export function escapeHTML(str: string): string {
|
||||
'/': '/',
|
||||
};
|
||||
|
||||
return str.replace(/[&<>"'/]/g, (char) => map[char]);
|
||||
return str.replace(/[&<>"'/]/g, (char) => map[char] ?? char);
|
||||
}
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ export function debounce<T extends (...args: unknown[]) => unknown>(
|
||||
): (...args: Parameters<T>) => void {
|
||||
let timeout: NodeJS.Timeout | null = null
|
||||
return (...args: Parameters<T>) => {
|
||||
if (timeout) clearTimeout(timeout)
|
||||
if (timeout) {clearTimeout(timeout)}
|
||||
timeout = setTimeout(() => func(...args), wait)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user