251 lines
7.7 KiB
TypeScript
251 lines
7.7 KiB
TypeScript
import { WATER_COLORS, PAPER_SIZE } from '../../constants/colors';
|
|
import TextDrawService from '../../service/textDrawService';
|
|
|
|
Page({
|
|
canvas: null as Canvas | null,
|
|
ctx: null as RenderingContext | null,
|
|
boxHeight: 0,
|
|
boxWidth: 0,
|
|
textDrawService: null as TextDrawService | null,
|
|
|
|
data: {
|
|
cardList: [] as Array<{ color: string; word: string }>,
|
|
showColorPopup: false,
|
|
currentKey: 0,
|
|
currentColor: '',
|
|
showIntroductionPopup: false,
|
|
},
|
|
|
|
onLoad() {
|
|
const hasShowIntroduction =
|
|
wx.getStorageSync('hasShowIntroduction') || false;
|
|
|
|
if (!hasShowIntroduction) {
|
|
this.setData({
|
|
cardList: [
|
|
{ color: '#FF0000', word: '涂' },
|
|
{ color: '#00FF00', word: '欢' },
|
|
{ color: '#FF7F00', word: '鸦' },
|
|
{ color: '#00FFFF', word: '迎' },
|
|
{ color: '#FFFF00', word: '丫' },
|
|
{ color: '#8A2BE2', word: '你' },
|
|
],
|
|
showIntroductionPopup: true,
|
|
});
|
|
}
|
|
},
|
|
|
|
onReady() {
|
|
const query = wx.createSelectorQuery();
|
|
query
|
|
.select('#canvasWrapper')
|
|
.boundingClientRect((rect) => {
|
|
if (rect) {
|
|
const { width, height } = PAPER_SIZE['A4'];
|
|
const boxWidth = rect.width;
|
|
const boxHeight = boxWidth / (width / height);
|
|
|
|
this.boxHeight = boxHeight;
|
|
this.boxWidth = boxWidth;
|
|
this.initCanvas(boxWidth, boxHeight);
|
|
}
|
|
})
|
|
.exec();
|
|
},
|
|
|
|
initCanvas(boxWidth: number, boxHeight: number) {
|
|
wx.createSelectorQuery()
|
|
.select('#canvasContent')
|
|
.fields({
|
|
node: true,
|
|
size: true,
|
|
})
|
|
.exec((res) => {
|
|
if (res[0] && res[0].node) {
|
|
const canvas = res[0].node;
|
|
const ctx = canvas.getContext('2d');
|
|
if (ctx) {
|
|
this.canvas = canvas;
|
|
this.ctx = ctx;
|
|
// const rect = res[0];
|
|
this.textDrawService = new TextDrawService(canvas, ctx);
|
|
// textDrawService.draw();
|
|
this.setData({ boxWidth, boxHeight });
|
|
this.drawCanvas();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
|
|
/** 变更cardList 并更新canvas */
|
|
drawCanvas(
|
|
updatedCardList?: Array<{ color: string; word: string }>,
|
|
callback: () => void = () => {},
|
|
) {
|
|
if (updatedCardList && updatedCardList.length >= 0) {
|
|
this.setData({ cardList: updatedCardList }, callback);
|
|
} else {
|
|
updatedCardList = this.data.cardList;
|
|
}
|
|
|
|
this.textDrawService?.draw(updatedCardList);
|
|
},
|
|
|
|
tapCard(e: WechatMiniprogram.TouchEvent) {
|
|
const { url } = e.currentTarget.dataset;
|
|
wx.navigateTo({ url });
|
|
},
|
|
|
|
onConfirmInput(e: WechatMiniprogram.Input) {
|
|
const { cardList } = this.data;
|
|
const { value } = e.detail;
|
|
const characters = value.split('');
|
|
// 计算剩余空间
|
|
const remainingSlots = 6 - cardList.length;
|
|
if (remainingSlots <= 0) {
|
|
wx.showToast({
|
|
title: '最多只能添加6个字哦!',
|
|
icon: 'none',
|
|
duration: 2000,
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 准备颜色数组
|
|
const allColors = WATER_COLORS.basic12.map((color) => color.hex);
|
|
const usedColors = cardList.map((item) => item.color);
|
|
const usedWords = cardList.map((item) => item.word);
|
|
|
|
const availableColors = allColors.filter(
|
|
(color) => !usedColors.includes(color),
|
|
);
|
|
const shuffledColors = [...availableColors].sort(
|
|
() => Math.random() - 0.5,
|
|
);
|
|
|
|
const newCharacters: string[] = [];
|
|
let isBeyond = false;
|
|
for (const char of characters) {
|
|
// 检查字符是否是新字符且未被使用
|
|
if (newCharacters.length >= remainingSlots) {
|
|
isBeyond = true;
|
|
break;
|
|
}
|
|
if (!usedWords.includes(char) && !newCharacters.includes(char)) {
|
|
newCharacters.push(char);
|
|
}
|
|
}
|
|
if (isBeyond) {
|
|
wx.showToast({
|
|
title: '最多只能添加6个字,多余的字为被添加哦!',
|
|
icon: 'none',
|
|
duration: 2000,
|
|
});
|
|
}
|
|
|
|
// 为新字符创建卡片
|
|
const newCards = newCharacters.map((char, index) => {
|
|
const colorIndex = index % shuffledColors.length;
|
|
return {
|
|
word: char,
|
|
color: shuffledColors[colorIndex],
|
|
};
|
|
});
|
|
|
|
// 合并新旧卡片
|
|
const updatedCardList = [...cardList, ...newCards];
|
|
this.drawCanvas(updatedCardList);
|
|
},
|
|
|
|
deleteWordCard(e: WechatMiniprogram.CustomEvent) {
|
|
const { key, word } = e.detail;
|
|
const { cardList } = this.data;
|
|
const updatedCardList = cardList.filter((_, index) => index !== key);
|
|
this.drawCanvas(updatedCardList, () => {
|
|
wx.showToast({
|
|
title: `已删除 "${word}"`,
|
|
icon: 'none',
|
|
duration: 2000,
|
|
});
|
|
});
|
|
},
|
|
|
|
/** 下载打印 */
|
|
exportToPrint() {
|
|
console.log('this.canvas:', this.canvas);
|
|
if (this.canvas && this.data.cardList.length > 0) {
|
|
wx.canvasToTempFilePath({
|
|
canvas: this.canvas,
|
|
fileType: 'png',
|
|
quality: 1,
|
|
success: (res) => {
|
|
wx.getImageInfo({
|
|
src: res.tempFilePath,
|
|
success: (res) =>
|
|
console.log(
|
|
'getImageInfo image size :',
|
|
res.width,
|
|
res.height,
|
|
), // 应输出2480x3508
|
|
});
|
|
wx.saveImageToPhotosAlbum({
|
|
filePath: res.tempFilePath,
|
|
success: () => wx.showToast({ title: '保存成功' }),
|
|
});
|
|
},
|
|
});
|
|
return;
|
|
}
|
|
},
|
|
|
|
onColorTap(e: WechatMiniprogram.CustomEvent) {
|
|
const { key, word, color } = e.detail;
|
|
this.setData({
|
|
showColorPopup: true,
|
|
currentKey: key,
|
|
currentColor: color,
|
|
});
|
|
},
|
|
|
|
onCloseColorPopup() {
|
|
this.setData({
|
|
showColorPopup: false,
|
|
currentKey: 0,
|
|
currentColor: '',
|
|
});
|
|
},
|
|
|
|
onChangeColor(e: WechatMiniprogram.CustomEvent) {
|
|
const { color } = e.detail;
|
|
const { currentKey, cardList } = this.data;
|
|
cardList[currentKey].color = color;
|
|
this.setData(
|
|
{
|
|
showColorPopup: false,
|
|
cardList,
|
|
},
|
|
() => {
|
|
this.drawCanvas();
|
|
},
|
|
);
|
|
},
|
|
|
|
onCloseIntroductionPopup() {
|
|
this.setData({ showIntroductionPopup: false });
|
|
wx.setStorageSync('hasShowIntroduction', true);
|
|
},
|
|
|
|
onShareAppMessage() {
|
|
return {
|
|
title: '涂鸦丫 - 涂色|识字|画画|打印',
|
|
path: '/pages/index/index',
|
|
};
|
|
},
|
|
onShareTimeline() {
|
|
return {
|
|
title: '涂鸦丫 - 涂色|识字|画画|打印',
|
|
query: '/pages/index/index',
|
|
};
|
|
},
|
|
});
|