feat: carousel and set text color according to bg color
This commit is contained in:
23
project.private.config.json
Normal file
23
project.private.config.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"libVersion": "3.9.0",
|
||||||
|
"projectname": "playBallTogether",
|
||||||
|
"condition": {},
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": true,
|
||||||
|
"coverView": true,
|
||||||
|
"lazyloadPlaceholderEnable": false,
|
||||||
|
"skylineRenderEnable": false,
|
||||||
|
"preloadBackgroundData": false,
|
||||||
|
"autoAudits": false,
|
||||||
|
"useApiHook": true,
|
||||||
|
"useApiHostProcess": true,
|
||||||
|
"showShadowRootInWxmlPanel": false,
|
||||||
|
"useStaticServer": false,
|
||||||
|
"useLanDebug": false,
|
||||||
|
"showES6CompileOption": false,
|
||||||
|
"compileHotReLoad": true,
|
||||||
|
"checkInvalidKey": true,
|
||||||
|
"ignoreDevUnusedFiles": true,
|
||||||
|
"bigPackageSizeSupport": false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export default defineAppConfig({
|
export default defineAppConfig({
|
||||||
pages: [
|
pages: [
|
||||||
'pages/index/index'
|
'pages/index/index',
|
||||||
|
'pages/detail/index',
|
||||||
],
|
],
|
||||||
window: {
|
window: {
|
||||||
backgroundTextStyle: 'light',
|
backgroundTextStyle: 'light',
|
||||||
|
|||||||
4
src/pages/detail/index.config.ts
Normal file
4
src/pages/detail/index.config.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export default definePageConfig({
|
||||||
|
navigationBarTitleText: '球局详情',
|
||||||
|
navigationStyle: 'custom',
|
||||||
|
})
|
||||||
90
src/pages/detail/index.scss
Normal file
90
src/pages/detail/index.scss
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
.detail-page {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.custom-navbar {
|
||||||
|
height: 56px; /* 通常与原生导航栏高度一致 */
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
// background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
padding-top: 36px; /* 适配状态栏 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-navigator {
|
||||||
|
height: 30px;
|
||||||
|
width: 80px;
|
||||||
|
border-radius: 15px;
|
||||||
|
position: absolute;
|
||||||
|
left: 12px;
|
||||||
|
border: 1px solid #888;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.detail-navigator-back, .detail-navigator-icon {
|
||||||
|
height: 20px;
|
||||||
|
width: 50%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
& > svg {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-page-bg {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
background-size: cover;
|
||||||
|
filter: blur(40px);
|
||||||
|
transform: scale(1.5);
|
||||||
|
z-index: -2;
|
||||||
|
width: calc(100% + 20px);
|
||||||
|
height: calc(100% + 20px);
|
||||||
|
margin: -10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-page-bg-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
z-index: -1;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-swiper {
|
||||||
|
height: 240px;
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-swiper-item {
|
||||||
|
overflow: visible;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.detail-swiper-item-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-radius: 12px;
|
||||||
|
transition: transform 0.5s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-text {
|
||||||
|
font-size: 40rpx;
|
||||||
|
margin-top: 20px;
|
||||||
|
transition: color 0.3s ease-in;
|
||||||
|
}
|
||||||
|
}
|
||||||
117
src/pages/detail/index.tsx
Normal file
117
src/pages/detail/index.tsx
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { View, Text, Button, Swiper, SwiperItem, Image } from '@tarojs/components'
|
||||||
|
import { Cell, Avatar, Progress } from '@nutui/nutui-react-taro'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
// 导入API服务
|
||||||
|
import demoApi from '../../services/demoApi'
|
||||||
|
import commonApi from '../../services/commonApi'
|
||||||
|
import {
|
||||||
|
useUserStats,
|
||||||
|
useUserActions
|
||||||
|
} from '../../store/userStore'
|
||||||
|
import { getTextColorOnImage } from '../../utils/processImage'
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
|
const images = [
|
||||||
|
'http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/1a35ebbf-2361-44da-b338-7608561d0b31.png',
|
||||||
|
'http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/cf5a82ba-90af-4138-a1b3-9119adcde9e0.png',
|
||||||
|
'http://bimwe.oss-cn-shanghai.aliyuncs.com/front/ball/images/49d7cdf0-b03c-4a0f-91c6-e7778080cfcd.png'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function Index() {
|
||||||
|
// 使用Zustand store
|
||||||
|
// const userStats = useUserStats()
|
||||||
|
// const { incrementRequestCount, resetUserStats } = useUserActions()
|
||||||
|
|
||||||
|
const [current, setCurrent] = useState(0)
|
||||||
|
const [colors, setColors] = useState<string []>([])
|
||||||
|
|
||||||
|
// 本地状态管理
|
||||||
|
const [loading, setLoading] = useState(false)
|
||||||
|
const [userProfile, setUserProfile] = useState<any>(null)
|
||||||
|
const [interests, setInterests] = useState<string[]>([])
|
||||||
|
|
||||||
|
// 页面加载时获取数据
|
||||||
|
useEffect(() => {
|
||||||
|
initializeData()
|
||||||
|
calcBgMainColors()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
const initializeData = async () => {
|
||||||
|
try {
|
||||||
|
// 获取推荐的兴趣爱好
|
||||||
|
const interestsRes = await demoApi.getRecommendedInterests()
|
||||||
|
if (interestsRes.success) {
|
||||||
|
setInterests(interestsRes.data || [])
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log('获取初始数据失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const calcBgMainColors = async () => {
|
||||||
|
const textcolors: string[] = []
|
||||||
|
for (const index in images) {
|
||||||
|
const { textColor } = await getTextColorOnImage(images[index])
|
||||||
|
textcolors[index] = textColor
|
||||||
|
}
|
||||||
|
setColors(textcolors)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className='detail-page'>
|
||||||
|
<view className="custom-navbar">
|
||||||
|
<View className='detail-navigator'>
|
||||||
|
<View className='detail-navigator-back'>
|
||||||
|
<svg width="8" height="14" viewBox="0 0 8 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M7 1L1 7L7 13" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
<View className='detail-navigator-icon'>
|
||||||
|
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M16.9106 10.4998L16.7487 6.92161C16.7208 6.30199 17.1953 5.79401 17.8708 5.79401C18.5462 5.79401 19.0319 6.30199 18.9984 6.92161L18.8197 10.4998C18.7862 11.0413 18.3787 11.3985 17.8652 11.3985C17.3404 11.3985 16.9329 11.019 16.9106 10.4998ZM16.7599 12.822C16.7599 12.2135 17.2623 11.8395 17.8763 11.8395C18.4848 11.8395 18.9816 12.2135 18.9816 12.822C18.9816 13.4361 18.4848 13.8101 17.8763 13.8101C17.2623 13.8101 16.7599 13.4361 16.7599 12.822Z" fill="white"/>
|
||||||
|
<path d="M8.65674 10.3268V9.50059C8.65674 7.27329 9.93506 5.93914 12.1512 5.93914C14.3673 5.93914 15.6401 7.27887 15.6401 9.50059V10.3268C15.6401 12.5373 14.3673 13.8603 12.1512 13.8603C9.93506 13.8603 8.65674 12.5317 8.65674 10.3268ZM10.8617 9.48384V10.3212C10.8617 11.4432 11.3362 12.0907 12.1512 12.0907C12.9662 12.0907 13.4351 11.4432 13.4351 10.3212V9.48384C13.4351 8.36182 12.9662 7.7087 12.1512 7.7087C11.3362 7.7087 10.8617 8.36182 10.8617 9.48384Z" fill="white"/>
|
||||||
|
<path d="M1 10.3323V9.41127C1 7.29562 2.32857 5.93914 4.45539 5.93914C5.2983 5.93914 6.07981 6.16243 6.6492 6.52527C7.20742 6.87137 7.56468 7.34586 7.56468 7.83151C7.56468 8.34507 7.20184 8.70233 6.68269 8.70233C6.4594 8.70233 6.27519 8.63535 6.1133 8.5237C5.66115 8.22226 5.30388 7.78127 4.62844 7.78127C3.67388 7.78127 3.20497 8.36182 3.20497 9.5285V10.3268C3.20497 11.4767 3.67388 12.0852 4.57261 12.0852C5.24248 12.0852 5.69464 11.6944 5.69464 11.1306V10.9743H5.35412C4.80148 10.9743 4.50005 10.7063 4.50005 10.2207C4.50005 9.73504 4.7959 9.48384 5.35412 9.48384H6.56546C7.40279 9.48384 7.76564 9.83552 7.76564 10.6338V10.9352C7.76564 12.7048 6.47057 13.8603 4.47772 13.8603C2.28949 13.8603 1 12.5373 1 10.3323Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{/* <view className="navbar-title">我的自定义标题</view> */}
|
||||||
|
</view>
|
||||||
|
<View className='detail-page-bg' style={{ backgroundImage: `url(${images[current]})` }} />
|
||||||
|
<View className='detail-page-bg-text' />
|
||||||
|
<Swiper
|
||||||
|
className='detail-swiper'
|
||||||
|
indicatorDots={false}
|
||||||
|
circular
|
||||||
|
nextMargin="20px"
|
||||||
|
onChange={(e) => { setCurrent(e.detail.current) }}
|
||||||
|
>
|
||||||
|
{images.map((imageUrl, index) => (
|
||||||
|
<SwiperItem
|
||||||
|
key={index}
|
||||||
|
className='detail-swiper-item'
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
src={imageUrl}
|
||||||
|
mode="aspectFill"
|
||||||
|
className='detail-swiper-item-image'
|
||||||
|
style={{
|
||||||
|
transform: index !== current ? 'scale(0.8) translateX(-12%)' : 'scale(0.95)', // 前后图缩小
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SwiperItem>
|
||||||
|
))}
|
||||||
|
</Swiper>
|
||||||
|
<Text className='detail-text' style={{ color: colors[current] }}>
|
||||||
|
Five feet from the bed was an earthen wall that had suffered from numerous cracks due to the passage of time. From the other side of the wall came the nagging voice of his mother and the occasional deep breathing of his father who was smoking his pipe.
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Index
|
||||||
@@ -5,8 +5,8 @@ import Taro from '@tarojs/taro'
|
|||||||
// 导入API服务
|
// 导入API服务
|
||||||
import demoApi from '../../services/demoApi'
|
import demoApi from '../../services/demoApi'
|
||||||
import commonApi from '../../services/commonApi'
|
import commonApi from '../../services/commonApi'
|
||||||
import {
|
import {
|
||||||
useUserStats,
|
useUserStats,
|
||||||
useUserActions
|
useUserActions
|
||||||
} from '../../store/userStore'
|
} from '../../store/userStore'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
@@ -15,7 +15,7 @@ function Index() {
|
|||||||
// 使用Zustand store
|
// 使用Zustand store
|
||||||
const userStats = useUserStats()
|
const userStats = useUserStats()
|
||||||
const { incrementRequestCount, resetUserStats } = useUserActions()
|
const { incrementRequestCount, resetUserStats } = useUserActions()
|
||||||
|
|
||||||
// 本地状态管理
|
// 本地状态管理
|
||||||
const [loading, setLoading] = useState(false)
|
const [loading, setLoading] = useState(false)
|
||||||
const [userProfile, setUserProfile] = useState<any>(null)
|
const [userProfile, setUserProfile] = useState<any>(null)
|
||||||
@@ -43,19 +43,19 @@ function Index() {
|
|||||||
const handleGetUserProfile = async () => {
|
const handleGetUserProfile = async () => {
|
||||||
console.log('获取用户信息...');
|
console.log('获取用户信息...');
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await demoApi.getUserProfile()
|
const response = await demoApi.getUserProfile()
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
setUserProfile(response.data)
|
setUserProfile(response.data)
|
||||||
incrementRequestCount()
|
incrementRequestCount()
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '获取用户信息成功',
|
title: '获取用户信息成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('用户信息:', response.data)
|
console.log('用户信息:', response.data)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -64,7 +64,7 @@ function Index() {
|
|||||||
title: '获取失败,使用模拟数据',
|
title: '获取失败,使用模拟数据',
|
||||||
icon: 'none'
|
icon: 'none'
|
||||||
})
|
})
|
||||||
|
|
||||||
// 模拟数据
|
// 模拟数据
|
||||||
setUserProfile({
|
setUserProfile({
|
||||||
id: '123',
|
id: '123',
|
||||||
@@ -83,7 +83,7 @@ function Index() {
|
|||||||
const handleSubmitStats = async () => {
|
const handleSubmitStats = async () => {
|
||||||
console.log('提交统计数据...');
|
console.log('提交统计数据...');
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await commonApi.submitForm('userStats', [
|
const response = await commonApi.submitForm('userStats', [
|
||||||
{
|
{
|
||||||
@@ -97,21 +97,21 @@ function Index() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
incrementRequestCount()
|
incrementRequestCount()
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '统计数据提交成功',
|
title: '统计数据提交成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('提交结果:', response.data)
|
console.log('提交结果:', response.data)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('提交统计数据失败:', error)
|
console.error('提交统计数据失败:', error)
|
||||||
incrementRequestCount() // 即使失败也计数,用于演示
|
incrementRequestCount() // 即使失败也计数,用于演示
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '网络模拟提交成功',
|
title: '网络模拟提交成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
@@ -125,7 +125,7 @@ function Index() {
|
|||||||
const handleSubmitFeedback = async () => {
|
const handleSubmitFeedback = async () => {
|
||||||
console.log('提交用户反馈...');
|
console.log('提交用户反馈...');
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await demoApi.submitFeedback({
|
const response = await demoApi.submitFeedback({
|
||||||
matchId: 'demo_match_' + Date.now(),
|
matchId: 'demo_match_' + Date.now(),
|
||||||
@@ -134,21 +134,21 @@ function Index() {
|
|||||||
aspects: ['场地环境', '服务质量', '价格合理'],
|
aspects: ['场地环境', '服务质量', '价格合理'],
|
||||||
comments: `用户反馈 - 请求次数: ${userStats.requestCount + 1},体验良好!`
|
comments: `用户反馈 - 请求次数: ${userStats.requestCount + 1},体验良好!`
|
||||||
})
|
})
|
||||||
|
|
||||||
if (response.success) {
|
if (response.success) {
|
||||||
incrementRequestCount()
|
incrementRequestCount()
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '反馈提交成功',
|
title: '反馈提交成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('反馈结果:', response.data)
|
console.log('反馈结果:', response.data)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('提交反馈失败:', error)
|
console.error('提交反馈失败:', error)
|
||||||
incrementRequestCount() // 即使失败也计数,用于演示
|
incrementRequestCount() // 即使失败也计数,用于演示
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '网络模拟提交成功',
|
title: '网络模拟提交成功',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
@@ -163,15 +163,22 @@ function Index() {
|
|||||||
console.log('重置所有数据...');
|
console.log('重置所有数据...');
|
||||||
resetUserStats()
|
resetUserStats()
|
||||||
setUserProfile(null)
|
setUserProfile(null)
|
||||||
|
|
||||||
Taro.showToast({
|
Taro.showToast({
|
||||||
title: '数据已重置',
|
title: '数据已重置',
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleDetail = () => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: '/pages/detail/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className='index-page'>
|
<View className='index-page'>
|
||||||
|
<Button onClick={handleDetail}>球局详情</Button>
|
||||||
{/* 页面标题 */}
|
{/* 页面标题 */}
|
||||||
<View className='page-header'>
|
<View className='page-header'>
|
||||||
<Text className='page-title'>API 请求演示</Text>
|
<Text className='page-title'>API 请求演示</Text>
|
||||||
@@ -181,9 +188,9 @@ function Index() {
|
|||||||
{/* 用户信息卡片 */}
|
{/* 用户信息卡片 */}
|
||||||
<View className='user-card'>
|
<View className='user-card'>
|
||||||
<View className='user-header'>
|
<View className='user-header'>
|
||||||
<Avatar
|
<Avatar
|
||||||
size="large"
|
size="large"
|
||||||
src={userProfile?.avatar || ''}
|
src={userProfile?.avatar || ''}
|
||||||
style={{ backgroundColor: '#fa2c19' }}
|
style={{ backgroundColor: '#fa2c19' }}
|
||||||
>
|
>
|
||||||
{userProfile?.nickname?.charAt(0) || 'U'}
|
{userProfile?.nickname?.charAt(0) || 'U'}
|
||||||
@@ -205,17 +212,17 @@ function Index() {
|
|||||||
{/* 统计数据 */}
|
{/* 统计数据 */}
|
||||||
<View className='stats-section'>
|
<View className='stats-section'>
|
||||||
<Text className='section-title'>📊 API 请求统计</Text>
|
<Text className='section-title'>📊 API 请求统计</Text>
|
||||||
|
|
||||||
<Cell title="API 请求次数" extra={userStats.requestCount} />
|
<Cell title="API 请求次数" extra={userStats.requestCount} />
|
||||||
<Cell title="创建的比赛" extra={userStats.matchesCreated} />
|
<Cell title="创建的比赛" extra={userStats.matchesCreated} />
|
||||||
<Cell title="参加的比赛" extra={userStats.matchesJoined} />
|
<Cell title="参加的比赛" extra={userStats.matchesJoined} />
|
||||||
<Cell
|
<Cell
|
||||||
title="最后活跃时间"
|
title="最后活跃时间"
|
||||||
extra={new Date(userStats.lastActiveTime).toLocaleTimeString()}
|
extra={new Date(userStats.lastActiveTime).toLocaleTimeString()}
|
||||||
/>
|
/>
|
||||||
{interests.length > 0 && (
|
{interests.length > 0 && (
|
||||||
<Cell
|
<Cell
|
||||||
title="推荐兴趣"
|
title="推荐兴趣"
|
||||||
extra={interests.slice(0, 2).join(', ')}
|
extra={interests.slice(0, 2).join(', ')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -224,10 +231,10 @@ function Index() {
|
|||||||
{/* API 请求按钮区域 */}
|
{/* API 请求按钮区域 */}
|
||||||
<View className='action-section'>
|
<View className='action-section'>
|
||||||
<Text className='section-title'>🚀 API 请求功能</Text>
|
<Text className='section-title'>🚀 API 请求功能</Text>
|
||||||
|
|
||||||
<View className='button-group'>
|
<View className='button-group'>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onClick={handleGetUserProfile}
|
onClick={handleGetUserProfile}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
@@ -236,8 +243,8 @@ function Index() {
|
|||||||
{loading ? '请求中...' : '获取用户信息'}
|
{loading ? '请求中...' : '获取用户信息'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="default"
|
type="default"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onClick={handleSubmitStats}
|
onClick={handleSubmitStats}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
@@ -246,8 +253,8 @@ function Index() {
|
|||||||
{loading ? '提交中...' : '提交统计数据'}
|
{loading ? '提交中...' : '提交统计数据'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="default"
|
type="default"
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onClick={handleSubmitFeedback}
|
onClick={handleSubmitFeedback}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
@@ -256,8 +263,8 @@ function Index() {
|
|||||||
{loading ? '提交中...' : '提交用户反馈'}
|
{loading ? '提交中...' : '提交用户反馈'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="warn"
|
type="warn"
|
||||||
onClick={handleResetAllData}
|
onClick={handleResetAllData}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
className="custom-button warning-btn"
|
className="custom-button warning-btn"
|
||||||
|
|||||||
33
src/utils/processImage.ts
Normal file
33
src/utils/processImage.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
export async function getTextColorOnImage(url) {
|
||||||
|
let canvas
|
||||||
|
const width = 100
|
||||||
|
const height = 50
|
||||||
|
try {
|
||||||
|
// 1. 创建离屏Canvas
|
||||||
|
canvas = wx.createOffscreenCanvas({ type: '2d', width, height })
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
|
||||||
|
// 2. 加载图片
|
||||||
|
const img = canvas.createImage()
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
img.onload = resolve
|
||||||
|
img.src = url
|
||||||
|
})
|
||||||
|
|
||||||
|
// 3. 绘制并分析图像
|
||||||
|
ctx.drawImage(img, 0, 0, width, height)
|
||||||
|
|
||||||
|
// TODO: 增加取样,提高精确性
|
||||||
|
const pixelData = ctx.getImageData(10, 10, 1, 1).data
|
||||||
|
|
||||||
|
// 4. 计算文字颜色
|
||||||
|
const brightness = (pixelData[0] * 2126 + pixelData[1] * 7152 + pixelData[2] * 722) / 10000
|
||||||
|
return { textColor: brightness > 128 ? 'black' : 'white' }
|
||||||
|
} finally {
|
||||||
|
// 释放资源
|
||||||
|
if (canvas) {
|
||||||
|
canvas.width = 0;
|
||||||
|
canvas.height = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user