统一排行榜对齐星雀UI,页面资源后台配置实时刷新
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
324
miniprogram/components/popup-notice/popup-notice.js
Normal file
324
miniprogram/components/popup-notice/popup-notice.js
Normal file
@@ -0,0 +1,324 @@
|
||||
// components/popup-notice/popup-notice.js
|
||||
import PopupService from '../../services/popupService.js';
|
||||
|
||||
Component({
|
||||
data: {
|
||||
// 原有全屏弹窗数据
|
||||
visible: false,
|
||||
title: '',
|
||||
images: [],
|
||||
processedImages: [],
|
||||
hasImages: false,
|
||||
hasTextOnly: false,
|
||||
textContent: '',
|
||||
duration: 0,
|
||||
remainingSeconds: 0,
|
||||
muteChecked: false,
|
||||
showMuteCheckbox: false,
|
||||
isFullscreen: false,
|
||||
timer: null,
|
||||
|
||||
// 悬浮窗相关数据
|
||||
isMinimized: false,
|
||||
floatX: 20,
|
||||
floatY: 200,
|
||||
savedRemainingSeconds: 0,
|
||||
floatAvatarUrl: '',
|
||||
|
||||
// 🆕 自定义预览数据
|
||||
showCustomPreview: false, // 是否显示自定义预览遮罩
|
||||
previewUrls: [], // 当前预览的图片URL列表
|
||||
currentPreviewIndex: 0, // 当前预览图片索引
|
||||
},
|
||||
|
||||
lifetimes: {
|
||||
detached() {
|
||||
this.clearTimer();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// ========== 原有所有方法(完全不变,一字不漏) ==========
|
||||
async show(config, onCloseCallback) {
|
||||
const { title, images, duration, showMuteCheckbox, serverTime } = config;
|
||||
this.onCloseCallback = onCloseCallback;
|
||||
|
||||
let safeImages = JSON.parse(JSON.stringify(images || []));
|
||||
const hasImages = safeImages.length > 0;
|
||||
let hasTextOnly = false, textContent = '';
|
||||
if (!hasImages) {
|
||||
hasTextOnly = true;
|
||||
textContent = config.text || '暂无内容';
|
||||
}
|
||||
|
||||
this.setData({
|
||||
visible: true,
|
||||
isMinimized: false,
|
||||
title: title || '',
|
||||
images: safeImages,
|
||||
hasImages,
|
||||
hasTextOnly,
|
||||
textContent,
|
||||
duration: duration || 0,
|
||||
remainingSeconds: duration || 0,
|
||||
muteChecked: false,
|
||||
showMuteCheckbox: showMuteCheckbox || false,
|
||||
isFullscreen: false,
|
||||
processedImages: [],
|
||||
});
|
||||
|
||||
if (duration > 0) {
|
||||
this.startCountdown();
|
||||
}
|
||||
|
||||
if (hasImages) {
|
||||
const processed = [];
|
||||
const screenWidth = wx.getSystemInfoSync().windowWidth;
|
||||
const containerWidth = screenWidth * 0.9;
|
||||
const imageWidth = containerWidth - 60;
|
||||
for (let i = 0; i < safeImages.length; i++) {
|
||||
const img = safeImages[i];
|
||||
const fullUrl = this.getFullImageUrl(img.url);
|
||||
let imageHeight = 200;
|
||||
try {
|
||||
const res = await this.getImageInfoPromise(fullUrl);
|
||||
const realHeight = (imageWidth * res.height) / res.width;
|
||||
imageHeight = realHeight;
|
||||
} catch (e) {
|
||||
console.error('获取图片信息失败', fullUrl, e);
|
||||
}
|
||||
processed.push({
|
||||
url: fullUrl,
|
||||
text: img.text,
|
||||
height: imageHeight,
|
||||
});
|
||||
}
|
||||
this.setData({ processedImages: processed });
|
||||
}
|
||||
},
|
||||
|
||||
getImageInfoPromise(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
wx.getImageInfo({
|
||||
src: url,
|
||||
success: resolve,
|
||||
fail: reject,
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
hide(muteToday = false) {
|
||||
this.clearTimer();
|
||||
this.setData({
|
||||
visible: false,
|
||||
isMinimized: false
|
||||
});
|
||||
if (this.onCloseCallback) {
|
||||
this.onCloseCallback({ muteToday });
|
||||
}
|
||||
},
|
||||
|
||||
startCountdown() {
|
||||
this.clearTimer();
|
||||
this.timer = setInterval(() => {
|
||||
let sec = this.data.remainingSeconds;
|
||||
if (sec <= 1) {
|
||||
this.clearTimer();
|
||||
this.setData({ remainingSeconds: 0 });
|
||||
} else {
|
||||
this.setData({ remainingSeconds: sec - 1 });
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
clearTimer() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
},
|
||||
|
||||
onCloseTap() {
|
||||
if (this.data.remainingSeconds > 0) {
|
||||
wx.showToast({
|
||||
title: `请阅读${this.data.remainingSeconds}秒后再关闭`,
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (this.data.showMuteCheckbox && this.data.muteChecked) {
|
||||
wx.showModal({
|
||||
title: '提示',
|
||||
content: '今天将不再收到本页面的任何公告,确认吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) this.hide(true);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this.hide(false);
|
||||
}
|
||||
},
|
||||
|
||||
onMuteChange(e) {
|
||||
this.setData({ muteChecked: e.detail.value.length > 0 });
|
||||
},
|
||||
|
||||
// 🆕 替换原有的 onPreviewImage,改用自定义预览(不触发 onShow)
|
||||
onCustomPreview(e) {
|
||||
const index = e.currentTarget.dataset.index;
|
||||
const urls = this.data.processedImages.map(img => img.url);
|
||||
this.setData({
|
||||
showCustomPreview: true,
|
||||
previewUrls: urls,
|
||||
currentPreviewIndex: index !== undefined ? index : 0
|
||||
});
|
||||
},
|
||||
|
||||
// 🆕 关闭自定义预览
|
||||
onCloseCustomPreview() {
|
||||
this.setData({
|
||||
showCustomPreview: false,
|
||||
previewUrls: [],
|
||||
currentPreviewIndex: 0
|
||||
});
|
||||
},
|
||||
|
||||
// 🆕 swiper 切换事件
|
||||
onPreviewSwiperChange(e) {
|
||||
this.setData({
|
||||
currentPreviewIndex: e.detail.current
|
||||
});
|
||||
},
|
||||
|
||||
// 保留原 onPreviewImage 方法以防外部调用,但不再使用
|
||||
onPreviewImage(e) {
|
||||
// 重定向到自定义预览
|
||||
this.onCustomPreview(e);
|
||||
},
|
||||
|
||||
onImageError(e) {
|
||||
console.error('图片加载失败:', e.currentTarget.dataset.url);
|
||||
},
|
||||
|
||||
toggleFullscreen() {
|
||||
this.setData({ isFullscreen: !this.data.isFullscreen });
|
||||
},
|
||||
|
||||
getFullImageUrl(relativeUrl) {
|
||||
if (!relativeUrl) return '';
|
||||
if (relativeUrl.startsWith('http')) return relativeUrl;
|
||||
const app = getApp();
|
||||
let base = app.globalData.ossImageUrl || '';
|
||||
base = base.replace(/\/+$/, '');
|
||||
const clean = relativeUrl.replace(/^\/+/, '');
|
||||
return base ? base + '/' + clean : clean;
|
||||
},
|
||||
|
||||
preventMove() {},
|
||||
|
||||
onMinimize() {
|
||||
const remaining = this.data.remainingSeconds;
|
||||
this.clearTimer();
|
||||
|
||||
const app = getApp();
|
||||
let avatarUrl = '';
|
||||
if (app.globalData.morentouxiang) {
|
||||
avatarUrl = app.globalData.morentouxiang;
|
||||
} else {
|
||||
avatarUrl = '/images/default-avatar.png';
|
||||
}
|
||||
|
||||
if (avatarUrl && !avatarUrl.startsWith('http')) {
|
||||
const ossBase = app.globalData.ossImageUrl || '';
|
||||
avatarUrl = ossBase.replace(/\/+$/, '') + '/' + avatarUrl.replace(/^\/+/, '');
|
||||
}
|
||||
|
||||
this.setData({
|
||||
visible: false,
|
||||
isMinimized: true,
|
||||
savedRemainingSeconds: remaining,
|
||||
floatX: 20,
|
||||
floatY: 200,
|
||||
floatAvatarUrl: avatarUrl
|
||||
});
|
||||
},
|
||||
|
||||
onFloatChange(e) {
|
||||
this.setData({
|
||||
floatX: e.detail.x,
|
||||
floatY: e.detail.y
|
||||
});
|
||||
},
|
||||
|
||||
onFloatTap() {
|
||||
this.setData({
|
||||
visible: true,
|
||||
isMinimized: false,
|
||||
remainingSeconds: this.data.savedRemainingSeconds
|
||||
});
|
||||
|
||||
if (this.data.duration > 0 && this.data.savedRemainingSeconds > 0) {
|
||||
this.startCountdown();
|
||||
}
|
||||
},
|
||||
|
||||
onFloatAvatarError() {
|
||||
this.setData({
|
||||
floatAvatarUrl: '/images/avatar-placeholder.png'
|
||||
});
|
||||
},
|
||||
|
||||
cleanup() {
|
||||
this.clearTimer();
|
||||
this.setData({
|
||||
visible: false,
|
||||
isMinimized: false
|
||||
});
|
||||
PopupService.reset();
|
||||
},
|
||||
|
||||
onFloatTouchStart(e) {
|
||||
const touch = e.touches[0];
|
||||
this.touchStartX = touch.clientX;
|
||||
this.touchStartY = touch.clientY;
|
||||
this.startFloatX = this.data.floatX;
|
||||
this.startFloatY = this.data.floatY;
|
||||
this.hasMoved = false;
|
||||
return false;
|
||||
},
|
||||
|
||||
onFloatTouchMove(e) {
|
||||
const touch = e.touches[0];
|
||||
const deltaX = touch.clientX - this.touchStartX;
|
||||
const deltaY = touch.clientY - this.touchStartY;
|
||||
|
||||
if (Math.abs(deltaX) > 5 || Math.abs(deltaY) > 5) {
|
||||
this.hasMoved = true;
|
||||
}
|
||||
|
||||
let newX = this.startFloatX + deltaX;
|
||||
let newY = this.startFloatY + deltaY;
|
||||
|
||||
const systemInfo = wx.getSystemInfoSync();
|
||||
const screenWidth = systemInfo.windowWidth;
|
||||
const screenHeight = systemInfo.windowHeight;
|
||||
const estimatedSize = 60;
|
||||
|
||||
newX = Math.max(0, Math.min(newX, screenWidth - estimatedSize));
|
||||
newY = Math.max(0, Math.min(newY, screenHeight - estimatedSize));
|
||||
this.setData({ floatX: newX, floatY: newY });
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
onFloatTouchEnd(e) {
|
||||
if (!this.hasMoved) {
|
||||
this.onFloatTap();
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// 🆕 阻止事件冒泡(用于预览遮罩内部点击不关闭)
|
||||
stopPropagation() {}
|
||||
}
|
||||
});
|
||||
4
miniprogram/components/popup-notice/popup-notice.json
Normal file
4
miniprogram/components/popup-notice/popup-notice.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
||||
110
miniprogram/components/popup-notice/popup-notice.wxml
Normal file
110
miniprogram/components/popup-notice/popup-notice.wxml
Normal file
@@ -0,0 +1,110 @@
|
||||
<!-- components/popup-notice/popup-notice.wxml -->
|
||||
|
||||
<!-- 全屏弹窗遮罩层(完全不变) -->
|
||||
<view class="popup-mask" wx:if="{{visible}}" catchtouchmove="preventMove">
|
||||
<view class="popup-container {{isFullscreen ? 'fullscreen' : ''}}">
|
||||
<!-- 右上角操作按钮组 -->
|
||||
<view class="action-buttons">
|
||||
<!-- 最小化按钮 -->
|
||||
<view class="minimize-btn" bindtap="onMinimize">
|
||||
<text class="btn-icon">−</text>
|
||||
</view>
|
||||
<!-- 全屏切换按钮 -->
|
||||
<view class="fullscreen-btn" bindtap="toggleFullscreen">
|
||||
<text class="btn-icon">{{isFullscreen ? '✕' : '⛶'}}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 标题 -->
|
||||
<view wx:if="{{title}}" class="popup-title">{{title}}</view>
|
||||
|
||||
<!-- 可滚动内容区 -->
|
||||
<view class="scroll-wrapper">
|
||||
<scroll-view scroll-y class="scroll-view" enhanced show-scrollbar="{{true}}">
|
||||
<view wx:if="{{hasTextOnly}}" class="text-content">{{textContent}}</view>
|
||||
<view wx:else>
|
||||
<view wx:for="{{processedImages}}" wx:key="index" class="image-block">
|
||||
<view wx:if="{{item.text}}" class="block-text">{{item.text}}</view>
|
||||
<view class="image-padding">
|
||||
<image
|
||||
class="block-image"
|
||||
src="{{item.url}}"
|
||||
style="width:100%; height:{{item.height}}px; display:block;"
|
||||
data-index="{{index}}"
|
||||
data-url="{{item.url}}"
|
||||
bindtap="onCustomPreview"
|
||||
binderror="onImageError"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
|
||||
<!-- 底部固定区 -->
|
||||
<view class="bottom-fixed">
|
||||
<view wx:if="{{remainingSeconds > 0}}" class="countdown-tip">
|
||||
请阅读 {{remainingSeconds}} 秒后关闭
|
||||
</view>
|
||||
<view wx:if="{{remainingSeconds === 0 && showMuteCheckbox}}" class="mute-row">
|
||||
<checkbox-group bindchange="onMuteChange">
|
||||
<checkbox value="mute" color="#000" />
|
||||
<text class="mute-label">今日不再提示</text>
|
||||
</checkbox-group>
|
||||
</view>
|
||||
<!-- 关闭按钮 -->
|
||||
<view
|
||||
class="close-btn {{remainingSeconds > 0 ? 'close-btn-disabled' : ''}}"
|
||||
bindtap="{{remainingSeconds > 0 ? '' : 'onCloseTap'}}"
|
||||
>
|
||||
<text class="close-btn-text">{{remainingSeconds > 0 ? '阅读中...' : '关闭'}}</text>
|
||||
<view class="close-btn-sweep" wx:if="{{remainingSeconds === 0}}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 悬浮窗(自定义触摸拖动) -->
|
||||
<view
|
||||
class="floating-avatar-wrapper"
|
||||
wx:if="{{isMinimized}}"
|
||||
style="left: {{floatX}}px; top: {{floatY}}px;"
|
||||
catchtouchstart="onFloatTouchStart"
|
||||
catchtouchmove="onFloatTouchMove"
|
||||
catchtouchend="onFloatTouchEnd"
|
||||
>
|
||||
<image
|
||||
class="floating-avatar"
|
||||
src="{{floatAvatarUrl}}"
|
||||
mode="aspectFill"
|
||||
binderror="onFloatAvatarError"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 🆕 自定义图片预览遮罩(全屏,不触发页面生命周期) -->
|
||||
<view
|
||||
class="custom-preview-mask"
|
||||
wx:if="{{showCustomPreview}}"
|
||||
catchtouchmove="preventMove"
|
||||
bindtap="onCloseCustomPreview"
|
||||
>
|
||||
<view class="preview-header">
|
||||
<text class="preview-index">{{currentPreviewIndex + 1}} / {{previewUrls.length}}</text>
|
||||
<view class="preview-close" bindtap="onCloseCustomPreview">×</view>
|
||||
</view>
|
||||
<swiper
|
||||
class="preview-swiper"
|
||||
current="{{currentPreviewIndex}}"
|
||||
bindchange="onPreviewSwiperChange"
|
||||
indicator-dots="{{false}}"
|
||||
>
|
||||
<swiper-item wx:for="{{previewUrls}}" wx:key="index">
|
||||
<image
|
||||
src="{{item}}"
|
||||
mode="aspectFit"
|
||||
class="preview-image"
|
||||
catchtap="stopPropagation"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
</view>
|
||||
295
miniprogram/components/popup-notice/popup-notice.wxss
Normal file
295
miniprogram/components/popup-notice/popup-notice.wxss
Normal file
@@ -0,0 +1,295 @@
|
||||
/* components/popup-notice/popup-notice.wxss */
|
||||
|
||||
/* ========== 全屏弹窗样式(原有,完全不变) ========== */
|
||||
.popup-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.popup-container {
|
||||
width: 90%;
|
||||
height: 85vh;
|
||||
background: white;
|
||||
border-radius: 32rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.popup-container.fullscreen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
position: absolute;
|
||||
top: 20rpx;
|
||||
right: 20rpx;
|
||||
display: flex;
|
||||
gap: 16rpx;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.minimize-btn,
|
||||
.fullscreen-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
backdrop-filter: blur(4rpx);
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.minimize-btn:active,
|
||||
.fullscreen-btn:active {
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
font-size: 36rpx;
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
text-align: center;
|
||||
padding: 30rpx 30rpx 20rpx;
|
||||
border-bottom: 2rpx solid #eee;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.scroll-wrapper {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.text-content {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
line-height: 1.6;
|
||||
padding: 30rpx;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.image-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.block-text {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #000;
|
||||
padding: 16rpx 30rpx 4rpx 30rpx;
|
||||
text-align: left;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.image-padding {
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.block-image {
|
||||
width: 100%;
|
||||
display: block;
|
||||
background: #f5f5f5;
|
||||
border-radius: 16rpx;
|
||||
}
|
||||
|
||||
.bottom-fixed {
|
||||
background: white;
|
||||
border-top: 1rpx solid #eee;
|
||||
padding: 20rpx 0 30rpx 0;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.countdown-tip {
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #ff6600;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.mute-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.mute-label {
|
||||
font-size: 28rpx;
|
||||
color: #555;
|
||||
margin-left: 12rpx;
|
||||
}
|
||||
|
||||
/* 🔥 关闭按钮(替换原有 button,增加扫光) */
|
||||
.close-btn {
|
||||
width: 600rpx;
|
||||
height: 100rpx;
|
||||
background: #1a1a1a;
|
||||
border-radius: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.close-btn:active {
|
||||
opacity: 0.85;
|
||||
transform: scale(0.98);
|
||||
}
|
||||
|
||||
.close-btn-disabled {
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.close-btn-text {
|
||||
color: white;
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.close-btn-sweep {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.5), transparent);
|
||||
transform: skewX(-20deg);
|
||||
animation: sweep 2.5s infinite ease-in-out;
|
||||
z-index: 1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@keyframes sweep {
|
||||
0% { left: -100%; }
|
||||
40% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
/* ========== 悬浮窗样式(纯圆形,适配自定义触摸拖动) ========== */
|
||||
.floating-avatar-wrapper {
|
||||
position: fixed;
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
z-index: 10001;
|
||||
transform: translateZ(0);
|
||||
will-change: left, top;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.floating-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.3);
|
||||
border: 2rpx solid rgba(255, 215, 0, 0.6);
|
||||
background: #f0f0f0;
|
||||
display: block;
|
||||
transform: translateZ(0);
|
||||
}
|
||||
|
||||
/* 以下原有 movable-view 相关样式已弃用,但保留以维持代码完整(用户要求不删代码) */
|
||||
.floating-area {
|
||||
display: none;
|
||||
}
|
||||
.floating-view {
|
||||
display: none;
|
||||
}
|
||||
.float-avatar-wrapper {
|
||||
display: none;
|
||||
}
|
||||
.float-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ========== 自定义图片预览遮罩样式(全屏,不触发 onShow) ========== */
|
||||
.custom-preview-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.95);
|
||||
z-index: 100000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.preview-header {
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 0 30rpx;
|
||||
color: white;
|
||||
font-size: 32rpx;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.preview-index {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.preview-close {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 48rpx;
|
||||
color: white;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.preview-swiper {
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
Reference in New Issue
Block a user