feat(card): 实现卡片预览区域自适应缩放功能
- 添加预览区高度动态计算逻辑,确保按钮始终可见 - 实现超大卡片等比缩放功能,避免超出屏幕范围 - 添加卡片真实高度测量和缩放比例计算 - 优化页面布局结构,设置固定操作按钮区域 - 调整样式防止内容溢出和滚动条显示
This commit is contained in:
+57
-9
@@ -7,9 +7,15 @@
|
||||
<text class="card-nav-title">酒局卡片</text>
|
||||
</view>
|
||||
|
||||
<!-- 大卡片预览 -->
|
||||
<view class="card-preview-area">
|
||||
<DrinkCard v-if="record" :record="record" />
|
||||
<!-- 大卡片预览:超高时自动等比缩放,保证按钮始终可见 -->
|
||||
<view class="card-preview-area" :style="{ height: previewH + 'px' }">
|
||||
<view
|
||||
v-if="record"
|
||||
class="card-scale-wrap"
|
||||
:style="previewScale < 1 ? { transform: 'scale(' + previewScale + ')', width: '620rpx' } : {}"
|
||||
>
|
||||
<DrinkCard :record="record" />
|
||||
</view>
|
||||
<view v-else class="card-empty">暂无记录</view>
|
||||
</view>
|
||||
|
||||
@@ -50,7 +56,11 @@ export default {
|
||||
record: null,
|
||||
saving: false,
|
||||
saved: false,
|
||||
posterPath: '' // 预生成的海报图片路径
|
||||
posterPath: '', // 预生成的海报图片路径
|
||||
// 预览区自适应缩放
|
||||
previewScale: 1,
|
||||
previewH: 400,
|
||||
cardNaturalH: 0
|
||||
}
|
||||
},
|
||||
async onLoad(options) {
|
||||
@@ -76,12 +86,45 @@ export default {
|
||||
}
|
||||
}
|
||||
if (!this.record) this.record = this.loadLocalRecord(options.recordId) || this.fallback()
|
||||
this.$nextTick(() => this.fitPreview())
|
||||
},
|
||||
onReady() {
|
||||
// 页面渲染完成后预生成海报,供分享使用
|
||||
this.preGeneratePoster()
|
||||
// 图片加载完成后卡片高度会变化,延迟再适配一次
|
||||
setTimeout(() => this.fitPreview(), 1500)
|
||||
},
|
||||
methods: {
|
||||
// ===== 预览区自适应:卡片超高时等比缩放,按钮始终完整可见 =====
|
||||
fitPreview() {
|
||||
const sys = uni.getSystemInfoSync()
|
||||
// 头部导航与底部按钮区的实测高度
|
||||
const query = uni.createSelectorQuery().in(this)
|
||||
query.select('.card-nav').boundingClientRect()
|
||||
query.select('.card-actions').boundingClientRect()
|
||||
query.exec(res => {
|
||||
const navH = (res && res[0] && res[0].height) || 88
|
||||
const actH = (res && res[1] && res[1].height) || 320
|
||||
this.previewH = Math.max(200, sys.windowHeight - navH - actH)
|
||||
this.measureCard()
|
||||
})
|
||||
},
|
||||
measureCard() {
|
||||
uni.createSelectorQuery().in(this)
|
||||
.select('.card-root').boundingClientRect()
|
||||
.exec(res => {
|
||||
const h = res && res[0] && res[0].height
|
||||
if (!h || h <= 0) {
|
||||
// 卡片尚未渲染完成,稍后重试
|
||||
setTimeout(() => this.measureCard(), 150)
|
||||
return
|
||||
}
|
||||
// scale 后测量值已被缩放,还原真实高度
|
||||
const natural = this.previewScale < 1 ? h / this.previewScale : h
|
||||
this.cardNaturalH = natural
|
||||
this.previewScale = natural > this.previewH ? Math.max(0.5, this.previewH / natural) : 1
|
||||
})
|
||||
},
|
||||
loadLocalRecord(id) {
|
||||
if (!id) return null
|
||||
try {
|
||||
@@ -757,7 +800,8 @@ export default {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
background: $bg-base;
|
||||
}
|
||||
|
||||
@@ -792,14 +836,17 @@ export default {
|
||||
color: $text-primary;
|
||||
}
|
||||
|
||||
/* 大卡片预览区 */
|
||||
/* 大卡片预览区:高度由 JS 按剩余可用空间动态设定,卡片超高时缩放 */
|
||||
.card-preview-area {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: $sp-lg;
|
||||
min-height: 0;
|
||||
padding: 0 $sp-lg;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-scale-wrap {
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
.card-empty {
|
||||
@@ -809,6 +856,7 @@ export default {
|
||||
|
||||
/* 操作按钮 */
|
||||
.card-actions {
|
||||
flex-shrink: 0;
|
||||
padding: $sp-lg;
|
||||
padding-bottom: calc($sp-lg + env(safe-area-inset-bottom));
|
||||
display: flex;
|
||||
|
||||
Reference in New Issue
Block a user