bindbox-mini/components/ClayCard.vue
2026-02-27 20:57:24 +08:00

152 lines
3.7 KiB
Vue
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view
class="clay-card"
:class="[
`clay-card-${size}`,
{ 'clay-card-primary': variant === 'primary' },
{ 'clay-card-gold': variant === 'gold' },
{ 'clay-card-inset': inset },
customClass
]"
:style="customStyle"
@tap="handleTap"
>
<slot></slot>
</view>
</template>
<script>
export default {
name: 'ClayCard',
props: {
// 卡片尺寸sm, md, lg
size: {
type: String,
default: 'md'
},
// 变体default, primary, gold
variant: {
type: String,
default: 'default'
},
// 是否凹陷效果
inset: {
type: Boolean,
default: false
},
// 自定义类名
customClass: {
type: String,
default: ''
},
// 自定义样式
customStyle: {
type: Object,
default: () => ({})
}
},
methods: {
handleTap(e) {
this.$emit('tap', e)
}
}
}
</script>
<style lang="scss" scoped>
/* ============================================
Claymorphism 卡片组件
使用示例:
<ClayCard size="lg" variant="primary">内容</ClayCard>
============================================ */
.clay-card {
background: linear-gradient(145deg, #ffffff, #f0f0f0);
border-radius: 24rpx;
position: relative;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
/* 外部双阴影 - 创造凸起效果 */
box-shadow:
8rpx 8rpx 16rpx rgba(0, 0, 0, 0.06),
-8rpx -8rpx 16rpx rgba(255, 255, 255, 0.8),
inset 2rpx 2rpx 4rpx rgba(255, 255, 255, 0.9),
inset -2rpx -2rpx 4rpx rgba(0, 0, 0, 0.03);
&.clay-card-sm {
border-radius: 16rpx;
box-shadow:
6rpx 6rpx 12rpx rgba(0, 0, 0, 0.04),
-6rpx -6rpx 12rpx rgba(255, 255, 255, 0.8),
inset 2rpx 2rpx 4rpx rgba(255, 255, 255, 0.9),
inset -2rpx -2rpx 4rpx rgba(0, 0, 0, 0.03);
}
&.clay-card-md {
border-radius: 24rpx;
}
&.clay-card-lg {
border-radius: 32rpx;
box-shadow:
12rpx 12rpx 24rpx rgba(0, 0, 0, 0.08),
-12rpx -12rpx 24rpx rgba(255, 255, 255, 0.7),
inset 4rpx 4rpx 8rpx rgba(255, 255, 255, 0.85),
inset -4rpx -4rpx 8rpx rgba(0, 0, 0, 0.04);
}
&:active {
transform: scale(0.98);
box-shadow:
4rpx 4rpx 8rpx rgba(0, 0, 0, 0.06),
-4rpx -4rpx 8rpx rgba(255, 255, 255, 0.6),
inset 4rpx 4rpx 8rpx rgba(0, 0, 0, 0.05),
inset -4rpx -4rpx 8rpx rgba(255, 255, 255, 0.4);
}
}
/* 彩色粘土卡片 */
.clay-card-primary {
background: linear-gradient(145deg, #FF9500, #FF6B00);
color: #fff;
box-shadow:
10rpx 10rpx 20rpx rgba(255, 107, 0, 0.2),
-10rpx -10rpx 20rpx rgba(255, 255, 255, 0.7),
inset 3rpx 3rpx 6rpx rgba(255, 255, 255, 0.4),
inset -3rpx -3rpx 6rpx rgba(0, 0, 0, 0.1);
&:active {
box-shadow:
5rpx 5rpx 10rpx rgba(255, 107, 0, 0.25),
-5rpx -5rpx 10rpx rgba(255, 255, 255, 0.5),
inset 5rpx 5rpx 10rpx rgba(0, 0, 0, 0.15),
inset -5rpx -5rpx 10rpx rgba(255, 255, 255, 0.2);
}
}
.clay-card-gold {
background: linear-gradient(145deg, #FFD60A, #FF9F0A);
box-shadow:
10rpx 10rpx 20rpx rgba(255, 159, 10, 0.2),
-10rpx -10rpx 20rpx rgba(255, 255, 255, 0.7),
inset 3rpx 3rpx 6rpx rgba(255, 255, 255, 0.4),
inset -3rpx -3rpx 6rpx rgba(0, 0, 0, 0.1);
&:active {
box-shadow:
5rpx 5rpx 10rpx rgba(255, 159, 10, 0.25),
-5rpx -5rpx 10rpx rgba(255, 255, 255, 0.5),
inset 5rpx 5rpx 10rpx rgba(0, 0, 0, 0.15),
inset -5rpx -5rpx 10rpx rgba(255, 255, 255, 0.2);
}
}
/* 凹陷粘土卡片 (Inset) */
.clay-card-inset {
background: linear-gradient(145deg, #e8e8e8, #f8f8f8);
box-shadow:
inset 6rpx 6rpx 12rpx rgba(0, 0, 0, 0.08),
inset -6rpx -6rpx 12rpx rgba(255, 255, 255, 0.9);
}
</style>