feat(tabbar): tabBar改造
This commit is contained in:
parent
eb7a4f68eb
commit
93cad9032e
|
@ -0,0 +1,333 @@
|
|||
<template>
|
||||
<view class="raised-tabbar">
|
||||
<!-- 背景遮罩层,创建凸起效果 -->
|
||||
<view class="tabbar-bg">
|
||||
<view class="raised-circle"></view>
|
||||
</view>
|
||||
|
||||
<!-- TabBar内容 -->
|
||||
<view class="tabbar-content">
|
||||
<!-- 左侧两个选项 -->
|
||||
<view
|
||||
v-for="(item, index) in leftItems"
|
||||
:key="index"
|
||||
class="tabbar-item"
|
||||
:class="{ active: current === index }"
|
||||
@click="tabbarChange(index)"
|
||||
>
|
||||
<view class="item-icon">
|
||||
<image
|
||||
:src="current === index ? item.activeIcon : item.inactiveIcon"
|
||||
class="icon-normal"
|
||||
/>
|
||||
<view v-if="item.badge && item.badge > 0" class="badge">{{
|
||||
item.badge
|
||||
}}</view>
|
||||
</view>
|
||||
<text class="item-text" :class="{ active: current === index }">{{
|
||||
item.text
|
||||
}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 中间凸起的选项 -->
|
||||
<view
|
||||
class="tabbar-item center-item"
|
||||
:class="{ active: current === 2 }"
|
||||
@click="tabbarChange(2)"
|
||||
>
|
||||
<view class="center-icon-wrapper">
|
||||
<view class="center-icon">
|
||||
<image
|
||||
:src="
|
||||
current === 2 ? centerItem.activeIcon : centerItem.inactiveIcon
|
||||
"
|
||||
class="center-image"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
<text
|
||||
class="item-text center-text"
|
||||
:class="{ active: current === 2 }"
|
||||
>{{ centerItem.text }}</text
|
||||
>
|
||||
</view>
|
||||
|
||||
<!-- 右侧两个选项 -->
|
||||
<view
|
||||
v-for="(item, index) in rightItems"
|
||||
:key="index + 3"
|
||||
class="tabbar-item"
|
||||
:class="{ active: current === index + 3 }"
|
||||
@click="tabbarChange(index + 3)"
|
||||
>
|
||||
<view class="item-icon">
|
||||
<image
|
||||
:src="current === index + 3 ? item.activeIcon : item.inactiveIcon"
|
||||
class="icon-normal"
|
||||
/>
|
||||
<view v-if="item.badge && item.badge > 0" class="badge">{{
|
||||
item.badge
|
||||
}}</view>
|
||||
</view>
|
||||
<text class="item-text" :class="{ active: current === index + 3 }">{{
|
||||
item.text
|
||||
}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'RaisedTabbar',
|
||||
props: {
|
||||
current: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 完整的路由列表
|
||||
list: [
|
||||
{
|
||||
text: '首页',
|
||||
path: 'pages/index/index',
|
||||
},
|
||||
{
|
||||
text: '会员专区',
|
||||
path: 'pages/specialArea/index',
|
||||
},
|
||||
{
|
||||
text: '个人推广',
|
||||
path: 'pages/mine/share/index',
|
||||
},
|
||||
{
|
||||
text: '购物车',
|
||||
path: 'pages/shoppingCar/index',
|
||||
},
|
||||
{
|
||||
text: '我的',
|
||||
path: 'pages/mine/index',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['shopCarLength']),
|
||||
// 左侧两个选项
|
||||
leftItems() {
|
||||
return [
|
||||
{
|
||||
text: '首页',
|
||||
activeIcon: require('@/static/images/one1.png'),
|
||||
inactiveIcon: require('@/static/images/one2.png'),
|
||||
},
|
||||
{
|
||||
text: '会员专区',
|
||||
activeIcon: require('@/static/images/five1.jpg'),
|
||||
inactiveIcon: require('@/static/images/five2.jpg'),
|
||||
},
|
||||
]
|
||||
},
|
||||
// 中间凸起选项
|
||||
centerItem() {
|
||||
return {
|
||||
text: '个人推广',
|
||||
activeIcon: require('@/static/images/code.svg'),
|
||||
inactiveIcon: require('@/static/images/code.svg'),
|
||||
}
|
||||
},
|
||||
// 右侧两个选项
|
||||
rightItems() {
|
||||
return [
|
||||
{
|
||||
text: '购物车',
|
||||
activeIcon: require('@/static/images/three1.png'),
|
||||
inactiveIcon: require('@/static/images/three2.png'),
|
||||
badge: this.shopCarLength,
|
||||
},
|
||||
{
|
||||
text: '我的',
|
||||
activeIcon: require('@/static/images/fore1.png'),
|
||||
inactiveIcon: require('@/static/images/fore2.png'),
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
tabbarChange(index) {
|
||||
this.$emit('change', index)
|
||||
uni.switchTab({
|
||||
url: '/' + this.list[index].path,
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.raised-tabbar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
|
||||
.tabbar-bg {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 60px;
|
||||
background: #ffffff;
|
||||
|
||||
// 中间凸起的圆形背景
|
||||
// .raised-circle {
|
||||
// position: absolute;
|
||||
// top: -30rpx;
|
||||
// left: 50%;
|
||||
// transform: translateX(-50%);
|
||||
// width: 110rpx;
|
||||
// height: 110rpx;
|
||||
// background: #ffffff;
|
||||
// border-radius: 50%;
|
||||
// box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
||||
// }
|
||||
|
||||
// 添加底部安全区域
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -40px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: env(safe-area-inset-bottom);
|
||||
background: #ffffff;
|
||||
}
|
||||
}
|
||||
|
||||
.tabbar-content {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
height: 60px;
|
||||
padding-bottom: 5px;
|
||||
background: transparent;
|
||||
|
||||
.tabbar-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 5px;
|
||||
position: relative;
|
||||
|
||||
.item-icon {
|
||||
position: relative;
|
||||
margin-bottom: 2px;
|
||||
|
||||
.icon-normal {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: -5px;
|
||||
right: -8px;
|
||||
background: #ff4757;
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
line-height: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.item-text {
|
||||
font-size: 10px;
|
||||
color: #666666;
|
||||
line-height: 1.2;
|
||||
|
||||
&.active {
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
|
||||
// 中间凸起的特殊样式
|
||||
&.center-item {
|
||||
position: relative;
|
||||
|
||||
.center-icon-wrapper {
|
||||
position: absolute;
|
||||
top: -60rpx;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
font-size: 0;
|
||||
padding: 4rpx;
|
||||
|
||||
.center-icon {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
// box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
position: relative;
|
||||
// 添加呼吸动画
|
||||
animation: breathe 3s ease-in-out infinite;
|
||||
|
||||
.center-image {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
// position: absolute;
|
||||
// top: -10rpx;
|
||||
}
|
||||
|
||||
// 活跃状态
|
||||
// &.active {
|
||||
// background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
.center-text {
|
||||
margin-top: 25px;
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
.center-icon-wrapper .center-icon {
|
||||
// background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||||
transform: scale(1.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 呼吸动画关键帧
|
||||
@keyframes breathe {
|
||||
0%,
|
||||
100% {
|
||||
transform: scale(1);
|
||||
// box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.05);
|
||||
// box-shadow: 0 6px 20px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -271,7 +271,7 @@ export default {
|
|||
.member-code-outer {
|
||||
position: absolute;
|
||||
bottom: 160rpx;
|
||||
width: 500rpx;
|
||||
width: 300rpx;
|
||||
text-align: center;
|
||||
background: rgb(217, 24, 25);
|
||||
border-radius: 20rpx;
|
||||
|
|
|
@ -0,0 +1,195 @@
|
|||
<template>
|
||||
<view class="test-page">
|
||||
<view class="test-content">
|
||||
<view class="test-title">TabBar图标测试</view>
|
||||
|
||||
<!-- 显示当前状态 -->
|
||||
<view class="status-info">
|
||||
<text>当前选中: {{ currentTab }}</text>
|
||||
<text>主题皮肤: {{ systemSkin }}</text>
|
||||
<text>购物车数量: {{ shopCarLength || 0 }}</text>
|
||||
</view>
|
||||
|
||||
<!-- 图标测试区域 -->
|
||||
<view class="icon-test">
|
||||
<view class="icon-section">
|
||||
<text class="section-title">首页图标测试</text>
|
||||
<view class="icon-row">
|
||||
<image src="@/static/images/one1.png" class="test-icon" />
|
||||
<image src="@/static/images/one2.png" class="test-icon" />
|
||||
<image src="@/static/images/one11.jpg" class="test-icon" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="icon-section">
|
||||
<text class="section-title">会员专区图标测试</text>
|
||||
<view class="icon-row">
|
||||
<image src="@/static/images/special1.png" class="test-icon" />
|
||||
<image src="@/static/images/special2.png" class="test-icon" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="icon-section">
|
||||
<text class="section-title">个人推广图标测试</text>
|
||||
<view class="icon-row">
|
||||
<image src="@/static/images/share-act.svg" class="test-icon" />
|
||||
<image src="@/static/images/share.svg" class="test-icon" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="icon-section">
|
||||
<text class="section-title">购物车图标测试</text>
|
||||
<view class="icon-row">
|
||||
<image src="@/static/images/three1.png" class="test-icon" />
|
||||
<image src="@/static/images/three2.png" class="test-icon" />
|
||||
<image src="@/static/images/three11.jpg" class="test-icon" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="icon-section">
|
||||
<text class="section-title">我的图标测试</text>
|
||||
<view class="icon-row">
|
||||
<image src="@/static/images/my_icon1.png" class="test-icon" />
|
||||
<image src="@/static/images/my_icon2.png" class="test-icon" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 主题切换按钮 -->
|
||||
<view class="theme-switcher">
|
||||
<button @click="switchTheme" class="theme-btn">
|
||||
切换主题 (当前: {{ systemSkin === 2 ? '绿色' : '默认' }})
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 使用修复后的TabBar -->
|
||||
<RaisedTabbar :current="currentTab" @change="handleTabChange" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RaisedTabbar from './raised-tabbar.vue'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'TabbarTest',
|
||||
components: {
|
||||
RaisedTabbar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentTab: 0,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['shopCarLength', 'user']),
|
||||
systemSkin() {
|
||||
return this.user?.skin || 0
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleTabChange(index) {
|
||||
this.currentTab = index
|
||||
console.log('Tab切换到:', index)
|
||||
},
|
||||
switchTheme() {
|
||||
// 这里只是演示,实际项目中应该通过Vuex更新
|
||||
if (this.user) {
|
||||
this.$store.commit('updateUserSkin', this.systemSkin === 2 ? 0 : 2)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.test-page {
|
||||
min-height: 100vh;
|
||||
background: #f8f9fa;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.test-content {
|
||||
padding: 40rpx;
|
||||
}
|
||||
|
||||
.test-title {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: #333;
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.status-info {
|
||||
background: white;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 40rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
|
||||
text {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-bottom: 10rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-test {
|
||||
background: white;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 40rpx;
|
||||
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.icon-section {
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
margin-bottom: 20rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.icon-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20rpx;
|
||||
}
|
||||
|
||||
.test-icon {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border: 2rpx solid #eee;
|
||||
border-radius: 8rpx;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
|
||||
.theme-switcher {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.theme-btn {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 50rpx;
|
||||
padding: 20rpx 40rpx;
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
|
@ -173,12 +173,12 @@ import areaProductList from '@/components/area-product-list/index.vue'
|
|||
import { formatCurrency } from '@/util/index.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import RegionSelect from '@/components/region-select/index.vue'
|
||||
|
||||
import RaisedTabbar from '@/components/raised-tabbar.vue'
|
||||
export default {
|
||||
components: {
|
||||
noticePopup,
|
||||
znNewsPopup,
|
||||
'cl-tabbar': clTabbar,
|
||||
'cl-tabbar': RaisedTabbar,
|
||||
getTree,
|
||||
areaProductList,
|
||||
RegionSelect,
|
||||
|
|
|
@ -349,6 +349,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import RaisedTabbar from '@/components/raised-tabbar.vue'
|
||||
import clTabbar from '@/components/cl-tabbar.vue'
|
||||
import * as min from '@/config/balance.js'
|
||||
import * as api from '@/config/login.js'
|
||||
|
@ -357,7 +358,7 @@ import RegionSelect from '@/components/region-select/index.vue'
|
|||
|
||||
export default {
|
||||
components: {
|
||||
'cl-tabbar': clTabbar,
|
||||
'cl-tabbar': RaisedTabbar,
|
||||
RegionSelect,
|
||||
// talentList,
|
||||
},
|
||||
|
|
|
@ -47,11 +47,12 @@ import { fansCode as getShareCode } from '@/config/goods'
|
|||
import clTabbar from '@/components/cl-tabbar.vue'
|
||||
import DefaultSharePage from '@/components/share/DefaultSharePage.vue'
|
||||
import SpecialSharePage from '@/components/share/SpecialSharePage.vue'
|
||||
import RaisedTabbar from '@/components/raised-tabbar.vue'
|
||||
|
||||
export default {
|
||||
name: 'ShareQRCode',
|
||||
components: {
|
||||
'cl-tabbar': clTabbar,
|
||||
'cl-tabbar': RaisedTabbar,
|
||||
DefaultSharePage,
|
||||
SpecialSharePage,
|
||||
},
|
||||
|
@ -214,24 +215,7 @@ export default {
|
|||
|
||||
.tabbar {
|
||||
position: static;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
:v-deep .u-tabbar--fixed {
|
||||
height: 100px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 667px) {
|
||||
.tabbar {
|
||||
height: 70px !important;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-height: 812px) {
|
||||
.tabbar {
|
||||
height: 80px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -181,9 +181,11 @@
|
|||
<script>
|
||||
import * as api from '@/config/goods'
|
||||
import clTabbar from '@/components/cl-tabbar.vue'
|
||||
import RaisedTabbar from '@/components/raised-tabbar.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'cl-tabbar': clTabbar,
|
||||
'cl-tabbar': RaisedTabbar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -35,9 +35,10 @@ import * as apis from '@/config/index.js'
|
|||
import clTabbar from '@/components/cl-tabbar.vue'
|
||||
import * as ban from '@/config/balance.js'
|
||||
import areaProductList from '@/components/area-product-list/index.vue'
|
||||
import RaisedTabbar from '@/components/raised-tabbar.vue'
|
||||
export default {
|
||||
components: {
|
||||
'cl-tabbar': clTabbar,
|
||||
'cl-tabbar': RaisedTabbar,
|
||||
'area-product-list': areaProductList,
|
||||
},
|
||||
data() {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<svg t="1753425176636" class="icon" viewBox="65.5 65.5 893 893" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3699" width="256" height="256"><path d="M579.299 444.702h168.604V276.097H579.299v168.605z m84.302-120.765c20.137 0 36.463 16.325 36.463 36.462 0 20.137-16.326 36.462-36.463 36.462-20.138 0-36.462-16.325-36.462-36.462 0-20.138 16.324-36.462 36.462-36.462zM276.097 747.902h168.604V579.299H276.097v168.603z m84.302-120.763c20.137 0 36.462 16.324 36.462 36.462 0 20.137-16.325 36.463-36.462 36.463-20.137 0-36.461-16.326-36.461-36.463 0-20.138 16.324-36.462 36.461-36.462zM276.097 444.702h168.604V276.097H276.097v168.605z m84.302-120.765c20.137 0 36.462 16.325 36.462 36.462 0 20.137-16.325 36.462-36.462 36.462-20.137 0-36.461-16.325-36.461-36.462 0-20.138 16.324-36.462 36.461-36.462z" p-id="3700" fill="#f52a10"></path><path d="M512 65.5C265.405 65.5 65.5 265.405 65.5 512S265.405 958.5 512 958.5 958.5 758.595 958.5 512 758.595 65.5 512 65.5z m-21.657 708.201c0 10.959-8.885 19.844-19.844 19.844h-220.2c-10.959 0-19.844-8.885-19.844-19.844v-220.2c0-10.961 8.885-19.845 19.844-19.845h220.2c10.959 0 19.844 8.884 19.844 19.845v220.2z m0-303.202c0 10.959-8.885 19.844-19.844 19.844h-220.2c-10.959 0-19.844-8.885-19.844-19.844v-220.2c0-10.959 8.885-19.844 19.844-19.844h220.2c10.959 0 19.844 8.885 19.844 19.844v220.2z m203.385 323.046h-54.572v-59.074h54.572v59.074z m99.817-19.844c0 10.959-8.885 19.844-19.844 19.844h-30.362v-59.073h50.206v39.229z m0-88.84l-154.39-0.001v-37.69h-49.611v146.375h-36.043c-10.96 0-19.845-8.885-19.845-19.844v-220.2c0-10.961 8.885-19.845 19.845-19.845h140.227v98.603h49.611v-98.603h30.362c10.959 0 19.844 8.884 19.844 19.845v131.36z m0-214.362c0 10.959-8.885 19.844-19.844 19.844h-220.2c-10.96 0-19.845-8.885-19.845-19.844v-220.2c0-10.959 8.885-19.844 19.845-19.844h220.2c10.959 0 19.844 8.885 19.844 19.844v220.2z" p-id="3701" fill="#f52a10"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
|
@ -0,0 +1,169 @@
|
|||
<svg width="120" height="120" viewBox="0 0 120 120" xmlns="http://www.w3.org/2000/svg">
|
||||
<!-- 定义强烈的3D效果和渐变 -->
|
||||
<defs>
|
||||
<!-- 强烈的3D背景渐变 -->
|
||||
<radialGradient id="redBackground" cx="30%" cy="30%" r="80%">
|
||||
<stop offset="0%" style="stop-color:#ff8888;stop-opacity:1" />
|
||||
<stop offset="40%" style="stop-color:#ff4444;stop-opacity:1" />
|
||||
<stop offset="80%" style="stop-color:#cc0000;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#880000;stop-opacity:1" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 内圆3D效果 -->
|
||||
<radialGradient id="innerCircle" cx="25%" cy="25%" r="75%">
|
||||
<stop offset="0%" style="stop-color:#ffffff;stop-opacity:0.9" />
|
||||
<stop offset="30%" style="stop-color:#ffcccc;stop-opacity:0.7" />
|
||||
<stop offset="70%" style="stop-color:#ff9999;stop-opacity:0.5" />
|
||||
<stop offset="100%" style="stop-color:#ff6666;stop-opacity:0.3" />
|
||||
</radialGradient>
|
||||
|
||||
<!-- 线条渐变效果 -->
|
||||
<linearGradient id="lineGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" style="stop-color:#ffffff;stop-opacity:1" />
|
||||
<stop offset="50%" style="stop-color:#cccccc;stop-opacity:1" />
|
||||
<stop offset="100%" style="stop-color:#888888;stop-opacity:1" />
|
||||
</linearGradient>
|
||||
|
||||
<!-- 强烈外阴影 -->
|
||||
<filter id="strongShadow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feDropShadow dx="5" dy="5" stdDeviation="4" flood-color="#000000" flood-opacity="0.6"/>
|
||||
<feDropShadow dx="2" dy="2" stdDeviation="2" flood-color="#660000" flood-opacity="0.4"/>
|
||||
</filter>
|
||||
|
||||
<!-- 内发光效果 -->
|
||||
<filter id="innerGlow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur stdDeviation="2" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- 线条发光效果 -->
|
||||
<filter id="lineGlow" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feGaussianBlur stdDeviation="1" result="coloredBlur"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="coloredBlur"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- 3D凸起效果 -->
|
||||
<filter id="emboss" x="-50%" y="-50%" width="200%" height="200%">
|
||||
<feConvolveMatrix order="3" kernelMatrix="
|
||||
-2 -1 0
|
||||
-1 1 1
|
||||
0 1 2" result="emboss"/>
|
||||
<feOffset dx="1" dy="1" result="offset"/>
|
||||
<feFlood flood-color="#ffffff" flood-opacity="0.5"/>
|
||||
<feComposite in2="offset" operator="in" result="emboss2"/>
|
||||
<feMerge>
|
||||
<feMergeNode in="emboss2"/>
|
||||
<feMergeNode in="SourceGraphic"/>
|
||||
</feMerge>
|
||||
</filter>
|
||||
|
||||
<!-- 圆形裁剪 -->
|
||||
<clipPath id="circleClip">
|
||||
<circle cx="60" cy="60" r="48"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<!-- 最外层阴影圆 -->
|
||||
<circle cx="63" cy="63" r="57" fill="#000000" opacity="0.3"/>
|
||||
|
||||
<!-- 主背景圆 - 强烈3D效果 -->
|
||||
<circle cx="60" cy="60" r="55" fill="url(#redBackground)" filter="url(#strongShadow)"/>
|
||||
|
||||
<!-- 内圆 - 3D凹陷效果 -->
|
||||
<circle cx="60" cy="60" r="48" fill="url(#innerCircle)" stroke="url(#lineGradient)" stroke-width="2" filter="url(#emboss)"/>
|
||||
|
||||
<!-- 二维码线条部分 -->
|
||||
<g clip-path="url(#circleClip)" filter="url(#lineGlow)">
|
||||
|
||||
<!-- 左上角定位符 - 线条版本 -->
|
||||
<g stroke="url(#lineGradient)" stroke-width="2.5" fill="none">
|
||||
<circle cx="35" cy="35" r="12" opacity="0.9"/>
|
||||
<circle cx="35" cy="35" r="8" opacity="0.8"/>
|
||||
<circle cx="35" cy="35" r="4" opacity="0.7"/>
|
||||
<circle cx="35" cy="35" r="1" fill="url(#lineGradient)" opacity="0.9"/>
|
||||
</g>
|
||||
|
||||
<!-- 右上角定位符 - 线条版本 -->
|
||||
<g stroke="url(#lineGradient)" stroke-width="2.5" fill="none">
|
||||
<circle cx="85" cy="35" r="12" opacity="0.9"/>
|
||||
<circle cx="85" cy="35" r="8" opacity="0.8"/>
|
||||
<circle cx="85" cy="35" r="4" opacity="0.7"/>
|
||||
<circle cx="85" cy="35" r="1" fill="url(#lineGradient)" opacity="0.9"/>
|
||||
</g>
|
||||
|
||||
<!-- 左下角定位符 - 线条版本 -->
|
||||
<g stroke="url(#lineGradient)" stroke-width="2.5" fill="none">
|
||||
<circle cx="35" cy="85" r="12" opacity="0.9"/>
|
||||
<circle cx="35" cy="85" r="8" opacity="0.8"/>
|
||||
<circle cx="35" cy="85" r="4" opacity="0.7"/>
|
||||
<circle cx="35" cy="85" r="1" fill="url(#lineGradient)" opacity="0.9"/>
|
||||
</g>
|
||||
|
||||
<!-- 数据线条 - 环形分布 -->
|
||||
<g stroke="url(#lineGradient)" stroke-width="2" fill="none" opacity="0.8">
|
||||
<!-- 主要数据线条 -->
|
||||
<path d="M 25,60 Q 35,35 60,25" stroke-width="1.5"/>
|
||||
<path d="M 60,25 Q 85,35 95,60" stroke-width="1.5"/>
|
||||
<path d="M 95,60 Q 85,85 60,95" stroke-width="1.5"/>
|
||||
<path d="M 60,95 Q 35,85 25,60" stroke-width="1.5"/>
|
||||
|
||||
<!-- 交叉线条 -->
|
||||
<path d="M 42,42 L 78,78" stroke-width="1"/>
|
||||
<path d="M 78,42 L 42,78" stroke-width="1"/>
|
||||
|
||||
<!-- 环形线条 -->
|
||||
<circle cx="60" cy="60" r="20" stroke-width="1" opacity="0.6"/>
|
||||
<circle cx="60" cy="60" r="30" stroke-width="1" opacity="0.5"/>
|
||||
<circle cx="60" cy="60" r="40" stroke-width="1" opacity="0.4"/>
|
||||
</g>
|
||||
|
||||
<!-- 数据点线条 -->
|
||||
<g stroke="url(#lineGradient)" stroke-width="1.5" fill="none" opacity="0.7">
|
||||
<!-- 径向线条 -->
|
||||
<line x1="60" y1="30" x2="60" y2="20" stroke-width="2"/>
|
||||
<line x1="90" y1="60" x2="100" y2="60" stroke-width="2"/>
|
||||
<line x1="60" y1="90" x2="60" y2="100" stroke-width="2"/>
|
||||
<line x1="30" y1="60" x2="20" y2="60" stroke-width="2"/>
|
||||
|
||||
<!-- 对角线条 -->
|
||||
<line x1="77" y1="43" x2="85" y2="35" stroke-width="1.5"/>
|
||||
<line x1="77" y1="77" x2="85" y2="85" stroke-width="1.5"/>
|
||||
<line x1="43" y1="77" x2="35" y2="85" stroke-width="1.5"/>
|
||||
<line x1="43" y1="43" x2="35" y2="35" stroke-width="1.5"/>
|
||||
|
||||
<!-- 短线条装饰 -->
|
||||
<line x1="50" y1="35" x2="55" y2="30"/>
|
||||
<line x1="70" y1="35" x2="65" y2="30"/>
|
||||
<line x1="85" y1="50" x2="90" y2="55"/>
|
||||
<line x1="85" y1="70" x2="90" y2="65"/>
|
||||
<line x1="70" y1="85" x2="65" y2="90"/>
|
||||
<line x1="50" y1="85" x2="55" y2="90"/>
|
||||
<line x1="35" y1="70" x2="30" y2="65"/>
|
||||
<line x1="35" y1="50" x2="30" y2="55"/>
|
||||
</g>
|
||||
|
||||
<!-- 中心对齐标记 - 线条版本 -->
|
||||
<g stroke="url(#lineGradient)" stroke-width="2" fill="none" filter="url(#innerGlow)">
|
||||
<circle cx="60" cy="60" r="6" opacity="0.9"/>
|
||||
<circle cx="60" cy="60" r="3" opacity="0.8"/>
|
||||
<circle cx="60" cy="60" r="1" fill="url(#lineGradient)" opacity="1"/>
|
||||
<!-- 十字标记 -->
|
||||
<line x1="54" y1="60" x2="66" y2="60" stroke-width="1"/>
|
||||
<line x1="60" y1="54" x2="60" y2="66" stroke-width="1"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
<!-- 强烈高光效果 -->
|
||||
<ellipse cx="42" cy="35" rx="20" ry="6" fill="rgba(255,255,255,0.7)" transform="rotate(-35 42 35)" filter="url(#innerGlow)"/>
|
||||
<ellipse cx="35" cy="42" rx="6" ry="20" fill="rgba(255,255,255,0.4)" transform="rotate(-35 35 42)"/>
|
||||
|
||||
<!-- 边缘高光 -->
|
||||
<circle cx="60" cy="60" r="54" stroke="rgba(255,255,255,0.3)" stroke-width="1" fill="none"/>
|
||||
<circle cx="60" cy="60" r="47" stroke="rgba(255,255,255,0.2)" stroke-width="1" fill="none"/>
|
||||
</svg>
|
After Width: | Height: | Size: 7.1 KiB |
Loading…
Reference in New Issue