feat:选择文字

This commit is contained in:
2025-06-30 17:14:03 +08:00
parent 23ad49d333
commit 654afced6f
10 changed files with 129 additions and 39 deletions
@@ -37,9 +37,9 @@
.word-list { .word-list {
display: grid; display: grid;
grid-template-columns: repeat(7, 72rpx); grid-template-columns: repeat(6, 72rpx);
grid-template-rows: repeat(20, 72rpx); grid-template-rows: repeat(1, 72rpx);
gap: 24rpx; gap: 40rpx;
justify-content: center; justify-content: center;
// box-shadow: 0 0 -10rpx rgba(0, 0, 0, 0.2); // box-shadow: 0 0 -10rpx rgba(0, 0, 0, 0.2);
// align-items: flex-start; // align-items: flex-start;
@@ -49,12 +49,18 @@
height: 72rpx; height: 72rpx;
border-radius: 16rpx; border-radius: 16rpx;
background: rgba(240, 240, 240, 1); background: rgba(240, 240, 240, 1);
box-shadow: 3.9px 3.9px 5.2px rgba(0, 0, 0, 0.15); box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.15);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 28rpx; font-size: 28rpx;
color: #141414; color: #141414;
&.selected {
background: rgb(147, 211, 51);
color: #ffffff;
box-shadow: 0px 2px 4px rgba(147, 211, 51, 0.15);
}
} }
} }
@@ -76,4 +82,10 @@
} }
} }
.btn-area {
display: flex;
justify-content: space-between;
margin-bottom: 96rpx;
}
} }
@@ -14,20 +14,20 @@ Component({
type: Number, type: Number,
value: 0, value: 0,
}, },
selectedWords: {
type: Array,
value: [],
},
}, },
/** /**
* 组件的初始数据 * 组件的初始数据
*/ */
data: { data: {
wordList: WORDS, wordList: WORDS,
selectedWords: [],
}, },
lifetimes: { lifetimes: {
ready() { ready() {
// setTimeout(() => { console.log('selectedWords', this.data.selectedWords);
// console.log('111');
// this.selectComponent('#tabs').resize();
// }, 1000);
}, },
}, },
/** /**
@@ -38,8 +38,37 @@ Component({
this.triggerEvent('onClose'); this.triggerEvent('onClose');
}, },
onChange() {
this.triggerEvent('onChange', { selectedWords: this.data.selectedWords });
},
onTabChange(e: WechatMiniprogram.CustomEvent) { onTabChange(e: WechatMiniprogram.CustomEvent) {
this.setData({ currentTab: e.detail }); this.setData({ currentTab: e.detail });
}, },
onWordClick(e: WechatMiniprogram.TouchEvent) {
const { word } = e.currentTarget.dataset;
const { selectedWords } = this.data;
let newSelectedWords = selectedWords as string[];
// 如果是已选中的文字,直接取消选中
if (newSelectedWords.includes(word)) {
newSelectedWords = newSelectedWords.filter((item) => item !== word);
} else {
// 如果是未选中的文字,先判断是否已选满6个
if (newSelectedWords.length >= 6) {
wx.showToast({
title: '最多选择6个字',
icon: 'none',
});
return;
}
newSelectedWords = [...newSelectedWords, word];
}
this.setData({
selectedWords: newSelectedWords,
});
},
}, },
}); });
@@ -1,9 +1,13 @@
<wxs module="wxs" src="./word-picker.wxs"></wxs>
<van-popup <van-popup
show="{{ show }}" show="{{ show }}"
bind:close="onClose" bind:close="onClose"
round round
close-on-click-overlay="{{false}}"
safe-area-inset-bottom="{{true}}"
position="bottom" position="bottom"
custom-style="height: 65%" custom-style="height: 70%"
custom-class="word-picker"> custom-class="word-picker">
<view class="word-picker-title">请选择文字</view> <view class="word-picker-title">请选择文字</view>
<van-tabs <van-tabs
@@ -21,14 +25,14 @@
bind:change="onTabChange"> bind:change="onTabChange">
<van-tab <van-tab
wx:for="{{wordList}}" wx:for="{{wordList}}"
wx:for-index="wordIndex" wx:for-index="categoryIndex"
wx:key="wordIndex" wx:key="categoryIndex"
title="{{wordList[wordIndex].categoryName}}"> title="{{wordList[categoryIndex].categoryName}}">
<view class="word-list-wrapper"> <view class="word-list-wrapper">
<view class="word-list"> <view class="word-list">
<view <view
class="word-item" class="word-item {{wxs.isSelected(selectedWords, item) ? 'selected' : ''}}"
wx:for="{{wordList[wordIndex].words}}" wx:for="{{wordList[categoryIndex].words}}"
wx:key="index" wx:key="index"
data-word="{{item}}" data-word="{{item}}"
bind:tap="onWordClick"> bind:tap="onWordClick">
@@ -46,7 +50,19 @@
class="selected-word-text" class="selected-word-text"
wx:for="{{selectedWords}}" wx:for="{{selectedWords}}"
wx:key="index" wx:key="index"
>{{item}}</text >{{item}}{{index !== selectedWords.length - 1 ? '、' : ''}}</text
> >
</view> </view>
<view class="btn-area">
<toy-button
type="primary"
bind:click="onChange"
width="420rpx"
disabled="{{selectedWords.length <= 0}}">
(已选{{selectedWords.length}}个) 确定
</toy-button>
<toy-button type="white" bind:click="onClose" width="220rpx">
取消
</toy-button>
</view>
</van-popup> </van-popup>
@@ -0,0 +1,8 @@
module.exports = {
isSelected: function (selectedWords, word) {
if (selectedWords && selectedWords.length > 0) {
return selectedWords.indexOf(word) !== -1;
}
return false;
},
};
+13 -6
View File
@@ -16,7 +16,6 @@ Page({
currentColor: '', currentColor: '',
showIntroductionPopup: false, showIntroductionPopup: false,
showSelectWordPopup: false, // 选择文字弹窗 showSelectWordPopup: false, // 选择文字弹窗
selectedWords: [] as string[],
}, },
onLoad() { onLoad() {
@@ -295,15 +294,23 @@ Page({
showSelectWordPopup: true, showSelectWordPopup: true,
}); });
}, },
closeSelectWordPopup() { closeSelectWordPopup() {
this.setData({ this.setData({
showSelectWordPopup: false, showSelectWordPopup: false,
}); });
}, },
onSelectWord(e: WechatMiniprogram.CustomEvent) {
const { words } = e.detail; onChangeWord(e: WechatMiniprogram.CustomEvent) {
this.setData({ const selectedWords = e.detail.selectedWords as string[];
selectedWords: words, console.log('selectedWords:', selectedWords);
});
const colors = [...WATER_COLORS.basic12];
const cardList = selectedWords.map((word, index) => ({
color: colors[index].hex,
word,
}));
this.setData({ showSelectWordPopup: false });
this.drawCanvas(cardList);
}, },
}); });
+3 -2
View File
@@ -44,7 +44,7 @@
</toy-button> </toy-button>
<toy-button <toy-button
disabled="{{cardList.length <= 0}}" disabled="{{cardList.length <= 0}}"
type="green" type="white"
bind:click="clearCardList" bind:click="clearCardList"
width="220rpx" width="220rpx"
icon="clear" icon="clear"
@@ -73,8 +73,9 @@
bind:onChange="onChangeColor" /> bind:onChange="onChangeColor" />
<word-picker <word-picker
show="{{showSelectWordPopup}}" show="{{showSelectWordPopup}}"
selectedWords="{{selectedWords}}"
bind:onClose="closeSelectWordPopup" bind:onClose="closeSelectWordPopup"
bind:onSelect="onSelectWord" /> bind:onChange="onChangeWord" />
</view> </view>
<view class="btn-area"> <view class="btn-area">
<toy-button <toy-button
+11 -9
View File
@@ -27,11 +27,11 @@ wx-button:not([size=mini]) {
&--primary { &--primary {
background: rgba(255, 215, 25, 1); background: rgba(255, 215, 25, 1);
box-shadow: 0px 10rpx 4rpx #DBB917; box-shadow: 0px 10rpx 2rpx #DBB917;
&.disabled { &.disabled {
background: rgba(255, 215, 25, 0.5); background: rgba(255, 215, 25, 0.5);
box-shadow: 0px 10rpx 4rpx rgba(219, 185, 23, 0.5); box-shadow: 0px 10rpx 2rpx rgba(219, 185, 23, 0.5);
} }
&.active { &.active {
@@ -43,11 +43,11 @@ wx-button:not([size=mini]) {
&--green { &--green {
background: #93d333; background: #93d333;
box-shadow: 0px 10rpx 4rpx rgba(121, 185, 21, 1); box-shadow: 0px 10rpx 2rpx rgba(121, 185, 21, 1);
&.disabled { &.disabled {
background: rgba(147, 211, 51, 0.5); background: rgba(147, 211, 51, 0.5);
box-shadow: 0px 10rpx 4rpx rgba(121, 185, 21, 0.5); box-shadow: 0px 10rpx 2rpx rgba(121, 185, 21, 0.5);
} }
&.active { &.active {
@@ -60,18 +60,20 @@ wx-button:not([size=mini]) {
&--white { &--white {
color: rgba(34, 36, 37, 0.9); color: rgba(34, 36, 37, 0.9);
background: #fff; background: #fff;
box-shadow: 0 6rpx 0 rgba(255, 255, 255, 0.7); box-shadow: 0 8rpx 0rpx rgba(223, 220, 220, 1);
border: 2rpx solid rgba(223, 220, 220, 1);
&.disabled { &.disabled {
color: rgba(34, 36, 37, 0.7);
background: rgba(255, 255, 255, 0.8); background: rgba(255, 255, 255, 0.8);
box-shadow: 0px 6rpx 0px rgba(255, 255, 255, 0.55); box-shadow: 0px 8rpx 0rpx rgba(223, 220, 220, 0.9);
} }
&.plain { &.plain {
color: #fff; color: #fff;
background: rgba(255, 255, 255, 0.2); background: rgba(255, 255, 255, 0.2);
border: 2rpx solid rgba(255, 255, 255, 1); border: 2rpx solid rgba(255, 255, 255, 1);
box-shadow: 0px 6rpx 0px rgba(255, 255, 255, 0.88); box-shadow: 0px 8rpx 0rpx rgba(255, 255, 255, 0.88);
// &.disabled { // &.disabled {
// background: rgba(255, 255, 255, 0.2); // background: rgba(255, 255, 255, 0.2);
@@ -81,8 +83,8 @@ wx-button:not([size=mini]) {
} }
&.active { &.active {
transform: translateY(6rpx); transform: translateY(8rpx);
box-shadow: 0 0 0 rgba(255, 255, 255, 0.7); box-shadow: 0 0 0 rgba(223, 220, 220, 1);
/* 阴影效果 */ /* 阴影效果 */
} }
} }
+9 -1
View File
@@ -82,7 +82,15 @@ Component({
*/ */
data: {}, data: {},
lifetimes: { lifetimes: {
attached() {}, attached() {
const { type, plain, disabled } = this.data;
if (type === 'white' && !plain) {
const iconColor = disabled ? 'rgba(34, 36, 37, 0.7)' : 'rgba(34, 36, 37, 0.9)';
this.setData({
iconColor,
});
}
},
}, },
/** /**
* 组件的方法列表 * 组件的方法列表
+1 -1
View File
@@ -40,7 +40,7 @@
size="1.2em" size="1.2em"
name="{{ icon }}" name="{{ icon }}"
size="{{ iconSize }}" size="{{ iconSize }}"
color="{{ iconColor }}" color="{{ wxs.getIconColor(iconColor, type, plain, disabled) }}"
class-prefix="{{ iconClassPrefix }}" class-prefix="{{ iconClassPrefix }}"
class="toy-button__icon" /> class="toy-button__icon" />
</block> </block>
+11 -4
View File
@@ -6,18 +6,25 @@ module.exports = {
var loading = dataSet.loading; var loading = dataSet.loading;
if (instance && !disabled && !loading) { if (instance && !disabled && !loading) {
instance.addClass('active') instance.addClass('active');
} }
}, },
touchEnd: function (event, ownerInstance) { touchEnd: function (event, ownerInstance) {
var instance = event.instance var instance = event.instance;
var dataSet = instance.getDataset(); var dataSet = instance.getDataset();
var disabled = dataSet.disabled; var disabled = dataSet.disabled;
var loading = dataSet.loading; var loading = dataSet.loading;
if (instance && !disabled && !loading) { if (instance && !disabled && !loading) {
instance.removeClass('active') instance.removeClass('active');
} }
}, },
getIconColor: function (iconColor, type, plain, disabled) {
if (type === 'white' && !plain) {
return disabled ? 'rgba(34, 36, 37, 0.7)' : 'rgba(34, 36, 37, 0.9)';
}
return iconColor;
},
}; };