change
This commit is contained in:
parent
47d9efd677
commit
56a9c28ec1
|
@ -13,7 +13,6 @@ import CustomWallpaper from './CustomWallpaper'
|
|||
|
||||
addIcons(BiChevronLeft, BiChevronDown)
|
||||
|
||||
|
||||
const wallpaperAttrList = ['动态壁纸', '静态壁纸', '自定义壁纸']
|
||||
export type BackgroundType = {
|
||||
id: string
|
||||
|
@ -51,11 +50,12 @@ export default defineComponent(() => {
|
|||
(e) => {
|
||||
if (!e[0]) return
|
||||
wallpaperList.value = []
|
||||
request<WallpaperItem[]>('GET', `/api/app/backgrounds?typeId=${e[0]}&sort=${sortBy.value}`).then(
|
||||
(res) => {
|
||||
wallpaperList.value = res
|
||||
}
|
||||
)
|
||||
request<WallpaperItem[]>(
|
||||
'GET',
|
||||
`/api/app/backgrounds?typeId=${e[0]}&sort=${sortBy.value}`
|
||||
).then((res) => {
|
||||
wallpaperList.value = res
|
||||
})
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
|
@ -166,10 +166,6 @@ export default defineComponent(() => {
|
|||
<div
|
||||
onClick={() => {
|
||||
layout.changeBackground(item.url)
|
||||
background.bgTrriger = false
|
||||
setTimeout(() => {
|
||||
background.bgTrriger = true
|
||||
}, 0)
|
||||
}}
|
||||
class="h-[156px] relative cursor-pointer group w-full flex-grow-0 rounded-xl overflow-hidden"
|
||||
>
|
||||
|
@ -201,7 +197,6 @@ export default defineComponent(() => {
|
|||
<div
|
||||
key={index}
|
||||
onClick={() => {
|
||||
|
||||
if (index === 2) {
|
||||
if (!userStore.isLogin) {
|
||||
router.go('global-login')
|
||||
|
|
|
@ -1,31 +1,103 @@
|
|||
import { defineComponent, Transition } from 'vue'
|
||||
import { defineComponent, nextTick, reactive, ref, Transition, watch } from 'vue'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import useSettingsStore from '@/settings/useSettingsStore'
|
||||
import useBackgroundStore from './useBackgroundStore'
|
||||
|
||||
const BgContent = defineComponent({
|
||||
props: {
|
||||
image: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
video: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: ''
|
||||
},
|
||||
zIndex: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
return () => (
|
||||
<div
|
||||
class="absolute left-0 top-0 w-full h-full"
|
||||
style={{
|
||||
zIndex: props.zIndex
|
||||
}}
|
||||
>
|
||||
{props.video ? (
|
||||
<video src={props.video} class="w-full h-full" muted />
|
||||
) : (
|
||||
<div
|
||||
class="w-full h-full bg-center bg-cover bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url('${props.image}')`
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BackgroundPage',
|
||||
setup() {
|
||||
const layout = useLayoutStore()
|
||||
const background = useBackgroundStore()
|
||||
const settings = useSettingsStore()
|
||||
const animate = ref(false)
|
||||
const pair = reactive<{
|
||||
front: typeof layout.background | null
|
||||
back: typeof layout.background | null
|
||||
}>({ front: { ...layout.background }, back: null })
|
||||
let first = false
|
||||
watch(layout.background, (val) => {
|
||||
if (!first) {
|
||||
first = true
|
||||
pair.front = { ...val } as any
|
||||
pair.back = null
|
||||
return
|
||||
}
|
||||
animate.value = true
|
||||
|
||||
nextTick(() => {
|
||||
// 让前面的消失,后面的显式
|
||||
pair.front = null
|
||||
pair.back = { ...val }
|
||||
})
|
||||
})
|
||||
watch(
|
||||
() => pair.front,
|
||||
(val) => {
|
||||
if (val === null) {
|
||||
setTimeout(() => {
|
||||
animate.value = false
|
||||
nextTick(() => {
|
||||
pair.front = { ...pair.back } as any
|
||||
pair.back = null
|
||||
})
|
||||
}, 600)
|
||||
}
|
||||
}
|
||||
)
|
||||
watch(pair, console.log)
|
||||
return () => (
|
||||
<div class="absolute left-0 top-0 w-full h-screen z-0">
|
||||
<Transition name="background">
|
||||
{background.bgTrriger && (
|
||||
<>
|
||||
{layout.background.video ? (
|
||||
<video src={layout.background.video} class="w-full h-full" />
|
||||
) : (
|
||||
<div
|
||||
class="w-full h-full bg-center bg-cover bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url('${layout.background.image}')`
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
</>
|
||||
<Transition name={animate.value ? 'background' : ''}>
|
||||
{pair.front ? (
|
||||
<div class="absolute left-0 top-0 w-full h-full">
|
||||
<BgContent image={pair.front.image} video={pair.front.video} zIndex={1} />
|
||||
</div>
|
||||
) : null}
|
||||
</Transition>
|
||||
<Transition name={animate.value ? 'background' : ''}>
|
||||
{pair.back && (
|
||||
<div class="absolute left-0 top-0 w-full h-full">
|
||||
<BgContent image={pair.back.image} video={pair.back.video} zIndex={0} />
|
||||
</div>
|
||||
)}
|
||||
</Transition>
|
||||
<div
|
||||
|
@ -35,9 +107,7 @@ export default defineComponent({
|
|||
backgroundColor: `rgba(0,0,0,${settings.state.maskOpacity})`,
|
||||
backdropFilter: `blur(${settings.state.maskFilter}px)`
|
||||
}}
|
||||
>
|
||||
|
||||
</div>
|
||||
></div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,6 @@ import { reactive, ref, watch } from 'vue'
|
|||
|
||||
export default defineStore('background', () => {
|
||||
const tag = ref(localStorage.getItem('backgroundTag') || '')
|
||||
const bgTrriger = ref(true)
|
||||
const resource = reactive({
|
||||
type: 'image',
|
||||
brief: '',
|
||||
|
@ -30,7 +29,6 @@ export default defineStore('background', () => {
|
|||
)
|
||||
return {
|
||||
tag,
|
||||
resource,
|
||||
bgTrriger
|
||||
resource
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
import { computed, defineComponent, onMounted, ref, Transition, watch } from 'vue'
|
||||
import returnImg from "~/icons/work/return.png"
|
||||
import endImg from "~/icons/work/tomotoIconEnd.png"
|
||||
import playWaveGif from "~/icons/work/playMusicIcon.gif"
|
||||
import PlayStartImg from "~/icons/work/start.png"
|
||||
import musicIcon from "~/icons/work/musicIcon.png"
|
||||
import useBackgroundStore from '../background/useBackgroundStore'
|
||||
import useLayoutStore from '../useLayoutStore'
|
||||
import { defineComponent, onMounted, ref, Transition } from 'vue'
|
||||
import returnImg from '~/icons/work/return.png'
|
||||
import endImg from '~/icons/work/tomotoIconEnd.png'
|
||||
import playWaveGif from '~/icons/work/playMusicIcon.gif'
|
||||
import PlayStartImg from '~/icons/work/start.png'
|
||||
import musicIcon from '~/icons/work/musicIcon.png'
|
||||
import useTomatoStore, { musicList } from '@/widgets/work/useTomatoStore'
|
||||
import Search from '../header/search'
|
||||
import { Modal, Tooltip } from 'ant-design-vue'
|
||||
import { formatSeconds } from '@/utils/tool'
|
||||
import clsx from 'clsx'
|
||||
import Background from '../background'
|
||||
export const DefaultPageSetting = [
|
||||
{
|
||||
name: '游戏',
|
||||
|
@ -38,8 +37,6 @@ export const DefaultPageSetting = [
|
|||
}
|
||||
]
|
||||
export default defineComponent(() => {
|
||||
const background = useBackgroundStore()
|
||||
const layout = useLayoutStore()
|
||||
const store = useTomatoStore()
|
||||
const isFirst = ref(false)
|
||||
const showSelectModal = ref(false)
|
||||
|
@ -57,129 +54,135 @@ export default defineComponent(() => {
|
|||
return () =>
|
||||
store.openFullscreen && (
|
||||
<div class="fixed left-0 top-0 z-50 w-full ">
|
||||
|
||||
<Transition name="background">
|
||||
{background.bgTrriger && (
|
||||
<>
|
||||
{layout.background.video ? (
|
||||
<video src={layout.background.video} class="w-full h-screen" />
|
||||
) : (
|
||||
<div
|
||||
class="w-full h-screen bg-center bg-cover bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url('${layout.background.image}')`
|
||||
}}
|
||||
></div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Transition>
|
||||
<Background />
|
||||
<div class="w-full h-screen" />
|
||||
<Transition name="modal">
|
||||
|
||||
<div class={"w-[500px] h-[500px] absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 "}>
|
||||
|
||||
<Modal open={showSelectModal.value} footer={null} class={'bg-white p-0 rounded-lg'}
|
||||
<div
|
||||
class={
|
||||
'w-[500px] h-[500px] absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 '
|
||||
}
|
||||
>
|
||||
<Modal
|
||||
open={showSelectModal.value}
|
||||
footer={null}
|
||||
class={'bg-white p-0 rounded-lg'}
|
||||
destroyOnClose
|
||||
centered
|
||||
onCancel={() => {
|
||||
showSelectModal.value = false
|
||||
}}>
|
||||
<div class={"flex flex-col items-center px-4"}>
|
||||
<span class={"text-[#333] font-bold text-[16px] mb-5"}>音乐选择</span>
|
||||
<div class={"flex flex-col w-full gap-y-1"}>
|
||||
{
|
||||
musicList.map((item, idx) => (
|
||||
<div
|
||||
onClick={() => {
|
||||
store.state.selectMusic = idx
|
||||
store.setTrack(idx)
|
||||
}}
|
||||
class={"bg-black/[0.05] cursor-pointer rounded-lg text-[#333] text-[14px] py-2 pl-10 border-[1px] relative border-transparent hover:border-[#5955FB]"}>
|
||||
{
|
||||
store.state.selectMusic === idx &&
|
||||
<img src={playWaveGif} class={" absolute left-2 top-1/2 -translate-y-1/2"}></img>
|
||||
|
||||
}
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div class={'flex flex-col items-center px-4'}>
|
||||
<span class={'text-[#333] font-bold text-[16px] mb-5'}>音乐选择</span>
|
||||
<div class={'flex flex-col w-full gap-y-1'}>
|
||||
{musicList.map((item, idx) => (
|
||||
<div
|
||||
onClick={() => {
|
||||
store.state.selectMusic = idx
|
||||
store.setTrack(idx)
|
||||
}}
|
||||
class={
|
||||
'bg-black/[0.05] cursor-pointer rounded-lg text-[#333] text-[14px] py-2 pl-10 border-[1px] relative border-transparent hover:border-[#5955FB]'
|
||||
}
|
||||
>
|
||||
{store.state.selectMusic === idx && (
|
||||
<img
|
||||
src={playWaveGif}
|
||||
class={' absolute left-2 top-1/2 -translate-y-1/2'}
|
||||
></img>
|
||||
)}
|
||||
<span>{item.name}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => {
|
||||
showSelectModal.value = false
|
||||
|
||||
}}
|
||||
class={"px-10 py-2 mt-7 font-bold text-[16px] text-white rounded-lg flex items-center justify-center cursor-pointer hover:opacity-90 duration-150"} style={{
|
||||
class={
|
||||
'px-10 py-2 mt-7 font-bold text-[16px] text-white rounded-lg flex items-center justify-center cursor-pointer hover:opacity-90 duration-150'
|
||||
}
|
||||
style={{
|
||||
background: 'linear-gradient(225deg,#642FFF 0%,#5162FF 100%)',
|
||||
boxShadow: '0 2px 6px #00000026'
|
||||
}}>确定</button>
|
||||
}}
|
||||
>
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</Modal>
|
||||
<div class={"w-full h-full absolute z-0 rotate-90"}>
|
||||
{
|
||||
Array.from({ length: 60 }).map((_, idx) => (
|
||||
<div class={clsx(" w-[30px] h-[5px] absolute mt-[-2.5px] top-1/2",
|
||||
(((60 * 15 - store.remainingTime) / 15) >= idx) ? "bg-white" : "bg-white/50"
|
||||
)} style={{
|
||||
<div class={'w-full h-full absolute z-0 rotate-90'}>
|
||||
{Array.from({ length: 60 }).map((_, idx) => (
|
||||
<div
|
||||
class={clsx(
|
||||
' w-[30px] h-[5px] absolute mt-[-2.5px] top-1/2',
|
||||
(60 * 15 - store.remainingTime) / 15 >= idx ? 'bg-white' : 'bg-white/50'
|
||||
)}
|
||||
style={{
|
||||
transformOrigin: '250px',
|
||||
borderRadius: '3px',
|
||||
transform: `rotateZ(${idx * 6}deg)`
|
||||
|
||||
}}>
|
||||
|
||||
</div>
|
||||
))
|
||||
}
|
||||
}}
|
||||
></div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div class={"w-[500px] flex justify-center flex-col items-center gap-y-3 h-full text-white "}>
|
||||
<span class={"text-[24px] leading-[36px]"}>专注中</span>
|
||||
<span class={"font-din text-[82px] font-bold leading-[115px]"}>{!store.state.isStart ? '15:00' : formatSeconds(store.remainingTime)}</span>
|
||||
<div class={"relative"}>
|
||||
<div class={"aboslute w-[370px] z-10"}>
|
||||
<div
|
||||
class={
|
||||
'w-[500px] flex justify-center flex-col items-center gap-y-3 h-full text-white '
|
||||
}
|
||||
>
|
||||
<span class={'text-[24px] leading-[36px]'}>专注中</span>
|
||||
<span class={'font-din text-[82px] font-bold leading-[115px]'}>
|
||||
{!store.state.isStart ? '15:00' : formatSeconds(store.remainingTime)}
|
||||
</span>
|
||||
<div class={'relative'}>
|
||||
<div class={'aboslute w-[370px] z-10'}>
|
||||
<Search isMini></Search>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class={"w-full flex gap-x-4 justify-center z-[1] mt-5"}>
|
||||
<Tooltip title={"返回工作模式"}>
|
||||
<div class={'w-full flex gap-x-4 justify-center z-[1] mt-5'}>
|
||||
<Tooltip title={'返回工作模式'}>
|
||||
<div
|
||||
onClick={() => {
|
||||
store.openFullscreen = false
|
||||
}}
|
||||
class={"w-[44px] h-[44px] flex items-center justify-center rounded-lg cursor-pointer hover:opacity-90"}
|
||||
class={
|
||||
'w-[44px] h-[44px] flex items-center justify-center rounded-lg cursor-pointer hover:opacity-90'
|
||||
}
|
||||
style={{
|
||||
background: 'linear-gradient(225deg,#707eff 0%,#6b97ff 100%)',
|
||||
boxShadow: '0 2px 4px #0003'
|
||||
}}>
|
||||
<img src={returnImg} alt='return' class={"w-[18px] h-[18px]"}></img>
|
||||
}}
|
||||
>
|
||||
<img src={returnImg} alt="return" class={'w-[18px] h-[18px]'}></img>
|
||||
</div>
|
||||
</Tooltip>
|
||||
<Tooltip title={store.state.isStart ? "停止" : '开始'}>
|
||||
<Tooltip title={store.state.isStart ? '停止' : '开始'}>
|
||||
<div
|
||||
onClick={() => {
|
||||
store.state.isStart ?
|
||||
store.stopTomatoTime() :
|
||||
store.beginTomatoTime()
|
||||
|
||||
store.state.isStart ? store.stopTomatoTime() : store.beginTomatoTime()
|
||||
}}
|
||||
class={"w-[44px] h-[44px] flex items-center justify-center rounded-lg cursor-pointer hover:opacity-90"}
|
||||
class={
|
||||
'w-[44px] h-[44px] flex items-center justify-center rounded-lg cursor-pointer hover:opacity-90'
|
||||
}
|
||||
style={{
|
||||
background: 'linear-gradient(225deg,#707eff 0%,#6b97ff 100%)',
|
||||
boxShadow: '0 2px 4px #0003'
|
||||
}}>
|
||||
{
|
||||
store.state.isStart ?
|
||||
<img src={endImg} alt='return' class={"w-[18px] h-[18px]"}></img>
|
||||
:
|
||||
<img src={PlayStartImg} alt="start" class={"w-[18px] h-[18px]"} />
|
||||
|
||||
}
|
||||
}}
|
||||
>
|
||||
{store.state.isStart ? (
|
||||
<img src={endImg} alt="return" class={'w-[18px] h-[18px]'}></img>
|
||||
) : (
|
||||
<img src={PlayStartImg} alt="start" class={'w-[18px] h-[18px]'} />
|
||||
)}
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<div class={"w-[140px] h-[44px] relative bg-[#f0f0f0] rounded-lg flex px-3 gap-x-2 items-center justify-between cursor-pointer hover:opacity-90"}
|
||||
<div
|
||||
class={
|
||||
'w-[140px] h-[44px] relative bg-[#f0f0f0] rounded-lg flex px-3 gap-x-2 items-center justify-between cursor-pointer hover:opacity-90'
|
||||
}
|
||||
style={{
|
||||
boxShadow: '0 2px 4px #0003'
|
||||
}}
|
||||
|
@ -187,33 +190,33 @@ export default defineComponent(() => {
|
|||
showSelectModal.value = true
|
||||
}}
|
||||
>
|
||||
|
||||
{
|
||||
store.state.isPlaying ?
|
||||
<img src={playWaveGif} alt='return' class={"w-[18px] h-[18px] "}></img>
|
||||
:
|
||||
<img src={musicIcon} alt='return' class={"w-[18px] h-[18px] "}></img>
|
||||
}
|
||||
<span class={"whitespace-nowrap text-ellipsis overflow-hidden text-[#333]"}>{musicList[store.state.selectMusic].name}</span>
|
||||
{store.state.isPlaying ? (
|
||||
<img src={playWaveGif} alt="return" class={'w-[18px] h-[18px] '}></img>
|
||||
) : (
|
||||
<img src={musicIcon} alt="return" class={'w-[18px] h-[18px] '}></img>
|
||||
)}
|
||||
<span class={'whitespace-nowrap text-ellipsis overflow-hidden text-[#333]'}>
|
||||
{musicList[store.state.selectMusic].name}
|
||||
</span>
|
||||
<div
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
store.togglePlay()
|
||||
}}
|
||||
class={"w-[26px] h-[26px] right-[-14px] rounded-full bg-[#c0c0c0] absolute flex items-center justify-center"}>
|
||||
{
|
||||
store.state.isPlaying ?
|
||||
<img src={endImg} alt='start ' class={"w-[12px] h-[12px]"}></img>
|
||||
:
|
||||
<img src={PlayStartImg} alt='start ' class={"w-[12px] h-[12px]"}></img>
|
||||
|
||||
class={
|
||||
'w-[26px] h-[26px] right-[-14px] rounded-full bg-[#c0c0c0] absolute flex items-center justify-center'
|
||||
}
|
||||
>
|
||||
{store.state.isPlaying ? (
|
||||
<img src={endImg} alt="start " class={'w-[12px] h-[12px]'}></img>
|
||||
) : (
|
||||
<img src={PlayStartImg} alt="start " class={'w-[12px] h-[12px]'}></img>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Transition>
|
||||
</div>
|
||||
)
|
||||
|
|
26
src/main.css
26
src/main.css
|
@ -262,18 +262,20 @@ body {
|
|||
}
|
||||
}
|
||||
|
||||
.background-enter-active {
|
||||
animation: bounce-in 0.8s;
|
||||
.background-enter-active,
|
||||
.background-leave-active {
|
||||
transform: scale(1);
|
||||
opacity: 1;
|
||||
transition:
|
||||
transform 0.6s cubic-bezier(0.47, 1.64, 0.41, 0.8),
|
||||
opacity 0.6s ease-out;
|
||||
}
|
||||
|
||||
@keyframes bounce-in {
|
||||
0% {
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
.background-enter-from {
|
||||
transform: scale(1.25);
|
||||
opacity: 0;
|
||||
}
|
||||
.background-leave-to {
|
||||
transform: scale(1);
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue