feat:完成自定义文字涂色卡

This commit is contained in:
2025-07-02 15:17:50 +08:00
parent 26af95b604
commit 8006695f65
19 changed files with 201 additions and 39 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
{
"pages": ["pages/index/index"],
"pages": ["pages/index/index", "pages/debug/debug"],
"window": {},
"style": "v2",
"rendererOptions": {
+29 -3
View File
@@ -1,7 +1,33 @@
// app.ts
App<IAppOption>({
globalData: {},
onLaunch() {
globalData: {
env: 'release'
},
onLaunch() {
const accountInfo = wx.getAccountInfoSync();
const env = accountInfo.miniProgram.envVersion;
this.globalData.env = env;
if (env !== 'release') {
const printHeader = wx.getStorageSync('printHeader') || 'wechat';
this.globalData.printHeader = printHeader;
}
},
onShow() {
// 小程序显示时的生命周期
},
onHide() {
// 小程序隐藏时的生命周期
},
getPrintHeader(): PrintHeader {
return this.globalData.printHeader || 'wechat';
},
setPrintHeader(header: PrintHeader) {
header = header || 'wechat';
this.globalData.printHeader = header;
wx.setStorageSync('printHeader', header);
}
});
Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 168 KiB

@@ -26,7 +26,6 @@ Component({
lifetimes: {
attached() {
const { platform } = wx.getDeviceInfo();
console.log('platform:', platform);
this.setData({
platform,
});
@@ -53,6 +52,6 @@ Component({
});
},
preventScroll() {},
preventScroll() { },
},
});
@@ -14,7 +14,7 @@ Component({
type: Number,
value: 0,
},
selectedWords: {
cardList: {
type: Array,
value: [],
},
@@ -24,11 +24,18 @@ Component({
*/
data: {
wordList: WORDS,
selectedWords: [] as string[],
},
lifetimes: {
ready() {
},
},
observers: {
cardList(newVal: CardList) {
const selectedWords = newVal.map((item) => item.word);
this.setData({ selectedWords });
},
},
/**
* 组件的方法列表
*/
-6
View File
@@ -1,6 +0,0 @@
type Channel = 'wechat' | 'noLogo' | 'rednoteLogo' | 'miniHeader';
const channel: Channel = 'wechat';
export const CHANNEL = channel;
export const APP_NAME = '涂鸦丫';
+1 -2
View File
@@ -17,7 +17,6 @@ Page({
.select('#textCanvas')
.fields({ node: true, size: true })
.exec((res) => {
console.log('res----:', res);
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
this.canvas = canvas;
@@ -43,7 +42,7 @@ Page({
});
},
setCanvasSize() {},
setCanvasSize() { },
drawCircles: function () {
if (!this.canvas) {
+14
View File
@@ -0,0 +1,14 @@
{
"navigationBarTitleText": "Debug",
"navigationBarBackgroundColor": "#FFD719",
"homeButton": true,
"backgroundColor": "#F6F6F6",
"enablePullDownRefresh": false,
"usingComponents": {
"toy-button": "../../ui/button/button",
"van-radio": "@vant/weapp/radio/index",
"van-radio-group": "@vant/weapp/radio-group/index",
"van-cell": "@vant/weapp/cell/index",
"van-cell-group": "@vant/weapp/cell-group/index"
}
}
+24
View File
@@ -0,0 +1,24 @@
.debug-page {
min-height: 100vh;
padding: 20rpx;
background-color: #F6F6F6;
.debug-wrapper {
background-color: #fff;
border-radius: 20rpx;
overflow: hidden;
.centered-title {
text-align: center;
color: #666;
border-top: 0 none;
}
}
.btn-area {
display: flex;
align-items: center;
justify-content: center;
margin-top: 40rpx;
}
}
+25
View File
@@ -0,0 +1,25 @@
Page({
data: {
header: 'wechat'
},
onLoad() {
const header = getApp().getPrintHeader() || 'wechat';
this.setData({ header });
},
onChangeHeader(e: WechatMiniprogram.CustomEvent) {
const header = e.detail.value as PrintHeader;
this.setData({ header });
},
onClickHeaderSetting(e: WechatMiniprogram.CustomEvent) {
const header = e.currentTarget.dataset.name as PrintHeader;
this.setData({ header });
},
onConfirm() {
getApp().setPrintHeader(this.data.header);
wx.navigateBack();
}
});
+44
View File
@@ -0,0 +1,44 @@
<view class="debug-page">
<van-cell-group custom-class="debug-wrapper">
<van-cell
title="打印图片Header设置"
size="large"
custom-class="centered-title" />
<van-radio-group value="{{header}}" bind:change="onChangeHeader">
<van-cell
title="微信小程序头(wechat)(默认)"
clickable
data-name="wechat"
bind:click="onClickHeaderSetting">
<van-radio slot="right-icon" name="wechat" />
</van-cell>
<van-cell
title="无Logo图片头(noLogo"
clickable
data-name="noLogoImage"
bind:click="onClickHeaderSetting">
<van-radio slot="right-icon" name="noLogoImage" />
</van-cell>
<van-cell
title="有Logo图片头(LogoImage"
clickable
data-name="LogoImage"
bind:click="onClickHeaderSetting">
<van-radio slot="right-icon" name="LogoImage" />
</van-cell>
<van-cell
title="最小Header头(minimal"
clickable
data-name="minimal"
bind:click="onClickHeaderSetting"
border="{{ false }}">
<van-radio slot="right-icon" name="minimal" />
</van-cell>
</van-radio-group>
</van-cell-group>
<view class="btn-area">
<toy-button type="green" bind:click="onConfirm" width="360rpx">
确定
</toy-button>
</view>
</view>
-1
View File
@@ -26,7 +26,6 @@ Page({
tapCard(e: WechatMiniprogram.TouchEvent) {
const { url } = e.currentTarget.dataset;
console.log('navigateTo url:', url);
wx.navigateTo({ url });
},
});
+1
View File
@@ -5,6 +5,7 @@
"backgroundColor": "#F6F6F6",
"enablePullDownRefresh": false,
"usingComponents": {
"van-cell": "@vant/weapp/cell/index",
"van-icon": "@vant/weapp/icon/index",
"van-popup": "@vant/weapp/popup/index",
"word-input": "../../components/word-input/word-input",
+8 -1
View File
@@ -10,12 +10,13 @@ Page({
textDrawService: null as TextDrawService | null,
data: {
cardList: [] as Array<{ color: string; word: string }>,
cardList: [] as CardList,
showColorPopup: false,
currentKey: 0,
currentColor: '',
showIntroductionPopup: false,
showSelectWordPopup: false, // 选择文字弹窗
env: getApp().globalData.env || 'release',
},
onLoad() {
@@ -345,4 +346,10 @@ Page({
this.setData({ showSelectWordPopup: false });
this.drawCanvas(cardList);
},
onDebugEntryTap() {
wx.navigateTo({
url: '/pages/debug/debug',
});
},
});
+6 -9
View File
@@ -70,6 +70,11 @@
style="width:{{boxWidth}}px;height:{{boxHeight}}px" />
</view>
</view>
<van-cell
is-link
title="debug页面"
link-type="navigateTo"
url="/pages/debug/debug" />
<view class="empty"></view>
<color-picker
show="{{showColorPopup}}"
@@ -78,7 +83,7 @@
bind:onChange="onChangeColor" />
<word-picker
show="{{showSelectWordPopup}}"
selectedWords="{{selectedWords}}"
cardList="{{cardList}}"
bind:onClose="closeSelectWordPopup"
bind:onChange="onChangeWord" />
</view>
@@ -92,14 +97,6 @@
icon-class-prefix="toy-icon">
下载打印
</toy-button>
<!-- <toy-button
type="green"
width="680rpx"
disabled="{{cardList.length <= 0}}"
icon="download"
icon-class-prefix="toy-icon">
下载打印
</toy-button> -->
</view>
<introduction-popup
wx:if="{{showIntroductionPopup}}"
+14 -12
View File
@@ -1,6 +1,5 @@
// import { PAPER_SIZE } from './constant';
import { PAPER_SIZE } from '../constants/colors';
import { CHANNEL } from '../config/config';
import { getMiniCodeImage, getImage } from '../utils/index';
/**
@@ -51,6 +50,7 @@ function calculateCircleCenters(
}
class TextDrawService {
headerType: PrintHeader;
canvas: WechatMiniprogram.Canvas;
ctx: RenderingContext;
options: Record<string, any>;
@@ -83,12 +83,13 @@ class TextDrawService {
}
draw(list: Array<{ color: string; word: string }>) {
this.headerType = getApp().getPrintHeader() || 'wechat';
this.colors = list.map((item) => item.color || '#000');
this.characters = list.map((item) => item.word || '日');
this.clear();
this.setPaper();
// @ts-ignore
if (CHANNEL !== 'miniHeader') {
if (this.headerType !== 'minimal') {
this.drawHeader();
} else {
this.drawMiniHeader();
@@ -112,15 +113,17 @@ class TextDrawService {
const logoWidth = 200;
const logoHeight = 200;
switch (CHANNEL) {
// @ts-ignore
case 'rednoteLogo': {
switch (this.headerType) {
case 'LogoImage': {
const image = await getImage(canvas, '/assets/imgs/doodle-logo.png');
ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight);
break;
}
// @ts-ignore
case 'noLogo': {
case 'noLogoImage': {
titleX = 120;
break;
}
case 'minimal': {
titleX = 120;
break;
}
@@ -187,6 +190,7 @@ class TextDrawService {
const { canvas, ctx, colors, characters } = this;
if (characters.length <= 0) return;
// const { colors, characters } = options;
this.currentY = this.headerType === 'minimal' ? 200 : 304;
const radius = 65;
const rectWidth = 180;
const rectHeight = 80;
@@ -233,8 +237,7 @@ class TextDrawService {
);
});
// @ts-ignore
this.currentY = CHANNEL === 'miniHeader' ? 522 : 612; // 计算分割线的Y坐标,距离示例图20px
this.currentY = this.headerType === 'minimal' ? 522 : 612; // 计算分割线的Y坐标,距离示例图20px
this.drawLine(this.currentY);
}
@@ -243,8 +246,7 @@ class TextDrawService {
if (characters.length <= 0) return;
const len = characters.length;
// @ts-ignore
const rows = CHANNEL === 'miniHeader' ? 9 : 8;
const rows = this.headerType === 'minimal' ? 9 : 8;
const radius = 80;
const fontSize = 72;
+13 -1
View File
@@ -20,5 +20,17 @@
"bigPackageSizeSupport": false
},
"libVersion": "3.7.12",
"condition": {}
"condition": {
"miniprogram": {
"list": [
{
"name": "debug页",
"pathName": "pages/debug/debug",
"query": "",
"scene": null,
"launchMode": "default"
}
]
}
}
}
+7
View File
@@ -0,0 +1,7 @@
type PrintHeader = 'wechat' | 'noLogoImage' | 'LogoImage' | 'minimal';
type WordCard = {
color: string;
word: string;
};
interface CardList extends Array<WordCard> { }
+5
View File
@@ -1,7 +1,12 @@
/// <reference path="./global.d.ts" />
/// <reference path="./common.d.ts" />
interface IAppOption {
globalData: {
userInfo?: WechatMiniprogram.UserInfo;
env: string;
printHeader?: PrintHeader;
};
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback;
[key: string]: any;
}