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": {}, "window": {},
"style": "v2", "style": "v2",
"rendererOptions": { "rendererOptions": {
+29 -3
View File
@@ -1,7 +1,33 @@
// app.ts // app.ts
App<IAppOption>({ App<IAppOption>({
globalData: {}, globalData: {
onLaunch() { 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: { lifetimes: {
attached() { attached() {
const { platform } = wx.getDeviceInfo(); const { platform } = wx.getDeviceInfo();
console.log('platform:', platform);
this.setData({ this.setData({
platform, platform,
}); });
@@ -53,6 +52,6 @@ Component({
}); });
}, },
preventScroll() {}, preventScroll() { },
}, },
}); });
@@ -14,7 +14,7 @@ Component({
type: Number, type: Number,
value: 0, value: 0,
}, },
selectedWords: { cardList: {
type: Array, type: Array,
value: [], value: [],
}, },
@@ -24,11 +24,18 @@ Component({
*/ */
data: { data: {
wordList: WORDS, wordList: WORDS,
selectedWords: [] as string[],
}, },
lifetimes: { lifetimes: {
ready() { 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') .select('#textCanvas')
.fields({ node: true, size: true }) .fields({ node: true, size: true })
.exec((res) => { .exec((res) => {
console.log('res----:', res);
const canvas = res[0].node; const canvas = res[0].node;
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
this.canvas = canvas; this.canvas = canvas;
@@ -43,7 +42,7 @@ Page({
}); });
}, },
setCanvasSize() {}, setCanvasSize() { },
drawCircles: function () { drawCircles: function () {
if (!this.canvas) { 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) { tapCard(e: WechatMiniprogram.TouchEvent) {
const { url } = e.currentTarget.dataset; const { url } = e.currentTarget.dataset;
console.log('navigateTo url:', url);
wx.navigateTo({ url }); wx.navigateTo({ url });
}, },
}); });
+1
View File
@@ -5,6 +5,7 @@
"backgroundColor": "#F6F6F6", "backgroundColor": "#F6F6F6",
"enablePullDownRefresh": false, "enablePullDownRefresh": false,
"usingComponents": { "usingComponents": {
"van-cell": "@vant/weapp/cell/index",
"van-icon": "@vant/weapp/icon/index", "van-icon": "@vant/weapp/icon/index",
"van-popup": "@vant/weapp/popup/index", "van-popup": "@vant/weapp/popup/index",
"word-input": "../../components/word-input/word-input", "word-input": "../../components/word-input/word-input",
+8 -1
View File
@@ -10,12 +10,13 @@ Page({
textDrawService: null as TextDrawService | null, textDrawService: null as TextDrawService | null,
data: { data: {
cardList: [] as Array<{ color: string; word: string }>, cardList: [] as CardList,
showColorPopup: false, showColorPopup: false,
currentKey: 0, currentKey: 0,
currentColor: '', currentColor: '',
showIntroductionPopup: false, showIntroductionPopup: false,
showSelectWordPopup: false, // 选择文字弹窗 showSelectWordPopup: false, // 选择文字弹窗
env: getApp().globalData.env || 'release',
}, },
onLoad() { onLoad() {
@@ -345,4 +346,10 @@ Page({
this.setData({ showSelectWordPopup: false }); this.setData({ showSelectWordPopup: false });
this.drawCanvas(cardList); 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" /> style="width:{{boxWidth}}px;height:{{boxHeight}}px" />
</view> </view>
</view> </view>
<van-cell
is-link
title="debug页面"
link-type="navigateTo"
url="/pages/debug/debug" />
<view class="empty"></view> <view class="empty"></view>
<color-picker <color-picker
show="{{showColorPopup}}" show="{{showColorPopup}}"
@@ -78,7 +83,7 @@
bind:onChange="onChangeColor" /> bind:onChange="onChangeColor" />
<word-picker <word-picker
show="{{showSelectWordPopup}}" show="{{showSelectWordPopup}}"
selectedWords="{{selectedWords}}" cardList="{{cardList}}"
bind:onClose="closeSelectWordPopup" bind:onClose="closeSelectWordPopup"
bind:onChange="onChangeWord" /> bind:onChange="onChangeWord" />
</view> </view>
@@ -92,14 +97,6 @@
icon-class-prefix="toy-icon"> icon-class-prefix="toy-icon">
下载打印 下载打印
</toy-button> </toy-button>
<!-- <toy-button
type="green"
width="680rpx"
disabled="{{cardList.length <= 0}}"
icon="download"
icon-class-prefix="toy-icon">
下载打印
</toy-button> -->
</view> </view>
<introduction-popup <introduction-popup
wx:if="{{showIntroductionPopup}}" wx:if="{{showIntroductionPopup}}"
+14 -12
View File
@@ -1,6 +1,5 @@
// import { PAPER_SIZE } from './constant'; // import { PAPER_SIZE } from './constant';
import { PAPER_SIZE } from '../constants/colors'; import { PAPER_SIZE } from '../constants/colors';
import { CHANNEL } from '../config/config';
import { getMiniCodeImage, getImage } from '../utils/index'; import { getMiniCodeImage, getImage } from '../utils/index';
/** /**
@@ -51,6 +50,7 @@ function calculateCircleCenters(
} }
class TextDrawService { class TextDrawService {
headerType: PrintHeader;
canvas: WechatMiniprogram.Canvas; canvas: WechatMiniprogram.Canvas;
ctx: RenderingContext; ctx: RenderingContext;
options: Record<string, any>; options: Record<string, any>;
@@ -83,12 +83,13 @@ class TextDrawService {
} }
draw(list: Array<{ color: string; word: string }>) { draw(list: Array<{ color: string; word: string }>) {
this.headerType = getApp().getPrintHeader() || 'wechat';
this.colors = list.map((item) => item.color || '#000'); this.colors = list.map((item) => item.color || '#000');
this.characters = list.map((item) => item.word || '日'); this.characters = list.map((item) => item.word || '日');
this.clear(); this.clear();
this.setPaper(); this.setPaper();
// @ts-ignore if (this.headerType !== 'minimal') {
if (CHANNEL !== 'miniHeader') {
this.drawHeader(); this.drawHeader();
} else { } else {
this.drawMiniHeader(); this.drawMiniHeader();
@@ -112,15 +113,17 @@ class TextDrawService {
const logoWidth = 200; const logoWidth = 200;
const logoHeight = 200; const logoHeight = 200;
switch (CHANNEL) { switch (this.headerType) {
// @ts-ignore case 'LogoImage': {
case 'rednoteLogo': {
const image = await getImage(canvas, '/assets/imgs/doodle-logo.png'); const image = await getImage(canvas, '/assets/imgs/doodle-logo.png');
ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight); ctx.drawImage(image, logoX, logoY, logoWidth, logoHeight);
break; break;
} }
// @ts-ignore case 'noLogoImage': {
case 'noLogo': { titleX = 120;
break;
}
case 'minimal': {
titleX = 120; titleX = 120;
break; break;
} }
@@ -187,6 +190,7 @@ class TextDrawService {
const { canvas, ctx, colors, characters } = this; const { canvas, ctx, colors, characters } = this;
if (characters.length <= 0) return; if (characters.length <= 0) return;
// const { colors, characters } = options; // const { colors, characters } = options;
this.currentY = this.headerType === 'minimal' ? 200 : 304;
const radius = 65; const radius = 65;
const rectWidth = 180; const rectWidth = 180;
const rectHeight = 80; const rectHeight = 80;
@@ -233,8 +237,7 @@ class TextDrawService {
); );
}); });
// @ts-ignore this.currentY = this.headerType === 'minimal' ? 522 : 612; // 计算分割线的Y坐标,距离示例图20px
this.currentY = CHANNEL === 'miniHeader' ? 522 : 612; // 计算分割线的Y坐标,距离示例图20px
this.drawLine(this.currentY); this.drawLine(this.currentY);
} }
@@ -243,8 +246,7 @@ class TextDrawService {
if (characters.length <= 0) return; if (characters.length <= 0) return;
const len = characters.length; const len = characters.length;
// @ts-ignore const rows = this.headerType === 'minimal' ? 9 : 8;
const rows = CHANNEL === 'miniHeader' ? 9 : 8;
const radius = 80; const radius = 80;
const fontSize = 72; const fontSize = 72;
+13 -1
View File
@@ -20,5 +20,17 @@
"bigPackageSizeSupport": false "bigPackageSizeSupport": false
}, },
"libVersion": "3.7.12", "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="./global.d.ts" />
/// <reference path="./common.d.ts" />
interface IAppOption { interface IAppOption {
globalData: { globalData: {
userInfo?: WechatMiniprogram.UserInfo; userInfo?: WechatMiniprogram.UserInfo;
env: string;
printHeader?: PrintHeader;
}; };
userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback; userInfoReadyCallback?: WechatMiniprogram.GetUserInfoSuccessCallback;
[key: string]: any;
} }