feat: 生产 shape
This commit is contained in:
@@ -1,68 +1,173 @@
|
||||
import { SHAPES, ShapeCard } from '../../constants/shapes';
|
||||
import { WATER_COLORS, PAPER_SIZE } from '../../constants/colors';
|
||||
|
||||
import ShapeDrawService from '../../service/shapeDrawService';
|
||||
import { checkAndSaveImage } from '../../utils/saveImage';
|
||||
|
||||
|
||||
Page({
|
||||
canvas: null as Canvas | null,
|
||||
ctx: null as RenderingContext | null,
|
||||
boxHeight: 0,
|
||||
boxWidth: 0,
|
||||
shapeDrawService: null as ShapeDrawService | null,
|
||||
|
||||
data: {
|
||||
shapeList: [] as ShapeCard[],
|
||||
showSelectShapePopup: false,
|
||||
currentShapeKey: '',
|
||||
currentShapeId: '',
|
||||
showColorPopup: false,
|
||||
currentIndex: 0,
|
||||
currentColor: '',
|
||||
isPCDevtool: false,
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
// 判断是否在PC端开发工具上运行
|
||||
// const systemInfo = wx.getDeviceInfo();
|
||||
// if (systemInfo.platform === 'devtools') {
|
||||
// this.setData({
|
||||
// isPCDevtool: true,
|
||||
// });
|
||||
// }
|
||||
|
||||
this.refreshShapeCard();
|
||||
},
|
||||
|
||||
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.shapeDrawService = new ShapeDrawService(canvas, ctx);
|
||||
// shapeDrawService.draw();
|
||||
|
||||
this.setData({ boxWidth, boxHeight });
|
||||
this.drawCanvas();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/** 变更shapeList 并更新canvas */
|
||||
drawCanvas(
|
||||
updatedShapeList?: ShapeCard[],
|
||||
callback: () => void = () => { },
|
||||
) {
|
||||
if (updatedShapeList) {
|
||||
this.setData({ shapeList: updatedShapeList }, () => {
|
||||
this.shapeDrawService?.draw(updatedShapeList!);
|
||||
callback();
|
||||
});
|
||||
} else {
|
||||
const shapeList = this.data.shapeList;
|
||||
this.shapeDrawService?.draw(shapeList);
|
||||
}
|
||||
},
|
||||
|
||||
openSelectShapePopup(e: any) {
|
||||
const { key } = e.detail;
|
||||
this.setData({
|
||||
showSelectShapePopup: true,
|
||||
currentShapeKey: key
|
||||
currentShapeId: key
|
||||
});
|
||||
},
|
||||
|
||||
closeSelectShapePopup() {
|
||||
this.setData({
|
||||
showSelectShapePopup: false,
|
||||
currentShapeKey: ''
|
||||
currentShapeId: ''
|
||||
});
|
||||
},
|
||||
|
||||
onChangeShape(e: any) {
|
||||
const { shape, currentShapeKey, shapes } = e.detail;
|
||||
console.log('shape', shape);
|
||||
console.log('shapes', shapes);
|
||||
if (currentShapeKey) {
|
||||
this.setData({
|
||||
showSelectShapePopup: false,
|
||||
currentShapeKey: '',
|
||||
shapeList: this.data.shapeList.map(item => {
|
||||
if (item.id === currentShapeKey) {
|
||||
return { ...item, fillColor: item.fillColor };
|
||||
}
|
||||
return item;
|
||||
})
|
||||
});
|
||||
} else {
|
||||
// 随机从 WATER_COLORS.basic12 中获取不重复的颜色
|
||||
const colorList = WATER_COLORS.basic12.map(item => item.hex);
|
||||
const colorsCopy = [...colorList];
|
||||
for (let i = colorsCopy.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[colorsCopy[i], colorsCopy[j]] = [colorsCopy[j], colorsCopy[i]];
|
||||
}
|
||||
const selectedColors = colorsCopy.slice(0, shapes.length);
|
||||
const { shapes } = e.detail;
|
||||
const prevShapeList: ShapeCard[] = this.data.shapeList || [];
|
||||
// 1. 保留已选图形的 fillColor,不变
|
||||
// 2. 新增的图形分配未被占用的颜色,且不重复
|
||||
|
||||
this.setData({
|
||||
showSelectShapePopup: false,
|
||||
currentShapeKey: '',
|
||||
shapeList: shapes.map((item: ShapeCard, idx: number) => ({
|
||||
...item,
|
||||
fillColor: selectedColors[idx] || item.fillColor
|
||||
}))
|
||||
});
|
||||
// 获取所有可用颜色
|
||||
const colorList = WATER_COLORS.basic12.map(item => item.hex);
|
||||
|
||||
// 记录已被使用的颜色(只考虑当前 shapeList 中的 fillColor)
|
||||
const usedColors = prevShapeList.map(item => item.fillColor).filter(Boolean);
|
||||
|
||||
// 新的 shapeList
|
||||
const newShapeList: ShapeCard[] = [];
|
||||
|
||||
// 记录已分配的颜色,避免重复
|
||||
const assignedColors = [...usedColors];
|
||||
|
||||
// 先将 shapes 转为 Map,方便查找
|
||||
const prevShapeMap = new Map(prevShapeList.map(item => [item.id, item]));
|
||||
|
||||
// 随机打乱剩余可用颜色
|
||||
function shuffle(arr: string[]) {
|
||||
for (let i = arr.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[arr[i], arr[j]] = [arr[j], arr[i]];
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
// 计算未被占用的颜色
|
||||
let availableColors = colorList.filter(color => !assignedColors.includes(color));
|
||||
availableColors = shuffle(availableColors);
|
||||
|
||||
shapes.forEach((item: ShapeCard) => {
|
||||
if (prevShapeMap.has(item.id)) {
|
||||
// 已存在,保留原有 fillColor
|
||||
newShapeList.push({
|
||||
...item,
|
||||
fillColor: prevShapeMap.get(item.id)!.fillColor
|
||||
});
|
||||
} else {
|
||||
// 新增,分配未被占用的颜色
|
||||
const color = availableColors.shift() || colorList[0];
|
||||
assignedColors.push(color);
|
||||
newShapeList.push({
|
||||
...item,
|
||||
fillColor: color
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
this.setData({
|
||||
showSelectShapePopup: false,
|
||||
currentShapeId: '',
|
||||
shapeList: newShapeList
|
||||
}, () => {
|
||||
// 绘制canvas
|
||||
this.drawCanvas();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 随机生成6个图形
|
||||
@@ -94,6 +199,95 @@ Page({
|
||||
// 更新数据
|
||||
this.setData({
|
||||
shapeList
|
||||
}, () => {
|
||||
// 绘制canvas
|
||||
this.drawCanvas();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
onDelete(e: any) {
|
||||
const { index } = e.detail;
|
||||
const newShapeList = this.data.shapeList.filter((item, i) => i !== index);
|
||||
this.setData({
|
||||
shapeList: newShapeList
|
||||
}, () => {
|
||||
// 绘制canvas
|
||||
this.drawCanvas();
|
||||
});
|
||||
},
|
||||
onColorTap(e: any) {
|
||||
const { index, fillColor } = e.detail;
|
||||
console.log('shape Page onColorTap', index, fillColor);
|
||||
this.setData({
|
||||
showColorPopup: true,
|
||||
currentColor: fillColor,
|
||||
currentIndex: index
|
||||
});
|
||||
},
|
||||
onCloseColorPopup() {
|
||||
this.setData({
|
||||
showColorPopup: false,
|
||||
currentColor: '',
|
||||
currentIndex: 0
|
||||
});
|
||||
},
|
||||
onChangeColor(e: any) {
|
||||
const { color } = e.detail;
|
||||
const { currentIndex } = this.data;
|
||||
|
||||
this.setData({
|
||||
showColorPopup: false,
|
||||
[`shapeList[${currentIndex}].fillColor`]: color
|
||||
}, () => {
|
||||
// 绘制canvas
|
||||
this.drawCanvas();
|
||||
})
|
||||
},
|
||||
|
||||
// 测试ShapeDrawService
|
||||
// testShapeDrawService() {
|
||||
// if (!this.shapeDrawService) {
|
||||
// wx.showToast({
|
||||
// title: 'Canvas未初始化',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 使用当前选中的图形进行测试
|
||||
// const testShapes = this.data.shapeList.slice(0, 3); // 只测试前3个图形
|
||||
// if (testShapes.length === 0) {
|
||||
// wx.showToast({
|
||||
// title: '请先选择图形',
|
||||
// icon: 'none'
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
// this.shapeDrawService.draw(testShapes);
|
||||
// wx.showToast({
|
||||
// title: '绘制完成',
|
||||
// icon: 'success'
|
||||
// });
|
||||
// },
|
||||
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: '涂鸦丫-涂色|识字|画画|打印',
|
||||
path: '/pages/index/index',
|
||||
};
|
||||
},
|
||||
onShareTimeline() {
|
||||
return {
|
||||
title: '涂鸦丫-涂色|识字|画画|打印',
|
||||
query: '/pages/index/index',
|
||||
};
|
||||
},
|
||||
|
||||
/** 下载打印 */
|
||||
exportToPrint() {
|
||||
if (this.canvas && this.data.shapeList.length > 0) {
|
||||
checkAndSaveImage(this.canvas);
|
||||
return;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user