feat: 完成文字涂色卡功能

This commit is contained in:
2025-07-01 11:27:50 +08:00
parent 654afced6f
commit 6d38a17652
21 changed files with 267 additions and 103 deletions
+5 -2
View File
@@ -10,7 +10,6 @@ cloud.init({
exports.main = async (event, context) => {
try {
console.log('main event.action:', event.action);
switch (event.action) {
case 'getOpenId': {
const res = await getOpenId(event, context);
@@ -26,7 +25,11 @@ exports.main = async (event, context) => {
return await createPDF();
}
default:
return { code: 1, message: '请检查云函数名是否正确!', data: {} };
return {
code: 1,
message: '请检查云函数名是否正确!',
data: {},
};
}
} catch (error) {
console.error('Error in user cloud Function:', error);
-19
View File
@@ -2,25 +2,6 @@
App<IAppOption>({
globalData: {},
onLaunch() {
// 展示本地存储能力
const logs = wx.getStorageSync('logs') || [];
logs.unshift(Date.now());
wx.setStorageSync('logs', logs);
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: '',
traceUser: true,
});
// 登录
wx.login({
success: (res) => {
console.log(res.code);
// 发送 res.code 到后台换取 openId, sessionKey, unionId
},
});
},
});
@@ -147,8 +147,6 @@ class TextDrawService {
canvas.width = width;
canvas.height = height;
console.log('width---:', width);
console.log('height---:', height);
this.clear();
ctx.fillStyle = '#fff'; // 设置背景色为白色
ctx.fillRect(0, 0, width, height);
@@ -210,8 +210,6 @@ class TextDrawService {
canvas.width = width;
canvas.height = height;
console.log('width---:', width);
console.log('height---:', height);
this.clear();
ctx.fillStyle = '#fff'; // 设置背景色为白色
ctx.fillRect(0, 0, width, height);
@@ -13,7 +13,7 @@
height: 60rpx;
border-radius: 50%;
background-color: #ff0000;
margin-left: 20rpx;
margin-left: 24rpx;
border: 1rpx solid #141414;
position: relative;
@@ -34,7 +34,7 @@
}
.word-box {
margin: 0 4rpx 0 24rpx;
margin: 0 16rpx 0 36rpx;
display: flex;
justify-content: center;
align-items: center;
@@ -2,6 +2,7 @@
"component": true,
"styleIsolation": "apply-shared",
"usingComponents": {
"van-icon": "@vant/weapp/icon/index"
"van-icon": "@vant/weapp/icon/index",
"toy-button": "/ui/button/button"
}
}
@@ -19,4 +19,22 @@
font-size: 28rpx;
line-height: 92rpx;
}
.btn-word-add {
box-sizing: border-box;
display: inline-flex;
align-items: center;
justify-content: center;
height: 72rpx;
padding: 0 24rpx;
background: rgba(255, 215, 25, 1);
border-radius: 20rpx;
font-size: 28rpx;
color: #fff;
margin-right: 10rpx;
&.active {
background-color: rgba(255, 215, 25, 0.8);
}
}
}
@@ -18,20 +18,28 @@ Component({
/**
* 组件的初始数据
*/
data: {},
data: {
},
lifetimes: {
attached() {
(this as any).words = '';
(this as any).value = '';
},
},
/**
* 组件的方法列表
*/
methods: {
onConfirm(e: WechatMiniprogram.Input) {
onInput(e: WechatMiniprogram.Input) {
let { value } = e.detail;
// (this as any).words = value;
value = value.replace(' ', '');
value = value.replace(/\s/g, '');
if (value.length > 0) {
(this as any).value = value;
}
},
onConfirm() {
const value = (this as any).value;
if (value.length > 0) {
this.triggerEvent('onConfirm', { value });
}
@@ -1,3 +1,5 @@
<wxs module="wxs" src="./word-input.wxs"></wxs>
<view
class="word-input-container"
style="{{width ? 'width:' + width + ';' : ''}}">
@@ -10,5 +12,13 @@
class="word-input"
type="text"
placeholder="{{placeholder}}"
bindinput="onInput"
bindconfirm="onConfirm" />
<view
class="btn-word-add"
bind:tap="onConfirm"
bind:touchstart="{{wxs.touchStart}}"
bind:touchend="{{wxs.touchEnd}}">
添加
</view>
</view>
@@ -0,0 +1,23 @@
module.exports = {
touchStart: function (event, ownerInstance) {
var instance = event.instance;
var dataSet = instance.getDataset();
var disabled = dataSet.disabled;
var loading = dataSet.loading;
if (instance && !disabled && !loading) {
instance.addClass('active');
}
},
touchEnd: function (event, ownerInstance) {
var instance = event.instance;
var dataSet = instance.getDataset();
var disabled = dataSet.disabled;
var loading = dataSet.loading;
if (instance && !disabled && !loading) {
instance.removeClass('active');
}
},
};
@@ -86,6 +86,7 @@
display: flex;
justify-content: space-between;
margin-bottom: 96rpx;
padding: 0 28rpx;
}
}
@@ -27,7 +27,6 @@ Component({
},
lifetimes: {
ready() {
console.log('selectedWords', this.data.selectedWords);
},
},
/**
@@ -38,6 +37,12 @@ Component({
this.triggerEvent('onClose');
},
onClear() {
this.setData({
selectedWords: [],
});
},
onChange() {
this.triggerEvent('onChange', { selectedWords: this.data.selectedWords });
},
@@ -4,13 +4,15 @@
show="{{ show }}"
bind:close="onClose"
round
close-on-click-overlay="{{false}}"
closeable="{{true}}"
close-on-click-overlay="{{true}}"
safe-area-inset-bottom="{{true}}"
position="bottom"
custom-style="height: 70%"
custom-class="word-picker">
<view class="word-picker-title">请选择文字</view>
<van-tabs
wx:if="{{show}}"
id="tabs"
animated
color="#93d333"
@@ -54,15 +56,16 @@
>
</view>
<view class="btn-area">
<toy-button
type="primary"
bind:click="onChange"
width="420rpx"
disabled="{{selectedWords.length <= 0}}">
<toy-button type="primary" bind:click="onChange" width="400rpx">
(已选{{selectedWords.length}}个) 确定
</toy-button>
<toy-button type="white" bind:click="onClose" width="220rpx">
取消
<toy-button
type="white"
bind:click="onClear"
width="210rpx"
icon="clear"
icon-class-prefix="toy-icon">
清空
</toy-button>
</view>
</van-popup>
+126 -22
View File
@@ -172,9 +172,16 @@ export const WORDS = [
},
{
categoryId: 3,
icon: '🎨',
categoryName: '颜色',
words: ['红', '蓝', '绿', '黄', '黑', '白', '紫', '橙', '粉', '棕', '灰'],
},
{
categoryId: 4,
icon: '',
categoryName: '数字与颜色',
categoryName: '数字',
words: [
'零',
'一',
'二',
'三',
@@ -185,75 +192,172 @@ export const WORDS = [
'八',
'九',
'十',
'',
'',
'绿',
'',
'',
'',
'',
'',
'',
'',
'',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25',
'26',
'27',
'28',
'29',
'30',
'31',
'32',
'33',
'34',
'35',
'36',
'37',
'38',
'39',
'40',
'41',
'42',
'43',
'44',
'45',
'46',
'47',
'48',
'49',
'50',
'51',
'52',
'53',
'54',
'55',
'56',
'57',
'58',
'59',
'60',
'61',
'62',
'63',
'64',
'65',
'66',
'67',
'68',
'69',
'70',
'71',
'72',
'73',
'74',
'75',
'76',
'77',
'78',
'79',
'80',
'81',
'82',
'83',
'84',
'85',
'86',
'87',
'88',
'89',
'90',
'91',
'92',
'93',
'94',
'95',
'96',
'97',
'98',
'99',
'100'
],
},
{
categoryId: 4,
categoryId: 5,
icon: '🎨',
categoryName: '字母',
words: ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'],
},
{
categoryId: 6,
icon: '☀️',
categoryName: '日字旁',
words: ['日', '明', '早', '时', '晴', '春', '星', '晨'],
},
{
categoryId: 5,
categoryId: 7,
icon: '💧',
categoryName: '三点水',
words: ['水', '江', '河', '流', '沙', '洗', '海', '汗'],
},
{
categoryId: 6,
categoryId: 8,
icon: '🐦',
categoryName: '鸟字边',
words: ['鸟', '鸡', '鸭', '鹅', '鸣', '鸽', '鸦'],
},
{
categoryId: 7,
categoryId: 9,
icon: '🐾',
categoryName: '反犬旁',
words: ['狗', '猫', '猴', '狮', '狼', '猪'],
},
{
categoryId: 8,
categoryId: 10,
icon: '🪱',
categoryName: '虫字旁',
words: ['虫', '蚁', '蝶', '蜻', '蛙', '蛇', '蜘', '蜂'],
},
{
categoryId: 9,
categoryId: 11,
icon: '🌧️',
categoryName: '雨字头',
words: ['雨', '雪', '雷', '露', '雾', '雹', '霜'],
},
{
categoryId: 10,
categoryId: 12,
icon: '🌲',
categoryName: '木字旁',
words: ['木', '林', '树', '桃', '森', '松', '桥', '枝'],
},
{
categoryId: 11,
categoryId: 13,
icon: '👄',
categoryName: '口字旁',
words: ['口', '吃', '叫', '唱', '听', '吹', '叶', '和'],
},
{
categoryId: 12,
categoryId: 14,
icon: '🧍',
categoryName: '单人旁',
words: ['你', '他', '们', '作', '休', '住', '伙', '伴'],
},
{
categoryId: 13,
categoryId: 15,
icon: '❤️',
categoryName: '竖心旁',
words: ['心', '情', '快', '怕', '惊', '忙', '怀'],
+12 -4
View File
@@ -24,7 +24,7 @@ page {
.wrapper-title {
font-size: 32rpx;
color: #141414;
margin-bottom: 30rpx;
margin-bottom: 24rpx;
font-weight: bold;
text-align: center;
}
@@ -34,13 +34,23 @@ page {
}
.word-card-box {
margin-top: 30rpx;
padding: 34rpx 0;
.word-list-empty {
text-align: center;
font-size: 28rpx;
color: #999;
}
.word-card-list {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
}
}
@@ -66,9 +76,7 @@ page {
.canvas-wrapper {
margin-top: 20rpx;
width: 100%;
// border: 1rpx solid #141414;
background-color: #fff;
box-sizing: border-box;
}
+3 -4
View File
@@ -49,7 +49,9 @@ Page({
this.boxHeight = boxHeight;
this.boxWidth = boxWidth;
setTimeout(() => {
this.initCanvas(boxWidth, boxHeight);
}, 500);
}
})
.exec();
@@ -176,7 +178,6 @@ Page({
/** 下载打印 */
exportToPrint() {
console.log('this.canvas:', this.canvas);
if (this.canvas && this.data.cardList.length > 0) {
wx.canvasToTempFilePath({
canvas: this.canvas,
@@ -259,7 +260,7 @@ Page({
// 随机生成
refreshCardList() {
// 获取前4个分类的所有文字
const allWords = WORDS.slice(0, 4).reduce((acc, category) => {
const allWords = WORDS.slice(0, 2).reduce((acc, category) => {
return acc.concat(category.words);
}, [] as string[]);
@@ -286,7 +287,6 @@ Page({
color: selectedColors[index],
word
}));
console.log('cardList:', cardList);
this.drawCanvas(cardList);
},
openSelectWordPopup() {
@@ -303,7 +303,6 @@ Page({
onChangeWord(e: WechatMiniprogram.CustomEvent) {
const selectedWords = e.detail.selectedWords as string[];
console.log('selectedWords:', selectedWords);
const colors = [...WATER_COLORS.basic12];
const cardList = selectedWords.map((word, index) => ({
+10 -5
View File
@@ -12,6 +12,7 @@
</view>
<view class="word-card-box">
<block wx:if="{{cardList.length > 0}}">
<block
wx:for="{{cardList}}"
wx:for-item="item"
@@ -32,6 +33,12 @@
bind:onColorTap="onColorTap" />
</view>
</block>
</block>
<block wx:if="{{!cardList.length}}">
<view class="word-list-empty">
请选择或输入文字,生成涂鸦卡
</view>
</block>
</view>
<view class="operation-box">
<toy-button
@@ -53,16 +60,14 @@
</toy-button>
</view>
</view>
<view
id="previewWrapper"
class="wrapper {{cardList.length > 0 ? '' : 'hidden'}}">
<view id="previewWrapper" class="wrapper">
<text class="wrapper-title">预览打印效果</text>
<view id="canvasWrapper" class="canvas-wrapper">
<!-- <canvas
<canvas
type="2d"
id="canvasContent"
class="canvas-content"
style="width:{{boxWidth}}px;height:{{boxHeight}}px" /> -->
style="width:{{boxWidth}}px;height:{{boxHeight}}px" />
</view>
</view>
<view class="empty"></view>
+2 -2
View File
@@ -70,10 +70,10 @@ class TextDrawService {
this.ctx = ctx;
this.paperSize = 'A4';
this.options = {
appName: '涂鸦丫',
appName: '涂鸦丫小程序',
appHint: '涂色|识字|画画|打印',
title: '找一找 涂 色',
subTitle: '把相同的文字涂上相同的颜色',
subTitle: '文字涂上相同的颜色',
...options,
};
this.currentX = 0;
+2 -3
View File
@@ -15,7 +15,6 @@ wx-button:not([size=mini]) {
align-items: center;
justify-content: center;
height: @button-default-height;
line-height: @button-default-height;
border-radius: @button-border-radius;
font-size: @button-default-font-size;
color: @button-default-color;
@@ -64,8 +63,8 @@ wx-button:not([size=mini]) {
border: 2rpx solid rgba(223, 220, 220, 1);
&.disabled {
color: rgba(34, 36, 37, 0.7);
background: rgba(255, 255, 255, 0.8);
color: rgba(34, 36, 37, 0.5);
background: rgba(255, 255, 255, 0.7);
box-shadow: 0px 8rpx 0rpx rgba(223, 220, 220, 0.9);
}
+1 -1
View File
@@ -85,7 +85,7 @@ Component({
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)';
const iconColor = disabled ? 'rgba(34, 36, 37, 0.5)' : 'rgba(34, 36, 37, 0.9)';
this.setData({
iconColor,
});
+1 -1
View File
@@ -23,7 +23,7 @@ module.exports = {
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 disabled ? 'rgba(34, 36, 37, 0.5)' : 'rgba(34, 36, 37, 0.9)';
}
return iconColor;
},