Skip to content

Commit

Permalink
feat: slider linear
Browse files Browse the repository at this point in the history
  • Loading branch information
wkylin committed Dec 3, 2024
1 parent 274ab66 commit 3c3800b
Show file tree
Hide file tree
Showing 6 changed files with 203 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/components/hooks/useInViewport/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useEffect, useRef, useState } from 'react';

Check failure on line 1 in src/components/hooks/useInViewport/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package

const useInViewport = () => {
const inViewRef = useRef(null);
const [inViewport, setInViewport] = useState(false);

useEffect(() => {
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setInViewport(true);
} else {
setInViewport(false);
}
});
});

if (inViewRef.current) {
observer.observe(inViewRef.current);
}

return () => {
if (inViewRef.current) {
observer.unobserve(inViewRef.current);
}
};
}, []);

return {
inViewRef,
inViewport
};
};

export default useInViewport;
68 changes: 68 additions & 0 deletions src/components/hooks/useScrollIntoView/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { useEffect, useRef, useState } from 'react';

Check failure on line 1 in src/components/hooks/useScrollIntoView/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package


const useScrollIntoView = ({offset = 0}) => {
const targetRef = useRef<T>(null);

Check warning on line 5 in src/components/hooks/useScrollIntoView/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Pointless statement or boolean expression

Can be simplified to null
const [isScrolled, setIsScrolled] = useState(false);

const scrollIntoView = () => {
if (targetRef.current) {
const rect = targetRef.current.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;

Check notice on line 11 in src/components/hooks/useScrollIntoView/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Deprecated symbol used

Deprecated symbol used, consult docs for better alternative
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;

Check notice on line 12 in src/components/hooks/useScrollIntoView/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Deprecated symbol used

Deprecated symbol used, consult docs for better alternative
const elementTop = rect.top + scrollTop;
const elementLeft = rect.left + scrollLeft;

const windowHeight = window.innerHeight;
const windowWidth = window.innerWidth;

// 根据偏移量调整滚动位置
const adjustedTop = elementTop - offset;
const adjustedLeft = elementLeft - offset;

// 判断是否需要滚动
const shouldScrollY = adjustedTop < 0 || adjustedTop > windowHeight;
const shouldScrollX = adjustedLeft < 0 || adjustedLeft > windowWidth;

if (shouldScrollY) {
window.scrollTo({
top: shouldScrollY? adjustedTop : scrollTop,
behavior: 'smooth'
});
}

if (shouldScrollX) {
window.scrollTo({
left: shouldScrollX? adjustedLeft : scrollLeft,
behavior: 'smooth'
});
}

setIsScrolled(true);
}
};

useEffect(() => {
if (isScrolled) {
setIsScrolled(false);
}
}, [isScrolled]);

return {
scrollIntoView,
targetRef
};
};

export default useScrollIntoView;

// const { scrollIntoView, targetRef } = useScrollIntoView({
// offset: 60
// });

// return (
// <div>
// <div ref={targetRef}>这是要滚动到的目标元素</div>
// <button onClick={scrollIntoView}>滚动到目标元素</button>
// </div>
// );
37 changes: 37 additions & 0 deletions src/components/hooks/useWindowScroll/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, useEffect } from 'react';

Check failure on line 1 in src/components/hooks/useWindowScroll/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package

const useWindowScroll = () => {
// 用于存储窗口滚动位置的状态
const [scroll, setScroll] = useState({
x: window.pageXOffset,

Check notice on line 6 in src/components/hooks/useWindowScroll/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Deprecated symbol used

Deprecated symbol used, consult docs for better alternative
y: window.pageYOffset

Check notice on line 7 in src/components/hooks/useWindowScroll/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Deprecated symbol used

Deprecated symbol used, consult docs for better alternative
});

// 用于更新滚动位置状态的函数
const handleScroll = () => {
setScroll({
x: window.pageXOffset,

Check notice on line 13 in src/components/hooks/useWindowScroll/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Deprecated symbol used

Deprecated symbol used, consult docs for better alternative
y: window.pageYOffset

Check notice on line 14 in src/components/hooks/useWindowScroll/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

Deprecated symbol used

Deprecated symbol used, consult docs for better alternative
});
};

// 在组件挂载时添加滚动事件监听器,在组件卸载时移除监听器
useEffect(() => {
window.addEventListener('scroll', handleScroll);

return () => {
window.removeEventListener('scroll', handleScroll);
};
}, []);

// 返回滚动位置对象以及设置滚动位置的方法
return {
scroll,
setScroll: (newScroll) => {
window.scrollTo(newScroll.x, newScroll.y);
setScroll(newScroll);
}
};
};

export default useWindowScroll;
13 changes: 13 additions & 0 deletions src/components/stateless/SlideLinear/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react'

Check failure on line 1 in src/components/stateless/SlideLinear/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package
import styles from './index.module.less'
const SlideLinear = ({children}) => {
return (
<div className={styles.slider}>
<div className={styles.content}>
{children}
</div>
</div>
)
}

export default SlideLinear
36 changes: 36 additions & 0 deletions src/components/stateless/SlideLinear/index.module.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.slider {
overflow: hidden;
width: 100%;
position: relative;
}

.content {
display: flex;
white-space: nowrap;
animation: 90s linear 0s infinite normal none running slide-right;
}

@keyframes slide-left {
0% {
transform: translate(0);
}

50% {
transform: translate(-100%);
}
100% {
transform: translate(0);
}
}
@keyframes slide-right {
0% {
transform: translate(0);
}

50% {
transform: translate(100%);
}
100% {
transform: translate(0);
}
}
14 changes: 14 additions & 0 deletions src/pages/home/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import AnimateRipple from '@stateless/AnimateRipple'
import AnimateWave from '@stateless/AnimateWave'
import MeshGradientBackground from '@stateless/MeshGradientBackground'
import TagCloud from '@stateless/TagCloud'
import SlideLinear from '@stateless/SlideLinear'
import Masonry from '@container/masonryContainer'

import { oneApiChat, prettyObject } from '@utils/aidFn'
Expand Down Expand Up @@ -304,6 +305,18 @@ const Home = () => {
<section style={{ margin: 20 }}>
<TagCloud />
</section>
<section style={{ margin: 20 }}>
<SlideLinear >
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
<div style={{ width: 200, height: 40, background: '#aaa', margin: '0 10px', borderRadius: 4}}></div>
</SlideLinear>
</section>

<section style={{ width: 600, margin: '30px 0' }}>
<Input defaultValue={apiKey} placeholder="api key" onChange={changeApiKey} style={{ marginBottom: 20 }} />
Expand Down Expand Up @@ -340,6 +353,7 @@ const Home = () => {
<ReMarkdown markdownText={aiText} isLoading={isStream} />
</section>


<section style={{ position: 'relative', height: 300 }}>
<AnimateWave>
<p> wave </p>
Expand Down

0 comments on commit 3c3800b

Please sign in to comment.