feat: add component (AudioPlayer)

mack-mac
mackt 8 months ago
parent 3273f30025
commit 9d1102c1b3

@ -0,0 +1,4 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.8333 5.36009C19.8333 5.02405 19.8333 4.85604 19.8987 4.72769C19.9562 4.61479 20.048 4.52301 20.1609 4.46548C20.2893 4.40009 20.4573 4.40009 20.7933 4.40009H22.3733C22.7094 4.40009 22.8774 4.40009 23.0057 4.46548C23.1186 4.52301 23.2104 4.61479 23.2679 4.72769C23.3333 4.85604 23.3333 5.02405 23.3333 5.36009V22.6401C23.3333 22.9761 23.3333 23.1441 23.2679 23.2725C23.2104 23.3854 23.1186 23.4772 23.0057 23.5347C22.8774 23.6001 22.7094 23.6001 22.3733 23.6001H20.7933C20.4573 23.6001 20.2893 23.6001 20.1609 23.5347C20.048 23.4772 19.9562 23.3854 19.8987 23.2725C19.8333 23.1441 19.8333 22.9761 19.8333 22.6401V5.36009Z" fill="black" fill-opacity="0.95"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.2415 13.0134C17.9308 13.4906 17.9308 14.5095 17.2415 14.9867L5.38306 23.1964C4.58718 23.7474 3.50001 23.1778 3.50001 22.2098L3.50001 5.79034C3.50001 4.82235 4.58718 4.25272 5.38306 4.80371L17.2415 13.0134Z" fill="black" fill-opacity="0.95"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,4 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="4.70001" y="2.90002" width="4.5" height="16.2" rx="0.736" fill="white"/>
<rect x="12.8" y="2.90002" width="4.5" height="16.2" rx="0.736" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 264 B

@ -0,0 +1,4 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.5 2.625H18.6667C18.1834 2.625 17.7917 3.01675 17.7917 3.5C17.7917 3.98325 18.1834 4.375 18.6667 4.375H22.3876L2.88128 23.8813C2.53957 24.223 2.53957 24.777 2.88128 25.1187C3.22299 25.4604 3.77701 25.4604 4.11872 25.1187L23.625 5.61244V9.33333C23.625 9.81658 24.0168 10.2083 24.5 10.2083C24.9833 10.2083 25.375 9.81658 25.375 9.33333V3.5C25.375 3.26247 25.2804 3.04704 25.1267 2.88938C25.1215 2.88399 25.1161 2.87867 25.1108 2.87342C25.0287 2.79343 24.9349 2.73275 24.8349 2.69139C24.7318 2.64861 24.6186 2.625 24.5 2.625Z" fill="black" fill-opacity="0.7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M25.3076 24.8374C25.2659 24.9373 25.2048 25.0311 25.1244 25.113C25.1206 25.1168 25.1168 25.1206 25.113 25.1244C24.9466 25.2878 24.7312 25.3713 24.5146 25.3749C24.5092 25.375 24.5037 25.375 24.4983 25.375H18.6667C18.1834 25.375 17.7917 24.9832 17.7917 24.5C17.7917 24.0168 18.1834 23.625 18.6667 23.625H22.3876L16.8813 18.1187C16.5396 17.777 16.5396 17.223 16.8813 16.8813C17.223 16.5396 17.777 16.5396 18.1187 16.8813L23.625 22.3876V18.6667C23.625 18.1834 24.0168 17.7917 24.5 17.7917C24.9833 17.7917 25.375 18.1834 25.375 18.6667V24.5C25.375 24.6196 25.351 24.7336 25.3076 24.8374ZM11.1187 9.88128C11.4604 10.223 11.4604 10.777 11.1187 11.1187C10.777 11.4604 10.223 11.4604 9.88128 11.1187L2.88128 4.11872C2.53957 3.77701 2.53957 3.22299 2.88128 2.88128C3.22299 2.53957 3.77701 2.53957 4.11872 2.88128L11.1187 9.88128Z" fill="black" fill-opacity="0.7"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

@ -0,0 +1,4 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.5 11.6667H16.3333V3.50002" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M3.5 16.3333H11.6667V24.5" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 341 B

