feat:修改铸造选择卡片滑动bug异常
This commit is contained in:
parent
c93dd13dc3
commit
10bf5b9578
@ -6,14 +6,11 @@
|
|||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<view class="header-bar">
|
<view class="header-bar">
|
||||||
<view class="back-btn" @tap="handleBack">
|
<view class="back-btn" @tap="handleBack">
|
||||||
<image class="back-icon" src="/static/starbookcontent/tuichu.png" mode="aspectFit"></image>
|
<text class="back-icon">←</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="header-actions">
|
<view class="header-actions">
|
||||||
<ShareReportButtons
|
<ShareReportButtons :ownerNickname="assetData.owner_nickname || ''" :assetId="assetIdParam"
|
||||||
:ownerNickname="assetData.owner_nickname || ''"
|
:coverUrl="coverUrl" />
|
||||||
:assetId="assetIdParam"
|
|
||||||
:coverUrl="coverUrl"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
@ -116,8 +113,8 @@
|
|||||||
|
|
||||||
<!-- 创作者信息模块 -->
|
<!-- 创作者信息模块 -->
|
||||||
<view v-if="likeCount > 0" class="creator-section" @tap="showLikeUsersModal = true">
|
<view v-if="likeCount > 0" class="creator-section" @tap="showLikeUsersModal = true">
|
||||||
<!-- 点赞用户头像区域 -->
|
<!-- 点赞用户头像区域 -->
|
||||||
<view class="liked-users-area">
|
<view class="liked-users-area">
|
||||||
<view v-for="(user, index) in likedUsers" :key="index" class="liked-user-avatar" :style="{
|
<view v-for="(user, index) in likedUsers" :key="index" class="liked-user-avatar" :style="{
|
||||||
transform: `translate(${user.ellipseX || 0}rpx, ${user.ellipseY || 0}rpx) scale(${user.size || 1})`,
|
transform: `translate(${user.ellipseX || 0}rpx, ${user.ellipseY || 0}rpx) scale(${user.size || 1})`,
|
||||||
zIndex: index < 2 ? index + 1 : (index < 4 ? index + 3 : index + 1)
|
zIndex: index < 2 ? index + 1 : (index < 4 ? index + 3 : index + 1)
|
||||||
@ -376,7 +373,7 @@ function getStickerStyle(sticker) {
|
|||||||
return {
|
return {
|
||||||
left: `${ox}%`,
|
left: `${ox}%`,
|
||||||
top: `${oy}%`,
|
top: `${oy}%`,
|
||||||
transform: `translate(-50%, -50%) rotate(${rot}deg) scale(${scX}, ${scY})`,
|
transform: `translate(-50%, -50%) translateZ(0) rotate(${rot}deg) scale(${scX}, ${scY})`,
|
||||||
opacity: op,
|
opacity: op,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -837,8 +834,9 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.back-icon {
|
.back-icon {
|
||||||
width: 64rpx;
|
font-size: 48rpx;
|
||||||
height: 64rpx;
|
font-weight: bold;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-actions {
|
.header-actions {
|
||||||
@ -995,8 +993,9 @@ onUnmounted(() => {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 卡片区域 */
|
/* 卡片区域 */
|
||||||
.card-section {
|
.card-section {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -1005,6 +1004,7 @@ onUnmounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
perspective: 800rpx;
|
perspective: 800rpx;
|
||||||
transform-style: preserve-3d;
|
transform-style: preserve-3d;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-wrapper {
|
.card-wrapper {
|
||||||
@ -1014,21 +1014,26 @@ onUnmounted(() => {
|
|||||||
margin-bottom: 32rpx;
|
margin-bottom: 32rpx;
|
||||||
animation: card-3d-flip 15s ease-in-out infinite;
|
animation: card-3d-flip 15s ease-in-out infinite;
|
||||||
transform-origin: center center;
|
transform-origin: center center;
|
||||||
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes card-3d-flip {
|
@keyframes card-3d-flip {
|
||||||
0% {
|
0% {
|
||||||
transform: rotateY(0deg);
|
transform: rotateY(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
20% {
|
20% {
|
||||||
transform: rotateY(-30deg);
|
transform: rotateY(-30deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
50% {
|
50% {
|
||||||
transform: rotateY(30deg);
|
transform: rotateY(30deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
80% {
|
80% {
|
||||||
transform: rotateY(0deg);
|
transform: rotateY(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
transform: rotateY(0deg);
|
transform: rotateY(0deg);
|
||||||
}
|
}
|
||||||
@ -1047,9 +1052,9 @@ onUnmounted(() => {
|
|||||||
height: 96%;
|
height: 96%;
|
||||||
border-radius: 48rpx;
|
border-radius: 48rpx;
|
||||||
/* transform: translate(-50%, -50%) rotate(-10deg); */
|
/* transform: translate(-50%, -50%) rotate(-10deg); */
|
||||||
transform: translate(-50%, -50%) ;
|
transform: translate(-50%, -50%);
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
overflow: hidden;
|
/* overflow: hidden; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-lenticular-card {
|
.detail-lenticular-card {
|
||||||
@ -1066,7 +1071,7 @@ onUnmounted(() => {
|
|||||||
transform-origin: center center;
|
transform-origin: center center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
overflow: hidden;
|
/* overflow: hidden; */
|
||||||
/* transform: rotate(-10deg); */
|
/* transform: rotate(-10deg); */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1098,6 +1103,8 @@ onUnmounted(() => {
|
|||||||
height: 72rpx;
|
height: 72rpx;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
transform-origin: center center;
|
transform-origin: center center;
|
||||||
|
transform-style: preserve-3d;
|
||||||
|
will-change: transform;
|
||||||
filter: drop-shadow(0 2rpx 6rpx rgba(0, 0, 0, 0.35));
|
filter: drop-shadow(0 2rpx 6rpx rgba(0, 0, 0, 0.35));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,37 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
<image
|
<image class="bg-wrapper" src="/static/castlove/beijingban.png" mode="aspectFill"></image>
|
||||||
class="bg-wrapper"
|
|
||||||
src="/static/castlove/beijingban.png"
|
|
||||||
mode="aspectFill"
|
|
||||||
></image>
|
|
||||||
<!-- 主体内容 -->
|
|
||||||
<view class="main-container">
|
<view class="main-container">
|
||||||
<!-- 左侧图片卡片区域 - 半圆弧形布局 -->
|
<view class="cards-container" @touchstart="onTouchStart" @touchmove="onTouchMove" @touchend="onTouchEnd">
|
||||||
<view class="cards-container"
|
|
||||||
@touchstart="onTouchStart"
|
|
||||||
@touchend="onTouchEnd">
|
|
||||||
<view v-for="(card, index) in currentCardList" :key="index" class="card-item"
|
<view v-for="(card, index) in currentCardList" :key="index" class="card-item"
|
||||||
:class="{ 'card-selected': selectedIndex === index }" :style="getCardStyle(index)">
|
:class="{ 'no-transition': disableTransition }" :style="getCardStyle(index)">
|
||||||
<view class="card-frame"
|
<view class="card-frame"
|
||||||
:class="{ 'no-border': card.comingSoon, 'card-frame--tappable': !card.comingSoon }"
|
:class="{ 'no-border': card.comingSoon, 'card-frame--tappable': !card.comingSoon }"
|
||||||
@tap.stop="onCardFrameTap(index)">
|
@tap.stop="onCardFrameTap(index)">
|
||||||
<image class="card-image" :src="card.image" mode="aspectFill" />
|
<image class="card-image" :src="card.image" mode="aspectFill" />
|
||||||
<image v-if="card.comingSoon" class="coming-soon-badge" src="/static/castlove/jinqingqidai.png"
|
<image v-if="card.comingSoon" class="coming-soon-badge"
|
||||||
mode="aspectFit" />
|
src="/static/castlove/jinqingqidai.png" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 右侧文字列表 - 大分类 -->
|
|
||||||
<view class="text-panel">
|
<view class="text-panel">
|
||||||
<!-- 向上按钮 -->
|
|
||||||
<view class="arrow-btn arrow-up" @click="scrollUp">
|
<view class="arrow-btn arrow-up" @click="scrollUp">
|
||||||
<image class="arrow-icon" src="/static/castlove/jiantou.png" mode="aspectFit"
|
<image class="arrow-icon" src="/static/castlove/jiantou.png" style="transform:rotate(180deg)" />
|
||||||
style="transform: rotate(180deg);" />
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 文字列表 -->
|
|
||||||
<view class="text-list">
|
<view class="text-list">
|
||||||
<view v-for="(category, index) in categoryList" :key="index" class="text-item"
|
<view v-for="(category, index) in categoryList" :key="index" class="text-item"
|
||||||
:class="{ active: selectedCategoryIndex === index, 'font-large': index === 1, 'font-mid': index === 0 || index === 2 }"
|
:class="{ active: selectedCategoryIndex === index, 'font-large': index === 1, 'font-mid': index === 0 || index === 2 }"
|
||||||
@ -39,20 +26,11 @@
|
|||||||
<text>{{ category.name }}</text>
|
<text>{{ category.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 向下按钮 -->
|
|
||||||
<view class="arrow-btn arrow-down" @click="scrollDown">
|
<view class="arrow-btn arrow-down" @click="scrollDown">
|
||||||
<image class="arrow-icon" src="/static/castlove/jiantou.png" mode="aspectFit" />
|
<image class="arrow-icon" src="/static/castlove/jiantou.png" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 自定义底部导航 -->
|
|
||||||
<!-- <view class="nav-bar">
|
|
||||||
<button class="btn-secondary" @click="handleBack">返回</button>
|
|
||||||
<button class="btn-skip" @click="handleSkip">确认</button>
|
|
||||||
</view> -->
|
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -60,35 +38,14 @@
|
|||||||
export default {
|
export default {
|
||||||
onShow() {
|
onShow() {
|
||||||
try {
|
try {
|
||||||
uni.hideToast();
|
uni.hideToast()
|
||||||
} catch (e) {
|
uni.hideLoading()
|
||||||
/* noop */
|
} catch (e) { }
|
||||||
}
|
|
||||||
try {
|
|
||||||
uni.hideLoading();
|
|
||||||
} catch (e) {
|
|
||||||
/* noop */
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
selectedCategoryIndex: 0,
|
selectedCategoryIndex: 0,
|
||||||
selectedIndex: 0,
|
categoryList: [{ name: '星卡' }, { name: '吧唧' }, { name: '海报' }],
|
||||||
touchStartY: 0,
|
|
||||||
// 大分类名称 → 页面路由映射,方便扩展
|
|
||||||
cardRoutes: {
|
|
||||||
'光栅卡': '/pages/castlove/lenticular/lenticular-create',
|
|
||||||
'拍立得': '/pages/castlove/create',
|
|
||||||
'镭射卡': '/pages/castlove/create',
|
|
||||||
'撕拉片': '/pages/castlove/create',
|
|
||||||
},
|
|
||||||
// 大分类列表
|
|
||||||
categoryList: [
|
|
||||||
{ name: '星卡' },
|
|
||||||
{ name: '吧唧' },
|
|
||||||
{ name: '海报' },
|
|
||||||
],
|
|
||||||
// 各分类下的工艺卡片
|
|
||||||
cardListMap: {
|
cardListMap: {
|
||||||
'星卡': [
|
'星卡': [
|
||||||
{ name: '光栅卡', image: '/static/castlove/guangshanka.png', comingSoon: false },
|
{ name: '光栅卡', image: '/static/castlove/guangshanka.png', comingSoon: false },
|
||||||
@ -97,20 +54,8 @@ export default {
|
|||||||
{ name: '镭射卡', image: '/static/castlove/leisheka.png', comingSoon: false },
|
{ name: '镭射卡', image: '/static/castlove/leisheka.png', comingSoon: false },
|
||||||
{ name: '撕拉片', image: '/static/castlove/silapian.png', comingSoon: false },
|
{ name: '撕拉片', image: '/static/castlove/silapian.png', comingSoon: false },
|
||||||
],
|
],
|
||||||
'吧唧': [
|
'吧唧': [],
|
||||||
// { name: '光栅卡', image: '/static/castlove/guangshanka.png', comingSoon: false },
|
'海报': []
|
||||||
// { name: '拍立得', image: '/static/castlove/pailide.png', comingSoon: false },
|
|
||||||
// { name: '镭射卡', image: '/static/castlove/leisheka.png', comingSoon: false },
|
|
||||||
// { name: '撕拉片', image: '/static/castlove/silapian.png', comingSoon: false },
|
|
||||||
// { name: '开发中', image: '/static/castlove/daikaifa.png', comingSoon: true }
|
|
||||||
],
|
|
||||||
'海报': [
|
|
||||||
// { name: '光栅卡', image: '/static/castlove/guangshanka.png', comingSoon: false },
|
|
||||||
// { name: '拍立得', image: '/static/castlove/pailide.png', comingSoon: false },
|
|
||||||
// { name: '镭射卡', image: '/static/castlove/leisheka.png', comingSoon: false },
|
|
||||||
// { name: '撕拉片', image: '/static/castlove/silapian.png', comingSoon: false },
|
|
||||||
// { name: '开发中', image: '/static/castlove/daikaifa.png', comingSoon: true }
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
cardList: [
|
cardList: [
|
||||||
{ name: '光栅卡', image: '/static/castlove/guangshanka.png', comingSoon: false },
|
{ name: '光栅卡', image: '/static/castlove/guangshanka.png', comingSoon: false },
|
||||||
@ -118,152 +63,152 @@ export default {
|
|||||||
{ name: '镭射卡', image: '/static/castlove/leisheka.png', comingSoon: false },
|
{ name: '镭射卡', image: '/static/castlove/leisheka.png', comingSoon: false },
|
||||||
{ name: '撕拉片', image: '/static/castlove/silapian.png', comingSoon: false },
|
{ name: '撕拉片', image: '/static/castlove/silapian.png', comingSoon: false },
|
||||||
{ name: '开发中', image: '/static/castlove/daikaifa.png', comingSoon: true }
|
{ name: '开发中', image: '/static/castlove/daikaifa.png', comingSoon: true }
|
||||||
]
|
],
|
||||||
|
cardRoutes: {
|
||||||
|
'光栅卡': '/pages/castlove/lenticular/lenticular-create',
|
||||||
|
'拍立得': '/pages/castlove/create',
|
||||||
|
'镭射卡': '/pages/castlove/create',
|
||||||
|
'撕拉片': '/pages/castlove/create',
|
||||||
|
},
|
||||||
|
|
||||||
|
totalCard: 5,
|
||||||
|
selectedIndex: 1, // 默认第2张
|
||||||
|
touchStartY: 0,
|
||||||
|
dragOffset: 0,
|
||||||
|
isDragging: false,
|
||||||
|
disableTransition: false,
|
||||||
|
SWIPE_STEP: 100,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
currentCardList() {
|
currentCardList() {
|
||||||
const categoryName = this.categoryList[this.selectedCategoryIndex].name
|
const name = this.categoryList[this.selectedCategoryIndex]?.name
|
||||||
return this.cardListMap[categoryName] || this.cardList
|
return this.cardListMap[name] || this.cardList
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 选择大分类
|
|
||||||
selectCategory(index) {
|
selectCategory(index) {
|
||||||
this.selectedCategoryIndex = index
|
this.selectedCategoryIndex = index
|
||||||
this.selectedIndex = 0 // 重置子选项选中
|
this.selectedIndex = 1
|
||||||
|
this.dragOffset = 0
|
||||||
|
this.isDragging = false
|
||||||
},
|
},
|
||||||
// 触摸开始
|
|
||||||
onTouchStart(e) {
|
onTouchStart(e) {
|
||||||
this.touchStartY = e.touches[0].clientY
|
this.touchStartY = e.touches[0].clientY
|
||||||
|
this.isDragging = true
|
||||||
|
this.disableTransition = true
|
||||||
},
|
},
|
||||||
// 触摸结束 - 滑动切换工艺卡片
|
onTouchMove(e) {
|
||||||
onTouchEnd(e) {
|
if (!this.isDragging) return
|
||||||
const touchEndY = e.changedTouches[0].clientY
|
const moveY = e.touches[0].clientY
|
||||||
const diff = this.touchStartY - touchEndY
|
this.dragOffset = moveY - this.touchStartY
|
||||||
const threshold = 50 // 滑动阈值
|
},
|
||||||
|
onTouchEnd() {
|
||||||
|
if (!this.isDragging) return
|
||||||
|
this.isDragging = false
|
||||||
|
this.disableTransition = false
|
||||||
|
|
||||||
if (diff > threshold) {
|
const moveCount = Math.round(-this.dragOffset / this.SWIPE_STEP)
|
||||||
// 向上滑动 → 下一个工艺卡片
|
let newIdx = this.selectedIndex + moveCount
|
||||||
let newIndex = this.selectedIndex + 1
|
newIdx = ((newIdx % 5) + 5) % 5
|
||||||
if (newIndex < this.currentCardList.length) {
|
this.selectedIndex = newIdx
|
||||||
this.selectCard(newIndex)
|
this.dragOffset = 0
|
||||||
}
|
|
||||||
} else if (diff < -threshold) {
|
|
||||||
// 向下滑动 → 上一个工艺卡片
|
|
||||||
let newIndex = this.selectedIndex - 1
|
|
||||||
if (newIndex >= 0) {
|
|
||||||
this.selectCard(newIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
// 获取卡片样式 - 循环滚动布局
|
|
||||||
// positions 定义了5个位置的固定样式(位置0最上,位置2中间,位置4最下)
|
// ====================== 核心修复:z-index + 层级 + 循环 ======================
|
||||||
// 当选中某个卡片时,该卡片显示在位置2(中间),其他卡片循环填充
|
|
||||||
getCardStyle(index) {
|
getCardStyle(index) {
|
||||||
const positions = [
|
const positions = [
|
||||||
{ left: 9 * 32, top: 2 * 32, rotate: 25, scale: 0.75 }, // 位置0 - 最上
|
{ left: 288, top: 64, rotate: 25, scale: 0.75 },
|
||||||
{ left: 3.75 * 32, top: 9 * 32, rotate: 12, scale: 0.95 }, // 位置1 - 中上
|
{ left: 120, top: 288, rotate: 12, scale: 0.95 },
|
||||||
{ left: 60, top: 580, rotate: 0, scale: 1 }, // 位置2 - 中间
|
{ left: 60, top: 580, rotate: 0, scale: 1 },
|
||||||
{ left: 3.75 * 32, top: 27.75 * 32, rotate: -12, scale: 0.95 }, // 位置3 - 中下
|
{ left: 120, top: 888, rotate: -12, scale: 0.95 },
|
||||||
{ left: 7 * 32, top: 34.25 * 32, rotate: -25, scale: 0.75 } // 位置4 - 最下
|
{ left: 224, top: 1096, rotate: -25, scale: 0.75 },
|
||||||
];
|
]
|
||||||
|
|
||||||
// 计算当前卡片应该显示在哪个位置
|
const progress = -this.dragOffset / this.SWIPE_STEP
|
||||||
// 循环移位:selectedIndex 的卡片显示在位置2(中间)
|
const centerIdx = this.selectedIndex + progress
|
||||||
const cardPos = (index - this.selectedIndex + 2 + 5) % 5;
|
|
||||||
const pos = positions[cardPos];
|
|
||||||
|
|
||||||
// 选中卡片在中间位置时放大
|
// 循环最短差值(关键)
|
||||||
if (cardPos === 2) {
|
let diff = index - centerIdx
|
||||||
|
if (diff > 2) diff -= 5
|
||||||
|
if (diff < -2) diff += 5
|
||||||
|
const cardPos = diff + 2
|
||||||
|
|
||||||
|
// 插值计算
|
||||||
|
let pos
|
||||||
|
if (Number.isInteger(cardPos)) {
|
||||||
|
pos = positions[cardPos] ?? positions[2]
|
||||||
|
} else {
|
||||||
|
const prev = Math.floor(cardPos)
|
||||||
|
const next = (prev + 1) % 5
|
||||||
|
const t = cardPos - prev
|
||||||
|
const p = positions[prev] ?? positions[2]
|
||||||
|
const n = positions[next] ?? positions[2]
|
||||||
|
pos = {
|
||||||
|
left: p.left + (n.left - p.left) * t,
|
||||||
|
top: p.top + (n.top - p.top) * t,
|
||||||
|
rotate: p.rotate + (n.rotate - p.rotate) * t,
|
||||||
|
scale: p.scale + (n.scale - p.scale) * t,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ====================== Z‑INDEX 终极修复 ======================
|
||||||
|
const distance = Math.abs(cardPos - 2)
|
||||||
|
const zIndex = Math.round(100 - distance * 30) // 越靠近中间层级越高
|
||||||
|
const isCenter = distance < 0.02
|
||||||
|
|
||||||
|
if (isCenter) {
|
||||||
return {
|
return {
|
||||||
left: `${pos.left}rpx`,
|
left: pos.left + 'rpx',
|
||||||
top: `${pos.top}rpx`,
|
top: pos.top + 'rpx',
|
||||||
transform: `scale(${pos.scale * 1.15}) rotate(0deg)`,
|
transform: `scale(${pos.scale * 1.15}) rotate(${pos.rotate}deg)`,
|
||||||
zIndex: 100
|
zIndex: 999, // 中心永远最高
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
left: `${pos.left}rpx`,
|
left: pos.left + 'rpx',
|
||||||
top: `${pos.top}rpx`,
|
top: pos.top + 'rpx',
|
||||||
transform: `scale(${pos.scale}) rotate(${pos.rotate}deg)`,
|
transform: `scale(${pos.scale}) rotate(${pos.rotate}deg)`,
|
||||||
zIndex: 30 - Math.abs(cardPos - 2) * 10
|
zIndex,
|
||||||
};
|
}
|
||||||
},
|
},
|
||||||
// 选择卡片
|
|
||||||
selectCard(index) {
|
|
||||||
this.selectedIndex = index;
|
|
||||||
},
|
|
||||||
/** 当前叠卡在弧形布局中的槽位:2=正中主图(最大),1=中上「第二张」叠层,0最上… */
|
|
||||||
getCardStackPosition(index) {
|
getCardStackPosition(index) {
|
||||||
return (index - this.selectedIndex + 2 + 5) % 5;
|
const progress = -this.dragOffset / this.SWIPE_STEP
|
||||||
|
const centerIdx = this.selectedIndex + progress
|
||||||
|
let diff = index - centerIdx
|
||||||
|
if (diff > 2) diff -= 5
|
||||||
|
if (diff < -2) diff += 5
|
||||||
|
return diff + 2
|
||||||
},
|
},
|
||||||
/**
|
|
||||||
* 点击卡图区域:
|
|
||||||
* - 正中主图(槽位 2)→ 进入对应工艺创建页(光栅卡即进入已接入预览的 create)
|
|
||||||
* - 中上叠层(槽位 1,常为拍立得示意)在选中光栅时 → 同样进入光栅卡创建(与设计稿「点第二张进光栅」一致)
|
|
||||||
* - 其余叠层 → 仅切换选中
|
|
||||||
*/
|
|
||||||
onCardFrameTap(index) {
|
onCardFrameTap(index) {
|
||||||
const card = this.currentCardList[index];
|
const card = this.currentCardList[index]
|
||||||
if (!card) {
|
if (!card) return
|
||||||
return;
|
const pos = this.getCardStackPosition(index)
|
||||||
}
|
if (Math.abs(pos - 2) < 0.2) {
|
||||||
const pos = this.getCardStackPosition(index);
|
|
||||||
// 只有中间位置的卡片点击才会进入创建页
|
|
||||||
// 其他位置点击只是切换选中(把卡片移到中间),再次点击中间卡片才进入
|
|
||||||
if (pos === 2) {
|
|
||||||
if (card.name === '光栅卡') {
|
if (card.name === '光栅卡') {
|
||||||
const route = this.cardRoutes[card.name];
|
uni.navigateTo({
|
||||||
if (route) {
|
url: this.cardRoutes['光栅卡'] + '?name=' + encodeURIComponent(card.name),
|
||||||
uni.navigateTo({
|
})
|
||||||
url: `${route}?name=${encodeURIComponent(card.name)}`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
uni.showToast({
|
uni.showToast({ title: '激情开发中', icon: 'none' })
|
||||||
title: '激情开发中',
|
|
||||||
icon: 'none',
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
this.selectCard(index);
|
this.selectedIndex = index
|
||||||
},
|
|
||||||
handleBack() {
|
|
||||||
uni.navigateBack()
|
|
||||||
},
|
},
|
||||||
|
|
||||||
scrollUp() {
|
scrollUp() {
|
||||||
let newIndex = this.selectedCategoryIndex - 1;
|
if (this.selectedCategoryIndex > 0) this.selectCategory(this.selectedCategoryIndex - 1)
|
||||||
if (newIndex >= 0) {
|
|
||||||
this.selectCategory(newIndex);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
scrollDown() {
|
scrollDown() {
|
||||||
let newIndex = this.selectedCategoryIndex + 1;
|
if (this.selectedCategoryIndex < this.categoryList.length - 1) {
|
||||||
if (newIndex < this.categoryList.length) {
|
this.selectCategory(this.selectedCategoryIndex + 1)
|
||||||
this.selectCategory(newIndex);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
handleSkip() {
|
},
|
||||||
const card = this.cardList[this.selectedIndex]
|
|
||||||
if (card.name === '光栅卡') {
|
|
||||||
const route = this.cardRoutes[card.name]
|
|
||||||
if (route) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: `${route}?name=${encodeURIComponent(card.name)}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
uni.showToast({
|
|
||||||
title: '激情开发中',
|
|
||||||
icon: 'none',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -274,14 +219,13 @@ export default {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 背景图片 */
|
|
||||||
.bg-wrapper {
|
.bg-wrapper {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: -16rpx;
|
top: -16rpx;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 110%;
|
height: 110%;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-container {
|
.main-container {
|
||||||
@ -303,11 +247,12 @@ export default {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
width: 344rpx;
|
width: 344rpx;
|
||||||
height: 344rpx;
|
height: 344rpx;
|
||||||
transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
|
transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
will-change: transform, z-index;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-frame--tappable {
|
.card-item.no-transition {
|
||||||
cursor: pointer;
|
transition: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-frame {
|
.card-frame {
|
||||||
@ -316,21 +261,18 @@ export default {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
padding: 10rpx;
|
padding: 10rpx;
|
||||||
overflow: visible;
|
|
||||||
background-image: url('/static/square/cangpinkuang1.png');
|
background-image: url('/static/square/cangpinkuang1.png');
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
box-shadow: 0 0 0 rgba(0, 0, 0, 0.5);
|
}
|
||||||
|
|
||||||
&.no-border {
|
.card-frame.no-border {
|
||||||
background-image: none;
|
background-image: none;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-image {
|
.card-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
display: block;
|
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,26 +285,18 @@ export default {
|
|||||||
height: 160rpx;
|
height: 160rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .card-selected .card-frame {
|
|
||||||
// border-color: #ffd700;
|
|
||||||
// box-shadow:
|
|
||||||
// 0 0 60rpx rgba(255, 215, 0, 0.8),
|
|
||||||
// 0 20rpx 60rpx rgba(0, 0, 0, 0.4),
|
|
||||||
// inset 0 2rpx 10rpx rgba(255, 255, 255, 0.6);
|
|
||||||
// }
|
|
||||||
|
|
||||||
.text-panel {
|
.text-panel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 30rpx;
|
right: 30rpx;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
width: 200rpx;
|
width: 200rpx;
|
||||||
height: 392rpx; // 18rem = 360rpx
|
height: 392rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: url('/static/castlove/xiahualan.png') no-repeat center center;
|
background: url('/static/castlove/xiahualan.png') no-repeat center;
|
||||||
background-size: 130%;
|
background-size: 130%;
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
}
|
}
|
||||||
@ -374,10 +308,6 @@ export default {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.arrow-icon {
|
.arrow-icon {
|
||||||
@ -388,84 +318,30 @@ export default {
|
|||||||
.text-list {
|
.text-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
|
||||||
padding: 0 20rpx;
|
padding: 0 20rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-item {
|
.text-item {
|
||||||
color: rgba(255, 255, 255);
|
color: #fff;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
transition: all 0.3s ease;
|
|
||||||
position: relative;
|
|
||||||
padding: 10rpx 20rpx;
|
padding: 10rpx 20rpx;
|
||||||
border-radius: 14rpx;
|
border-radius: 14rpx;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: #fff;
|
|
||||||
font-weight: bold;
|
|
||||||
text-shadow: 0 0 10rpx rgba(0, 0, 0, 0.8);
|
|
||||||
background: url('/static/nft/dingbutubiao_liang.png') no-repeat center center;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.font-large {
|
|
||||||
font-size: 34rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.font-mid {
|
|
||||||
font-size: 30rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.font-small {
|
|
||||||
font-size: 26rpx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-bar {
|
.text-item.active {
|
||||||
position: absolute;
|
font-weight: bold;
|
||||||
bottom: 0;
|
background: url('/static/nft/dingbutubiao_liang.png') no-repeat center;
|
||||||
left: 0;
|
background-size: 100% 100%;
|
||||||
right: 0;
|
|
||||||
display: flex;
|
|
||||||
padding: 30rpx 40rpx;
|
|
||||||
padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
|
|
||||||
z-index: 20;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary,
|
.font-large {
|
||||||
.btn-skip {
|
font-size: 34rpx;
|
||||||
flex: 1;
|
|
||||||
height: 88rpx;
|
|
||||||
line-height: 88rpx;
|
|
||||||
border-radius: 44rpx;
|
|
||||||
font-size: 36rpx;
|
|
||||||
font-family: 'yt', sans-serif;
|
|
||||||
font-weight: 600;
|
|
||||||
border: none;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
|
|
||||||
text-shadow: 0 4rpx 4rpx rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-secondary {
|
.font-mid {
|
||||||
background: rgba(255, 255, 255, 0.2);
|
font-size: 30rpx;
|
||||||
backdrop-filter: blur(10rpx);
|
|
||||||
color: #e6e6e6;
|
|
||||||
border: 2rpx solid rgba(255, 255, 255, 0.4);
|
|
||||||
margin-right: 20rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-secondary::after {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-skip {
|
|
||||||
background: linear-gradient(165deg, #F0E4B1 0%, #F08399 50%, #B94E73 90%, #834B9E 100%);
|
|
||||||
color: #e6e6e6;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -125,15 +125,15 @@ const props = defineProps({
|
|||||||
},
|
},
|
||||||
showTaskIcon: {
|
showTaskIcon: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: false,
|
||||||
},
|
},
|
||||||
showGuideIcon: {
|
showGuideIcon: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: false,
|
||||||
},
|
},
|
||||||
showStarActivityIcon: {
|
showStarActivityIcon: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: false,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -480,14 +480,14 @@ defineExpose({
|
|||||||
/* --- 上层图标样式 --- */
|
/* --- 上层图标样式 --- */
|
||||||
.task-icon-box {
|
.task-icon-box {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 40rpx;
|
top: 32rpx;
|
||||||
/* 固定在顶部 */
|
/* 固定在顶部 */
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
/* 水平居中 */
|
/* 水平居中 */
|
||||||
width: 34rpx;
|
width: 34rpx;
|
||||||
/* 图标宽度 */
|
/* 图标宽度 */
|
||||||
height: 40rpx;
|
height: 48rpx;
|
||||||
/* 图标高度 */
|
/* 图标高度 */
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
/* 确保图标在文字块上面 */
|
/* 确保图标在文字块上面 */
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
<text
|
<text
|
||||||
style="font-size: 30rpx;text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);color: #FFF9E7;min-width: 128rpx;"
|
style="font-size: 30rpx;text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);color: #FFF9E7;min-width: 128rpx;"
|
||||||
class="info-value">{{ nickname }}</text>
|
class="info-value">{{ nickname }}</text>
|
||||||
<view class="edit-btn" @tap="handleViewNickname">
|
<view class="edit-btn" @tap="handleChangeNickname">
|
||||||
<image class="edit-nickname-btn" src="/static/icon/edit-nickname.png"
|
<image class="edit-nickname-btn" src="/static/icon/edit-nickname.png"
|
||||||
mode="aspectFit"></image>
|
mode="aspectFit"></image>
|
||||||
<view class="edit-nickname-text">
|
<view class="edit-nickname-text">
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user