speakeloudest 96dbe0c108
All checks were successful
site-dist-deploy / build-and-deploy (push) Successful in 1m8s
桌面端样式
2026-01-04 22:52:06 -08:00

291 lines
8.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="font-sans text-white">
<div class="flex flex-col gap-[10px]">
<div
v-for="item in downloadMethods"
:key="item.id"
@click="toggle(item.id)"
class="group relative flex flex-col rounded-[30px] border-[4px] border-white bg-black pt-4 pb-2 transition-all md:pb-6"
>
<div class="px-4 md:pl-[42px]">
<div
class="flex flex-wrap items-center gap-x-2 text-sm leading-tight font-bold md:text-2xl"
>
<StartIcon v-if="item.isHot" class="size-[20px] md:size-[30px]" />
<span>{{ item.title }}</span>
<span v-if="item.subtitle" class="font-medium">{{ item.subtitle }}</span>
<span v-if="item.highlight" class="font-black text-[#FF00FF]"
>{{ item.highlight }}</span
>
</div>
<!-- 打开按钮 -->
<div
class="flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100"
>
<div
v-show="activeId !== item.id"
class="mt-[16px] flex items-center gap-[10px] md:mt-[60px] md:text-xl"
>
<span class="tracking-tight">点击展开详情</span>
<ArrowIcon class="size-[12px] md:size-[18px]" />
</div>
</div>
</div>
<div v-if="activeId === item.id" class="px-2 md:pt-8">
<div
class="animate-in fade-in zoom-in-95 border-t-2 border-white pt-[10px] text-[15px] leading-relaxed duration-200 md:pt-[20px]"
>
<!-- 内容区域 (点击图片不收起只有特定的关闭按钮收起) -->
<div class="relative px-2" @click.stop>
<div
class="flex items-center justify-end gap-1.5 self-end text-sm font-bold group-hover:opacity-100 md:text-xl"
>
<div class="relative z-10 flex items-center gap-[10px]" @click="toggle(item.id)">
<span class="tracking-tight">点击收起</span>
<ArrowIcon class="size-[12px] rotate-180 md:size-[22px]" />
</div>
</div>
<!-- Mobile Image Stack -->
<div class="relative -mt-10 flex flex-col md:hidden">
<img
v-for="(img, idx) in item.mobileImages"
:key="idx"
:src="img"
class="w-full"
alt="mobile guide"
/>
<!-- Mobile Hot Zones -->
<div
v-for="(hz, hzIdx) in item.mobileHotzones"
:key="hzIdx"
class="absolute z-20 cursor-pointer"
:style="{
left: hz.x + 'px',
top: hz.y + 'px',
width: hz.w + 'px',
height: hz.h + 'px',
}"
@click="handleHotzone(hz)"
></div>
</div>
<!-- PC Image Stack -->
<div class="relative mt-4 hidden flex-col md:flex">
<img
v-for="(img, idx) in item.pcImages"
:key="idx"
:src="img"
class="w-full"
alt="pc guide"
/>
<!-- PC Hot Zones -->
<div
v-for="(hz, hzIdx) in item.pcHotzones"
:key="hzIdx"
class="absolute z-20 cursor-pointer"
:style="{
left: hz.x + 'px',
top: hz.y + 'px',
width: hz.w + 'px',
height: hz.h + 'px',
}"
@click="handleHotzone(hz)"
>
<span class="text-xs font-bold text-black" v-if="hz.type === 'text'">{{
hz.payload
}}</span>
</div>
</div>
<!-- 底部收起按钮 -->
<div class="absolute right-4 bottom-4 z-10">
<div @click="toggle(item.id)" class="h-[30px] w-[200px]"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import ArrowIcon from './arrow-icon.svg?component'
import StartIcon from './Star-1.svg?component'
import { toast } from 'vue-sonner'
// Sliced WebP Images
// Method 1
import m1_1 from './mobile1/row-1-column-1.webp'
import m1_2 from './mobile1/row-2-column-1.webp'
import m1_3 from './mobile1/row-3-column-1.webp'
import pc1_1 from './pc1/row-1-column-1.webp'
import pc1_2 from './pc1/row-2-column-1.webp'
import pc1_3 from './pc1/row-3-column-1.webp'
// Method 2
import m2_1 from './mobile2/row-1-column-1.webp'
import m2_2 from './mobile2/row-2-column-1.webp'
import m2_3 from './mobile2/row-3-column-1.webp'
import pc2_1 from './pc2/row-1-column-1.webp'
import pc2_2 from './pc2/row-2-column-1.webp'
import pc2_3 from './pc2/row-3-column-1.webp'
// Method 3
import m3_1 from './mobile3/row-1-column-1.webp'
import m3_2 from './mobile3/row-2-column-1.webp'
import m3_3 from './mobile3/row-3-column-1.webp'
import pc3_1 from './pc3/row-1-column-1.webp'
import pc3_2 from './pc3/row-2-column-1.webp'
import pc3_3 from './pc3/row-3-column-1.webp'
interface Hotzone {
x: number
y: number
w: number
h: number
type: 'copy' | 'link'
payload: string
label?: string
}
const accounts = [
{ account: 'prla08741@gmx.com', password: 'Qw990088' },
{ account: 'guazhexing721@gmx.com', password: 'Qw990088' },
]
const selectedIndex = ref(0) // 直接在内部定义数据
const downloadMethods = computed(() => {
const account = accounts[selectedIndex.value]
return [
{
id: 1,
title: '创建新“香港Apple ID”',
subtitle: '首推',
isHot: true,
highlight: '',
mobileImages: [m1_1, m1_2, m1_3],
pcImages: [pc1_1, pc1_2, pc1_3],
mobileHotzones: [] as Hotzone[],
pcHotzones: [
{
x: 410,
y: 224,
w: 140,
h: 20,
type: 'link',
payload: 'https://account.apple.com/account',
},
] as Hotzone[],
},
{
id: 2,
title: '修改已有 Apple ID 至 <香港>',
subtitle: '',
isHot: false,
highlight: '',
mobileImages: [m2_1, m2_2, m2_3],
pcImages: [pc2_1, pc2_2, pc2_3],
mobileHotzones: [] as Hotzone[],
pcHotzones: [
{
x: 410,
y: 224,
w: 140,
h: 20,
type: 'link',
payload: 'https://account.apple.com',
},
] as Hotzone[],
},
{
id: 3,
title: '使用Hi快提供的公用账号',
subtitle: '',
isHot: false,
highlight: '谨慎选择',
mobileImages: [m3_1, m3_2, m3_3],
pcImages: [pc3_1, pc3_2, pc3_3],
mobileHotzones: [] as Hotzone[],
pcHotzones: [
{
x: 103,
y: 1426,
w: 140,
h: 20,
type: 'text', // 展示账号文字
payload: account.account,
},
{
x: 103,
y: 1463,
w: 140,
h: 20,
type: 'text', // 展示密码文字
payload: account.password,
},
{
x: 103,
y: 1414,
w: 194,
h: 34,
type: 'copy',
payload: account.account,
label: '账号', // account
},
{
x: 103,
y: 1451,
w: 194,
h: 34,
type: 'copy',
payload: account.password,
label: '密码', // 复制提示
},
] as Hotzone[],
},
]
})
const activeId = ref<number | null>(null)
const toggle = (id: number) => {
if (activeId.value === id) {
activeId.value = null
} else {
activeId.value = id
// 重点:当点开 ID 为 3 的面板时,随机切换账号索引
if (id === 3) {
// 生成一个与当前不同的随机数,或者纯随机
selectedIndex.value = selectedIndex.value === 0 ? 1 : 0
}
}
}
const handleHotzone = (hz: Hotzone) => {
if (hz.type === 'copy') {
navigator.clipboard.writeText(hz.payload)
toast.success(`${hz.label || '内容'}已复制`)
} else if (hz.type === 'link') {
window.open(hz.payload, '_blank')
}
}
</script>
<style scoped>
/* 针对整体风格进行微调 */
.font-bold {
letter-spacing: -0.02em;
}
/* 移除移动端点击的高亮蓝色框 */
div {
-webkit-tap-highlight-color: transparent;
}
</style>