@ -1,7 +1,6 @@
import { Header, Footer } from '@/components'; import { Header, Footer, PlayerBar } from '@/components';
import type { Metadata, Viewport } from 'next'; import type { Metadata, Viewport } from 'next';
import './globals.css'; import './globals.css';
export const metadata: Metadata = { export const metadata: Metadata = {
@ -21,9 +20,12 @@ export const viewport: Viewport = {
export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) { export default function RootLayout({ children }: Readonly<{ children: React.ReactNode }>) {
return ( return (
<html lang="zn-ch" className="relative"> <html lang="zn-ch" className="relative">
<Header /> <body>
<body>{children}</body> <Header />
<Footer /> <div>{children}</div>
<Footer />
<PlayerBar />
</body>
</html> </html>
); );
} }

@ -1,24 +1,3 @@
import { useState, useEffect } from 'react';
import { TagCategory } from '@/components';
import { getTagName } from '@/store';
export default function Home() { export default function Home() {
return ( return <main></main>;
<main className="flex flex-row justify-between w-[1200px] mx-auto items-left pt-[80px] pb-[104px] ">
{/* 左侧 */}
<div className="w-[712px] mt-[50px]">
{/* category */}
<TagCategory category={'all'} />
{/* 期刊列表 */}
</div>
{/* 右侧 */}
<div className="w-[346px] mt-[217px]">
<p className="text-[17px] leading-[23.8px]"></p>
<div></div>
</div>
</main>
);
} }

@ -0,0 +1,75 @@
'use client';
import { useState } from 'react';
import Image from 'next/image';
export default function AudioPlayer({ className }: { className?: string }) {
const [curTime, setCurTime] = useState('00:00');
const [totalTime, setTotalTime] = useState('00:00');
return (
<div className={`flex flex-row w-[1200px] pt-[29px] ${className}`}>
{/* cover */}
<div className="w-[72px] h-[72px] rounded-[3px] bg-[#000]">
<Image src="/img/music.png" alt="music" width={72} height={72} unoptimized className="w-full h-full" />
</div>
{/* title & author */}
<div className="h-full ml-[27px] mr-[44px] py-[14px]">
{/* 改成滚动的 */}
<p className="w-[140px] text-[17px] leading-[23.8px] text-[rgba(0,0,0,0.95)] overflow-hidden whitespace-nowrap overflow-ellipsis truncate">
{'Ferrum Aeternum'}
</p>
{/* 改成滚动的 */}
<p className="w-[140px] text-[13px] leading-[18.2px] text-[rgba(0,0,0,0.7)] overflow-hidden whitespace-nowrap overflow-ellipsis truncate">
{'Ensiferum/mmmmsa'}
</p>
</div>
{/* progress bar */}
<div className="h-full mt-[29px]">
{/* bar */}
<div className="h-full cursor-pointer">
{/* black */}
<div className="w-[600px] h-[3px] bg-[rgba(0,0,0,1)]" />
{/* gery */}
<div className="w-[600px] h-[3px] mt-[-3px] bg-[rgba(0,0,0,0.1)]" />
{/* point */}
<div className="w-[12px] h-[12px] mt-[-7px] rounded-[50%] bg-[#000]" />
</div>
{/* time */}
<p className="texe-[12px] leading[16.8px]">
<span>{curTime}</span>
<span className="text-[rgba(0,0,0,0.4)]">{` / ${totalTime}`}</span>
</p>
</div>
{/* control */}
<div className="flex flex-row items-center">
<button>
{/* 随机播放 */}
<Image
src={'/img/audio-player/random.svg'}
alt="random"
width={28}
height={28}
className="ml-[55px] mr-[60px]"
/>
</button>
{/* 上一首 */}
<button>
<Image src={'/img/audio-player/next.svg'} alt="pre" width={28} height={28} className="rotate-180" />
</button>
{/* 播放/暂停 */}
<button className="flex justify-center items-center w-[54px] h-[54px] mx-[35px] rounded-[50%] bg-[rgba(180,67,67,1)] overflow-hidden">
{/* <Image src={'/img/audio-player/play.svg'} alt="play" width={28} height={28} /> */}
<Image src={'/img/audio-player/pause.svg'} alt="pause" width={28} height={28} />
</button>
{/* 下一首 */}
<button>
<Image src={'/img/audio-player/next.svg'} alt="next" width={28} height={28} />
</button>
</div>
</div>
);
}

@ -0,0 +1,38 @@
'use client';
import { useEffect, useState } from 'react';
import Player from './Player';
export default function PlayerBar({ className }: { className?: string }) {
let oldScrollY: number = 0;
function handleScroll() {
if (window.scrollY > oldScrollY) {
// 向下滚动
// if (oldScrollY < 0) return;
setPositionBottom(-130);
} else {
// 向上滚动
// if (oldScrollY > 0) return;
setPositionBottom(0);
}
oldScrollY = window.scrollY;
}
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
};
});
const [positionBottom, setPositionBottom] = useState<number>(0);
return (
<div
className={`fixed w-full h-[130px] bg-[#fff] ${className} transition-bottom duration-700`}
style={{ bottom: positionBottom }}
>
<Player className="m-auto" />
</div>
);
}

@ -19,3 +19,7 @@ export { default as HotJournalList } from './Journal/HotJournalList';
// Common // Common
export { default as Input } from './common/Input'; export { default as Input } from './common/Input';
export { default as Button } from './common/Button'; export { default as Button } from './common/Button';
// Audio Player
export { default as PlayerBar } from './AudioPlayer/PlayerBar';
export { default as AudioPlayer } from './AudioPlayer/Player';

Loading…
Cancel
Save