File size: 3,953 Bytes
96dd062
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
---
import { Icon } from "astro-icon/components";

/****

 * FloatingButton 组件

 * 用于创建一个悬浮按钮,支持图标、点击事件和可选的辅助标签。

 */

interface Props {
	id: string;
	icon: string;
	ariaLabel?: string;
	onclick?: string;
	class?: string;
}

const { id, icon, ariaLabel, onclick, class: className = "" } = Astro.props;
---

<div
  id={id}
  class:list={["floating-btn", className, "flex items-center rounded-2xl overflow-hidden transition"]}
  onclick={onclick}
>
  <button
    aria-label={ariaLabel}
    class="h-full w-full rounded-2xl"
  >
    <Icon name={icon} class="mx-auto" />
  </button>
</div>

<style lang="stylus">
.floating-btn
    color: var(--primary)
    font-size: 2.25rem
    font-weight: bold
    width: 4rem
    height: 4rem
    
    opacity: 1
    cursor: pointer
    pointer-events: auto
    /* 默认状态(显示):各属性平滑过渡 */
    transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1)
    border-radius: 1rem
    backdrop-filter: blur(12px)
    background-color: var(--card-bg)
    border: 1px solid rgba(0, 0, 0, 0.1)
    flex-shrink: 0
    overflow: hidden
    
    /* 图标样式 */
    :global(svg)
        font-size: 1.75rem
        opacity: 1
        transition: opacity 0.2s ease 0.1s /* 显示时:延迟出现,通过 delay 避免"先出现icon" */

    &.hide
        /* 隐藏状态:缩小并收起布局 */
        transform: scale(0.5)
        opacity: 0
        pointer-events: none
        
        /* 强制收缩布局占用 */
        height: 0 !important
        width: 0 !important
        margin: 0 !important
        border-width: 0 !important
        padding: 0 !important
        
        /* 隐藏时:不需要 delay,与布局同时(或稍快)消失 */
        /* 由于 width/height 也在变,all cover全部。关键是 inner element 必须快 */
        
        :global(svg)
            opacity: 0
            transition: opacity 0.1s ease /* 隐藏时:立即消失,解决"icon最后消失" */
        
    &:active
        transform: scale(0.9)
        
    &:hover
        transform: scale(1.05)
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15)
        background-color: rgba(255, 255, 255, 0.95)
        border-color: rgba(0, 0, 0, 0.2)

/* 暗色主题样式 */
:global(.dark) .floating-btn
    background-color: var(--card-bg)
    border: 1px solid rgba(255, 255, 255, 0.15)
    color: var(--primary, #60a5fa)
    
    &:hover
        background-color: var(--card-bg)
        border-color: rgba(255, 255, 255, 0.3)
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3)

/* 响应式调整 */
@media (max-width: 768px)
    .floating-btn
        width: 3rem
        height: 3rem
        font-size: 1.5rem
        border-radius: 0.75rem
        :global(svg)
            font-size: 1.25rem

@media (max-width: 480px)
    .floating-btn
        width: 2.5rem
        height: 2.5rem
        font-size: 1.25rem
        border-radius: 0.5rem
        :global(svg)
            font-size: 1rem

@media (max-width: 360px)
    .floating-btn
        width: 2rem
        height: 2rem
        font-size: 1rem
        border-radius: 0.375rem
        :global(svg)
            font-size: 0.875rem

@media (max-width: 320px)
    .floating-btn
        width: 1.75rem
        height: 1.75rem
        font-size: 0.875rem
        border-radius: 0.25rem
        :global(svg)
            font-size: 0.75rem

/* 确保按钮始终在可视区域内 */
.floating-btn
    min-width: 0
    min-height: 0
    padding: 0.25rem
    border-radius: 1rem !important
    
    &.hide
        padding: 0

/* 高DPI屏幕优化 */
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)
    .floating-btn
        image-rendering: -webkit-optimize-contrast
        image-rendering: crisp-edges
</style>