diff --git a/frontend/pages/asset-detail/asset-detail.vue b/frontend/pages/asset-detail/asset-detail.vue
index ba0fa4e..a9f1f09 100644
--- a/frontend/pages/asset-detail/asset-detail.vue
+++ b/frontend/pages/asset-detail/asset-detail.vue
@@ -6,14 +6,11 @@
@@ -116,8 +113,8 @@
-
-
+
+
-
-
+
-
-
+
+ :class="{ 'no-transition': disableTransition }" :style="getCardStyle(index)">
-
+
-
-
-
+
-
-
{{ category.name }}
-
-
-
+
-
-
-
-
@@ -60,35 +38,14 @@
export default {
onShow() {
try {
- uni.hideToast();
- } catch (e) {
- /* noop */
- }
- try {
- uni.hideLoading();
- } catch (e) {
- /* noop */
- }
+ uni.hideToast()
+ uni.hideLoading()
+ } catch (e) { }
},
data() {
return {
selectedCategoryIndex: 0,
- selectedIndex: 0,
- touchStartY: 0,
- // 大分类名称 → 页面路由映射,方便扩展
- cardRoutes: {
- '光栅卡': '/pages/castlove/lenticular/lenticular-create',
- '拍立得': '/pages/castlove/create',
- '镭射卡': '/pages/castlove/create',
- '撕拉片': '/pages/castlove/create',
- },
- // 大分类列表
- categoryList: [
- { name: '星卡' },
- { name: '吧唧' },
- { name: '海报' },
- ],
- // 各分类下的工艺卡片
+ categoryList: [{ name: '星卡' }, { name: '吧唧' }, { name: '海报' }],
cardListMap: {
'星卡': [
{ 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/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: [
{ 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/silapian.png', comingSoon: false },
{ 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: {
currentCardList() {
- const categoryName = this.categoryList[this.selectedCategoryIndex].name
- return this.cardListMap[categoryName] || this.cardList
+ const name = this.categoryList[this.selectedCategoryIndex]?.name
+ return this.cardListMap[name] || this.cardList
}
},
methods: {
- // 选择大分类
selectCategory(index) {
this.selectedCategoryIndex = index
- this.selectedIndex = 0 // 重置子选项选中
+ this.selectedIndex = 1
+ this.dragOffset = 0
+ this.isDragging = false
},
- // 触摸开始
onTouchStart(e) {
this.touchStartY = e.touches[0].clientY
+ this.isDragging = true
+ this.disableTransition = true
},
- // 触摸结束 - 滑动切换工艺卡片
- onTouchEnd(e) {
- const touchEndY = e.changedTouches[0].clientY
- const diff = this.touchStartY - touchEndY
- const threshold = 50 // 滑动阈值
+ onTouchMove(e) {
+ if (!this.isDragging) return
+ const moveY = e.touches[0].clientY
+ this.dragOffset = moveY - this.touchStartY
+ },
+ onTouchEnd() {
+ if (!this.isDragging) return
+ this.isDragging = false
+ this.disableTransition = false
- if (diff > threshold) {
- // 向上滑动 → 下一个工艺卡片
- let newIndex = this.selectedIndex + 1
- if (newIndex < this.currentCardList.length) {
- this.selectCard(newIndex)
- }
- } else if (diff < -threshold) {
- // 向下滑动 → 上一个工艺卡片
- let newIndex = this.selectedIndex - 1
- if (newIndex >= 0) {
- this.selectCard(newIndex)
- }
- }
+ const moveCount = Math.round(-this.dragOffset / this.SWIPE_STEP)
+ let newIdx = this.selectedIndex + moveCount
+ newIdx = ((newIdx % 5) + 5) % 5
+ this.selectedIndex = newIdx
+ this.dragOffset = 0
},
- // 获取卡片样式 - 循环滚动布局
- // positions 定义了5个位置的固定样式(位置0最上,位置2中间,位置4最下)
- // 当选中某个卡片时,该卡片显示在位置2(中间),其他卡片循环填充
+
+ // ====================== 核心修复:z-index + 层级 + 循环 ======================
getCardStyle(index) {
const positions = [
- { left: 9 * 32, top: 2 * 32, rotate: 25, scale: 0.75 }, // 位置0 - 最上
- { left: 3.75 * 32, top: 9 * 32, rotate: 12, scale: 0.95 }, // 位置1 - 中上
- { left: 60, top: 580, rotate: 0, scale: 1 }, // 位置2 - 中间
- { left: 3.75 * 32, top: 27.75 * 32, rotate: -12, scale: 0.95 }, // 位置3 - 中下
- { left: 7 * 32, top: 34.25 * 32, rotate: -25, scale: 0.75 } // 位置4 - 最下
- ];
+ { left: 288, top: 64, rotate: 25, scale: 0.75 },
+ { left: 120, top: 288, rotate: 12, scale: 0.95 },
+ { left: 60, top: 580, rotate: 0, scale: 1 },
+ { left: 120, top: 888, rotate: -12, scale: 0.95 },
+ { left: 224, top: 1096, rotate: -25, scale: 0.75 },
+ ]
- // 计算当前卡片应该显示在哪个位置
- // 循环移位:selectedIndex 的卡片显示在位置2(中间)
- const cardPos = (index - this.selectedIndex + 2 + 5) % 5;
- const pos = positions[cardPos];
+ const progress = -this.dragOffset / this.SWIPE_STEP
+ const centerIdx = this.selectedIndex + progress
- // 选中卡片在中间位置时放大
- 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 {
- left: `${pos.left}rpx`,
- top: `${pos.top}rpx`,
- transform: `scale(${pos.scale * 1.15}) rotate(0deg)`,
- zIndex: 100
- };
+ left: pos.left + 'rpx',
+ top: pos.top + 'rpx',
+ transform: `scale(${pos.scale * 1.15}) rotate(${pos.rotate}deg)`,
+ zIndex: 999, // 中心永远最高
+ }
}
return {
- left: `${pos.left}rpx`,
- top: `${pos.top}rpx`,
+ left: pos.left + 'rpx',
+ top: pos.top + 'rpx',
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) {
- 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) {
- const card = this.currentCardList[index];
- if (!card) {
- return;
- }
- const pos = this.getCardStackPosition(index);
- // 只有中间位置的卡片点击才会进入创建页
- // 其他位置点击只是切换选中(把卡片移到中间),再次点击中间卡片才进入
- if (pos === 2) {
+ const card = this.currentCardList[index]
+ if (!card) return
+ const pos = this.getCardStackPosition(index)
+ if (Math.abs(pos - 2) < 0.2) {
if (card.name === '光栅卡') {
- const route = this.cardRoutes[card.name];
- if (route) {
- uni.navigateTo({
- url: `${route}?name=${encodeURIComponent(card.name)}`,
- });
- }
+ uni.navigateTo({
+ url: this.cardRoutes['光栅卡'] + '?name=' + encodeURIComponent(card.name),
+ })
} else {
- uni.showToast({
- title: '激情开发中',
- icon: 'none',
- });
+ uni.showToast({ title: '激情开发中', icon: 'none' })
}
- return;
+ return
}
- this.selectCard(index);
- },
- handleBack() {
- uni.navigateBack()
+ this.selectedIndex = index
},
+
scrollUp() {
- let newIndex = this.selectedCategoryIndex - 1;
- if (newIndex >= 0) {
- this.selectCategory(newIndex);
- }
+ if (this.selectedCategoryIndex > 0) this.selectCategory(this.selectedCategoryIndex - 1)
},
scrollDown() {
- let newIndex = this.selectedCategoryIndex + 1;
- if (newIndex < this.categoryList.length) {
- this.selectCategory(newIndex);
+ if (this.selectedCategoryIndex < this.categoryList.length - 1) {
+ this.selectCategory(this.selectedCategoryIndex + 1)
}
},
- 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',
- });
- }
-
- }
- }
+ },
}
@@ -274,14 +219,13 @@ export default {
overflow: hidden;
}
-/* 背景图片 */
.bg-wrapper {
- position: fixed;
- top: -16rpx;
- left: 0;
- width: 100%;
- height: 110%;
- z-index: 0;
+ position: fixed;
+ top: -16rpx;
+ left: 0;
+ width: 100%;
+ height: 110%;
+ z-index: 0;
}
.main-container {
@@ -303,11 +247,12 @@ export default {
position: absolute;
width: 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 {
- cursor: pointer;
+.card-item.no-transition {
+ transition: none !important;
}
.card-frame {
@@ -316,21 +261,18 @@ export default {
height: 100%;
border-radius: 20rpx;
padding: 10rpx;
- overflow: visible;
background-image: url('/static/square/cangpinkuang1.png');
background-size: cover;
- box-shadow: 0 0 0 rgba(0, 0, 0, 0.5);
+}
- &.no-border {
- background-image: none;
- }
+.card-frame.no-border {
+ background-image: none;
}
.card-image {
width: 100%;
height: 100%;
border-radius: 14rpx;
- display: block;
object-fit: cover;
}
@@ -343,26 +285,18 @@ export default {
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 {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
width: 200rpx;
- height: 392rpx; // 18rem = 360rpx
+ height: 392rpx;
display: flex;
flex-direction: column;
align-items: 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%;
border-radius: 20rpx;
}
@@ -374,10 +308,6 @@ export default {
align-items: center;
justify-content: center;
opacity: 0.8;
-
- &:active {
- opacity: 0.6;
- }
}
.arrow-icon {
@@ -388,84 +318,30 @@ export default {
.text-list {
display: flex;
flex-direction: column;
- justify-content: center;
padding: 0 20rpx;
}
.text-item {
- color: rgba(255, 255, 255);
+ color: #fff;
font-size: 26rpx;
font-weight: 500;
- transition: all 0.3s ease;
- position: relative;
padding: 10rpx 20rpx;
border-radius: 14rpx;
display: flex;
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 {
- position: absolute;
- bottom: 0;
- left: 0;
- right: 0;
- display: flex;
- padding: 30rpx 40rpx;
- padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
- z-index: 20;
+.text-item.active {
+ font-weight: bold;
+ background: url('/static/nft/dingbutubiao_liang.png') no-repeat center;
+ background-size: 100% 100%;
}
-.btn-secondary,
-.btn-skip {
- 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);
+.font-large {
+ font-size: 34rpx;
}
-.btn-secondary {
- background: rgba(255, 255, 255, 0.2);
- 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;
+.font-mid {
+ font-size: 30rpx;
}
\ No newline at end of file
diff --git a/frontend/pages/components/Header.vue b/frontend/pages/components/Header.vue
index bc1de9f..3227b40 100644
--- a/frontend/pages/components/Header.vue
+++ b/frontend/pages/components/Header.vue
@@ -125,15 +125,15 @@ const props = defineProps({
},
showTaskIcon: {
type: Boolean,
- default: true,
+ default: false,
},
showGuideIcon: {
type: Boolean,
- default: true,
+ default: false,
},
showStarActivityIcon: {
type: Boolean,
- default: true,
+ default: false,
},
});
@@ -480,14 +480,14 @@ defineExpose({
/* --- 上层图标样式 --- */
.task-icon-box {
position: absolute;
- top: 40rpx;
+ top: 32rpx;
/* 固定在顶部 */
left: 50%;
transform: translateX(-50%);
/* 水平居中 */
width: 34rpx;
/* 图标宽度 */
- height: 40rpx;
+ height: 48rpx;
/* 图标高度 */
z-index: 10;
/* 确保图标在文字块上面 */
diff --git a/frontend/pages/profile/profile.vue b/frontend/pages/profile/profile.vue
index f8d6afe..e4efdef 100644
--- a/frontend/pages/profile/profile.vue
+++ b/frontend/pages/profile/profile.vue
@@ -34,7 +34,7 @@
{{ nickname }}
-
+