Skip to content

Commit

Permalink
Merge branch 'unit/28-speed-controller'
Browse files Browse the repository at this point in the history
  • Loading branch information
ElynnaChuang committed May 26, 2023
2 parents 56ebff3 + 38d3b06 commit b860a7f
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 0 deletions.
55 changes: 55 additions & 0 deletions src/Components/28Slider/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useRef, useState } from 'react';
import styles from './styles.module.scss';

function roundUp(num) {
return Math.round(num * 100) / 100;
}

export const Slider = ({ playRate, setPlayRate }) => {
const MIN_RATE = 0.5;
const MAX_RATE = 3;
const intialHeight = ((playRate - MIN_RATE) / (MAX_RATE - MIN_RATE)) * 100;

const [barHeight, setBarHeight] = useState(intialHeight);
const [isClick, setIsClick] = useState(false);
const speedRef = useRef();

const handleMouseDown = () => {
setIsClick(true);
};

const handleMouseMove = e => {
if (!isClick) return;
const rect = e.target.getBoundingClientRect();
const { top, height } = rect;

const mouseToTop = e.pageY - top;

const percent = roundUp((height - mouseToTop) / height);
setBarHeight(percent * 100);

const rate = roundUp((MAX_RATE - MIN_RATE) * percent + MIN_RATE);
setPlayRate(rate);
};

const handleMouseUp = () => {
setIsClick(false);
};

return (
<div className={styles.slider_container}>
<div
className={styles.bar}
ref={speedRef}
onMouseMove={handleMouseMove}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
role='button'
tabIndex={0}
>
<div className={styles.color} style={{ height: `${barHeight}%` }} />
</div>
<span className={styles.num}>{playRate} X</span>
</div>
);
};
44 changes: 44 additions & 0 deletions src/Components/28Slider/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.slider_container {
cursor: ns-resize;

display: flex;
flex-direction: column;
gap: 1rem;
align-items: center;
justify-content: center;

min-width: 50px;
height: auto;
}

.bar {
overflow: hidden;
display: flex;
flex: 1;
align-items: flex-end;

width: 100%;

background-color: #fff;
border-radius: 4px;

.color {
pointer-events: none;
display: flex;
width: 100%;
background: linear-gradient(#c2e2ff, #225683);
}
}

.num {
width: 100%;
padding: 0.5rem 0;

font-size: 0.75rem;
font-weight: 700;
color: #fff;
text-align: center;

background-color: #63aae9;
border-radius: 4px;
}
1 change: 1 addition & 0 deletions src/Components/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export { Paragraph } from './13Paragraph';
export { Example } from './14Example';
export { Form } from './15Form';
export { List } from './15List';
export { Slider } from './28Slider';

export { Title } from './Titles';

Expand Down
32 changes: 32 additions & 0 deletions src/Pages/28SpeedController/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import ReactPlayer from 'react-player';
import { useRef, useState } from 'react';
import video from '../../Assets/11video.mp4';

import { LayoutCol1 } from '@/Layouts';
import { Slider, Title } from '@/Components';
import styles from './styles.module.scss';

const SpeedControllerPage = () => {
const videoPlayerRef = useRef(null);
const [playRate, setPlayRate] = useState(1);

return (
<LayoutCol1 baseClassName={styles.page}>
<Title title='Video Speed Slider' size='s' titleClassName={styles.title} />
<div className={styles.content}>
<ReactPlayer
url={video}
style={{ display: 'flex' }}
ref={videoPlayerRef}
controls
width='100%'
height='auto'
playbackRate={playRate}
/>
<Slider playRate={playRate} setPlayRate={setPlayRate} />
</div>
</LayoutCol1>
);
};

export default SpeedControllerPage;
18 changes: 18 additions & 0 deletions src/Pages/28SpeedController/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.page {
align-items: center;
justify-content: center;
background: #f6d49a;
}

.title {
padding: 0.5rem;
color: #629fd5;
background: linear-gradient(to right, #fff0, #fff, #fff, #fff0);
}

.content {
display: flex;
gap: 1rem;
height: max-content;
margin-bottom: 160px;
}
3 changes: 3 additions & 0 deletions src/routesConfig.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ const StickyNavPage = lazy(() => import('./Pages/24StickyNav'));
const EventPage = lazy(() => import('./Pages/25Event'));
const NavDropdownPage = lazy(() => import('./Pages/26NavDropdown'));
const ClickAndDragPage = lazy(() => import('./Pages/27ClickAndDrag'));
const SpeedControllerPage = lazy(() => import('./Pages/28SpeedController'));

export const routes = [
{ id: 0, path: '/', element: <HomePage /> },
{ id: 1, path: '01', element: <DrumPage /> },
Expand Down Expand Up @@ -57,4 +59,5 @@ export const routes = [
{ id: 25, path: '25', element: <EventPage /> },
{ id: 26, path: '26', element: <NavDropdownPage /> },
{ id: 27, path: '27', element: <ClickAndDragPage /> },
{ id: 28, path: '28', element: <SpeedControllerPage /> },
];

0 comments on commit b860a7f

Please sign in to comment.