Skip to content

万宝锐旗外包-田晓宝前端面试 #1834

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 45 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,50 @@
import Carousel from './components/Carousel';
import img1 from './assets/iphone.png';
import img2 from './assets/tablet.png';
import img3 from './assets/airpods.png';
import './App.css';

function App() {
return <div className='App'>{/* write your component here */}</div>;
// 轮播图传入数据
const data = [
{
bgColor: '#000',
image: img1,
text: (
<>
<div className='carousel-item-title'>xPhone</div>
<div className='carousel-item-desc' style={{ fontWeight: 'normal' }}>Lots to love.Less to spend.<br/>Starting at $399.</div>
</>
)
},
{
bgColor: '#fff',
image: img2,
text: (
<>
<div className='carousel-item-title' style={{ color:'#000' }}>Tablet</div>
<div className='carousel-item-desc' style={{ color:'#000', fontWeight: 'normal'}}>Just the right amount of everything.</div>
</>
)
},
{
bgColor: '#666',
image: img3,
text: (
<>
<div className='carousel-item-title' style={{ color:'#000' }}>Buy a Tablet or xPhone for college.<br/>Get arPods.</div>
</>
)
}
];
return (
<div className='App'>
<Carousel
data={data}
interval={2}
/>
</div>
);
}

export default App;
export default App;
66 changes: 66 additions & 0 deletions frontend/src/components/Carousel/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
.carousel-wrapper {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.carousel {
position: absolute;
height: 100%;
display: flex;
}
.carousel-item {
position: relative;
width: 100vw;
}
.carousel-item-text {
position: absolute;
top: 20%;
left: 0;
right: 0;
margin: auto;
z-index: 1;
}
.carousel-item-title {
font-size: 50px;
font-weight: bold;
color:#fff;
}
.carousel-item-desc {
font-size: 20px;
color:#fff;
margin-top: 20px;
}
.carousel-item img {
width:100%;
height:100%;
position: absolute;
top:0;
bottom:0;
left:0;
right:0;
margin: auto;
}
.carousel-lineBox {
width: 200px;
height: 4px;
position: absolute;
bottom: 90px;
left: 0;
right: 0;
margin: auto;
display: flex;
}
.carousel-line{
width: 50px;
height: 3px;
background-color: gray;
margin-left: 10px;
cursor: pointer;
border-radius: 2px;
}
.carousel-line-active {
width: 0;
height: 3px;
background-color: #fff;
}
61 changes: 61 additions & 0 deletions frontend/src/components/Carousel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useState, useEffect } from 'react';
import './index.css'

interface CarouselProps {
data?: { bgColor?: string, image: string, text: React.ReactNode }[]; // 轮播数据
interval?: number; // 轮播间隔,默认3s
}

const Carousel1: React.FC<CarouselProps> = ({ data = [], interval = 3 }) => {
// 当前展示的轮播图索引
const [currentIndex, setCurrentIndex] = useState(0);
const [translateX, setTranslateX] = useState(0);

// 改变当前索引及动画效果
const slideFn = (idx: number) => {
setCurrentIndex(idx);
setTranslateX(-(idx) * 100);
};

useEffect(() => {
// 下个轮播图索引
const nextIndex = (currentIndex + 1) % data.length;
// 启用计时器
const timeout = setTimeout(() => {
slideFn(nextIndex);
}, interval * 1000);
// 清除计时器
return () => {
clearTimeout(timeout);
};
}, [currentIndex, data.length, interval]);

return (
<div className="carousel-wrapper">
<div
className="carousel"
style={{ transform: `translateX(${translateX}vw)`, transition: 'transform 0.5s' }}
>
{
data.map((item, index) => (
<div className="carousel-item" key={index} style={{ backgroundColor: item.bgColor}}>
<div className='carousel-item-text'>{item.text}</div>
<img src={item.image} alt={`img-${index}`} />
</div>
))
}
</div>
<div className="carousel-lineBox">
{
data.map((item, index) => (
<div className="carousel-line" key={index} onClick={() => slideFn(index)}>
<div className='carousel-line-active' style={{ width: currentIndex === index ? '100%' : 0, transition: currentIndex === index ? `all ${interval}s linear`: 'none'}}></div>
</div>
))
}
</div>
</div>
);
};

export default Carousel1;