Initial Commit
This commit is contained in:
commit
1d71a02738
237 changed files with 64293 additions and 0 deletions
534
components/voice-recorder/voice-recorder.wxss
Normal file
534
components/voice-recorder/voice-recorder.wxss
Normal file
|
|
@ -0,0 +1,534 @@
|
|||
/* 🎤 语音录制组件样式 */
|
||||
|
||||
/* CSS变量定义 */
|
||||
.voice-recorder-container {
|
||||
--primary-color: #007AFF;
|
||||
--primary-light: #5AC8FA;
|
||||
--primary-dark: #0051D5;
|
||||
--success-color: #34C759;
|
||||
--warning-color: #FF9500;
|
||||
--danger-color: #FF3B30;
|
||||
--background-color: #F2F2F7;
|
||||
--surface-color: #FFFFFF;
|
||||
--text-primary: #000000;
|
||||
--text-secondary: #8E8E93;
|
||||
--text-tertiary: #C7C7CC;
|
||||
--border-color: #E5E5EA;
|
||||
--shadow-light: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
|
||||
--shadow-medium: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
|
||||
--radius-small: 8rpx;
|
||||
--radius-medium: 12rpx;
|
||||
--radius-large: 20rpx;
|
||||
--radius-xl: 32rpx;
|
||||
}
|
||||
|
||||
/* 🌙 深色模式支持 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.voice-recorder-container {
|
||||
--primary-color: #0A84FF;
|
||||
--background-color: #000000;
|
||||
--surface-color: #1C1C1E;
|
||||
--text-primary: #FFFFFF;
|
||||
--text-secondary: #8E8E93;
|
||||
--text-tertiary: #48484A;
|
||||
--border-color: #38383A;
|
||||
--shadow-light: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
|
||||
--shadow-medium: 0 8rpx 24rpx rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
.voice-recorder-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.voice-recorder-container.visible {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.voice-recorder-container.hidden {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* 🎨 录音遮罩 */
|
||||
.recorder-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
backdrop-filter: blur(10rpx);
|
||||
}
|
||||
|
||||
/* 🎨 录音内容 */
|
||||
.recorder-content {
|
||||
width: 640rpx;
|
||||
max-width: 90vw;
|
||||
background: var(--surface-color);
|
||||
border-radius: var(--radius-xl);
|
||||
box-shadow: var(--shadow-medium);
|
||||
padding: 60rpx 40rpx 40rpx;
|
||||
position: relative;
|
||||
animation: slideUp 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(100rpx) scale(0.9);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 🎤 录音状态 */
|
||||
.recorder-status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 24rpx;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-icon.idle {
|
||||
background: var(--background-color);
|
||||
border: 2rpx solid var(--border-color);
|
||||
}
|
||||
|
||||
.status-icon.recording {
|
||||
background: linear-gradient(135deg, var(--danger-color) 0%, #FF6B6B 100%);
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
.status-icon.paused {
|
||||
background: var(--warning-color);
|
||||
}
|
||||
|
||||
.status-icon.completed {
|
||||
background: var(--success-color);
|
||||
}
|
||||
|
||||
.status-icon.error {
|
||||
background: var(--danger-color);
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { transform: scale(1); }
|
||||
50% { transform: scale(1.1); }
|
||||
}
|
||||
|
||||
.icon-microphone {
|
||||
font-size: 48rpx;
|
||||
}
|
||||
|
||||
.icon-recording {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.recording-dot {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
border-radius: 12rpx;
|
||||
background: white;
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%, 50% { opacity: 1; }
|
||||
51%, 100% { opacity: 0.3; }
|
||||
}
|
||||
|
||||
.icon-paused,
|
||||
.icon-completed,
|
||||
.icon-error {
|
||||
font-size: 48rpx;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.status-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* ⏱️ 录音时长 */
|
||||
.recording-duration {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40rpx;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.duration-text {
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: var(--primary-color);
|
||||
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
||||
}
|
||||
|
||||
.max-duration-text {
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
|
||||
}
|
||||
|
||||
/* 🌊 实时波形 */
|
||||
.realtime-waveform {
|
||||
height: 120rpx;
|
||||
margin-bottom: 40rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.waveform-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 6rpx;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wave-bar {
|
||||
width: 8rpx;
|
||||
border-radius: 4rpx;
|
||||
transition: all 0.2s ease;
|
||||
min-height: 16rpx;
|
||||
}
|
||||
|
||||
.wave-bar.realtime {
|
||||
background: var(--primary-color);
|
||||
animation: waveAnimation 1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.wave-bar.preview {
|
||||
background: var(--text-tertiary);
|
||||
}
|
||||
|
||||
@keyframes waveAnimation {
|
||||
0%, 100% { transform: scaleY(0.5); }
|
||||
50% { transform: scaleY(1); }
|
||||
}
|
||||
|
||||
/* 📊 录音预览 */
|
||||
.recording-preview {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.preview-waveform {
|
||||
height: 80rpx;
|
||||
margin-bottom: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.preview-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.file-size,
|
||||
.quality-text {
|
||||
font-size: 24rpx;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 🎛️ 录音控制 */
|
||||
.recorder-controls {
|
||||
margin-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
height: 88rpx;
|
||||
border-radius: var(--radius-medium);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 16rpx;
|
||||
transition: all 0.3s ease;
|
||||
user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.control-button:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.control-button.primary {
|
||||
background: linear-gradient(135deg, var(--primary-color) 0%, var(--primary-light) 100%);
|
||||
color: white;
|
||||
box-shadow: var(--shadow-light);
|
||||
}
|
||||
|
||||
.control-button.secondary {
|
||||
background: var(--background-color);
|
||||
color: var(--text-primary);
|
||||
border: 1rpx solid var(--border-color);
|
||||
}
|
||||
|
||||
.control-button.danger {
|
||||
background: rgba(255, 59, 48, 0.1);
|
||||
color: var(--danger-color);
|
||||
border: 1rpx solid rgba(255, 59, 48, 0.3);
|
||||
}
|
||||
|
||||
.control-button:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.control-button.primary:active {
|
||||
background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary-color) 100%);
|
||||
}
|
||||
|
||||
.button-text {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 录音中的控制按钮 */
|
||||
.recording-controls,
|
||||
.paused-controls,
|
||||
.completed-controls {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.recording-controls .control-button,
|
||||
.paused-controls .control-button,
|
||||
.completed-controls .control-button {
|
||||
flex: 1;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 💡 录音提示 */
|
||||
.recorder-tips {
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.tip-text.error {
|
||||
color: var(--danger-color);
|
||||
}
|
||||
|
||||
/* ❌ 关闭按钮 */
|
||||
.close-button {
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
right: 20rpx;
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 30rpx;
|
||||
background: var(--background-color);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.close-button:active {
|
||||
background: var(--border-color);
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
.close-icon {
|
||||
font-size: 36rpx;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
/* 🔐 权限引导 */
|
||||
.permission-guide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: var(--radius-xl);
|
||||
}
|
||||
|
||||
.guide-content {
|
||||
background: var(--surface-color);
|
||||
border-radius: var(--radius-large);
|
||||
padding: 60rpx 40rpx 40rpx;
|
||||
margin: 40rpx;
|
||||
text-align: center;
|
||||
box-shadow: var(--shadow-medium);
|
||||
}
|
||||
|
||||
.guide-icon {
|
||||
font-size: 80rpx;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.guide-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 16rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.guide-desc {
|
||||
font-size: 28rpx;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1.4;
|
||||
margin-bottom: 40rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.guide-buttons {
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.guide-button {
|
||||
flex: 1;
|
||||
height: 80rpx;
|
||||
border-radius: var(--radius-medium);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.guide-button.primary {
|
||||
background: var(--primary-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.guide-button.secondary {
|
||||
background: var(--background-color);
|
||||
color: var(--text-primary);
|
||||
border: 1rpx solid var(--border-color);
|
||||
}
|
||||
|
||||
.guide-button:active {
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
/* 📱 响应式设计 */
|
||||
@media screen and (max-width: 375px) {
|
||||
.recorder-content {
|
||||
width: 560rpx;
|
||||
padding: 50rpx 30rpx 30rpx;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.duration-text {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.realtime-waveform {
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
height: 76rpx;
|
||||
}
|
||||
|
||||
.button-text {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 414px) {
|
||||
.recorder-content {
|
||||
width: 720rpx;
|
||||
padding: 70rpx 50rpx 50rpx;
|
||||
}
|
||||
|
||||
.status-icon {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.duration-text {
|
||||
font-size: 56rpx;
|
||||
}
|
||||
|
||||
.realtime-waveform {
|
||||
height: 140rpx;
|
||||
}
|
||||
|
||||
.control-button {
|
||||
height: 96rpx;
|
||||
}
|
||||
|
||||
.button-text {
|
||||
font-size: 36rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 🎭 动画增强 */
|
||||
.voice-recorder-container.visible .recorder-content {
|
||||
animation: slideUp 0.3s ease-out;
|
||||
}
|
||||
|
||||
.voice-recorder-container.hidden .recorder-content {
|
||||
animation: slideDown 0.3s ease-in;
|
||||
}
|
||||
|
||||
@keyframes slideDown {
|
||||
from {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
}
|
||||
to {
|
||||
opacity: 0;
|
||||
transform: translateY(100rpx) scale(0.9);
|
||||
}
|
||||
}
|
||||
|
||||
/* 触摸反馈 */
|
||||
.control-button {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
/* 可访问性 */
|
||||
.control-button[aria-pressed="true"] {
|
||||
outline: 2rpx solid var(--primary-color);
|
||||
outline-offset: 4rpx;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue