feat: 文本绘制测试页面
This commit is contained in:
+17
-1
@@ -2,5 +2,21 @@
|
|||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
"tabWidth": 4,
|
"tabWidth": 4,
|
||||||
"printWidth": 200
|
"printWidth": 100,
|
||||||
|
"formatOnSave": true,
|
||||||
|
"bracketSameLine": true,
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "*.wxml",
|
||||||
|
"options": { "parser": "html" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "*.wxss",
|
||||||
|
"options": { "parser": "css" }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"files": "*.wxs",
|
||||||
|
"options": { "parser": "babel" }
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
{
|
{
|
||||||
"pages": ["pages/index/index", "pages/logs/logs", "demoPages/textPaint/textPaint"],
|
"pages": [
|
||||||
"window": {
|
"pages/index/index",
|
||||||
"navigationBarTextStyle": "black",
|
"pages/logs/logs",
|
||||||
"navigationStyle": "custom"
|
"demoPages/textPaint/textPaint",
|
||||||
},
|
"demoPages/textPaint2/textPaint"
|
||||||
|
],
|
||||||
|
"window": {},
|
||||||
"style": "v2",
|
"style": "v2",
|
||||||
"rendererOptions": {
|
"rendererOptions": {
|
||||||
"skyline": {
|
"skyline": {
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
/**app.wxss**/
|
/**app.wxss**/
|
||||||
.container {
|
// .container {
|
||||||
height: 100%;
|
// height: 100%;
|
||||||
display: flex;
|
// display: flex;
|
||||||
flex-direction: column;
|
// flex-direction: column;
|
||||||
align-items: center;
|
// align-items: center;
|
||||||
justify-content: space-between;
|
// justify-content: space-between;
|
||||||
padding: 200rpx 0;
|
// padding: 200rpx 0;
|
||||||
box-sizing: border-box;
|
// box-sizing: border-box;
|
||||||
}
|
// }
|
||||||
@@ -22,7 +22,5 @@ App<IAppOption>({
|
|||||||
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
// 发送 res.code 到后台换取 openId, sessionKey, unionId
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const a = '123';
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,20 +1,37 @@
|
|||||||
.color-picker {
|
// .color-picker {
|
||||||
display: flex;
|
// display: flex;
|
||||||
justify-content: center;
|
// justify-content: center;
|
||||||
padding: 20rpx;
|
// padding: 20rpx;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .color-circle {
|
||||||
|
// width: 80rpx;
|
||||||
|
// height: 80rpx;
|
||||||
|
// border-radius: 50%;
|
||||||
|
// margin: 0 40rpx;
|
||||||
|
// border: 4rpx solid #333;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// .action-btn {
|
||||||
|
// width: 60%;
|
||||||
|
// background: #4CAF50;
|
||||||
|
// color: white;
|
||||||
|
// margin: 40rpx auto;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.container {
|
||||||
|
height: 100vh;
|
||||||
|
background-color: transparent;
|
||||||
|
// overflow-y: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-circle {
|
.canvas-container {
|
||||||
width: 80rpx;
|
margin: 20rpx;
|
||||||
height: 80rpx;
|
width: calc(100% - 40rpx);
|
||||||
border-radius: 50%;
|
// width: 100%;
|
||||||
margin: 0 40rpx;
|
height: 86%;
|
||||||
border: 4rpx solid #333;
|
// height: calc(100% - 80rpx);
|
||||||
}
|
border: 1rpx solid #333;
|
||||||
|
background-color: #fff;
|
||||||
.action-btn {
|
box-sizing: border-box;
|
||||||
width: 60%;
|
|
||||||
background: #4CAF50;
|
|
||||||
color: white;
|
|
||||||
margin: 40rpx auto;
|
|
||||||
}
|
}
|
||||||
@@ -3,20 +3,21 @@ Page({
|
|||||||
ctx: null as RenderingContext | null,
|
ctx: null as RenderingContext | null,
|
||||||
data: {
|
data: {
|
||||||
characters: ['鱼', '鸟', '牛', '羊'] as const, // 固定汉字类型
|
characters: ['鱼', '鸟', '牛', '羊'] as const, // 固定汉字类型
|
||||||
colorMap: new Map([
|
colorMap: {
|
||||||
// 颜色映射关系
|
鱼: '#2196F3', // 蓝色
|
||||||
['鱼', '#2196F3'], // 蓝色
|
鸟: '#FFEB3B', // 黄色
|
||||||
['鸟', '#FFEB3B'], // 黄色
|
牛: '#FF9800', // 橙色
|
||||||
['牛', '#FF9800'], // 橙色
|
羊: '#9C27B0', // 紫色
|
||||||
['羊', '#9C27B0'], // 紫色
|
} as Record<string, string>,
|
||||||
]),
|
|
||||||
matrix: [] as string[], // 随机汉字矩阵
|
matrix: [] as string[], // 随机汉字矩阵
|
||||||
selectedColor: '', // 当前选中颜色
|
selectedColor: '', // 当前选中颜色
|
||||||
selectedChar: '', // 当前选中汉字
|
selectedChar: '', // 当前选中汉字
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
console.log('textPaint2 onLoad');
|
||||||
this.generateMatrix();
|
this.generateMatrix();
|
||||||
|
this.initCanvas();
|
||||||
},
|
},
|
||||||
|
|
||||||
// 生成6列随机矩阵
|
// 生成6列随机矩阵
|
||||||
@@ -33,36 +34,59 @@ Page({
|
|||||||
|
|
||||||
// 初始化A4画布(300DPI)
|
// 初始化A4画布(300DPI)
|
||||||
initCanvas() {
|
initCanvas() {
|
||||||
const dpi = 300;
|
|
||||||
const width = 2480,
|
|
||||||
height = 3508; // A4精确像素
|
|
||||||
|
|
||||||
wx.createSelectorQuery()
|
wx.createSelectorQuery()
|
||||||
.select('#canvas')
|
.select('#textCanvas')
|
||||||
.node()
|
.fields({
|
||||||
|
node: true,
|
||||||
|
size: true,
|
||||||
|
})
|
||||||
.exec((res) => {
|
.exec((res) => {
|
||||||
const canvas = res[0].node;
|
const canvas = res[0].node;
|
||||||
this.canvas = canvas;
|
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
this.canvas = canvas;
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
|
this.setCanvasSize(canvas, ctx);
|
||||||
// 设置物理尺寸
|
// ctx.fillRect(0, 0, 2480, 3508);
|
||||||
canvas.width = width;
|
|
||||||
canvas.height = height;
|
|
||||||
|
|
||||||
// 适配屏幕显示
|
|
||||||
const ratio = wx.getWindowInfo().pixelRatio;
|
|
||||||
canvas.style.width = `${width / ratio}px`;
|
|
||||||
ctx.scale(ratio, ratio);
|
|
||||||
|
|
||||||
this.drawGameBoard(ctx);
|
this.drawGameBoard(ctx);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setCanvasSize(canvas: Canvas, ctx: RenderingContext) {
|
||||||
|
const A4 = {
|
||||||
|
width: 2480,
|
||||||
|
height: 3508,
|
||||||
|
};
|
||||||
|
const { pixelRatio: dpr, windowWidth, windowHeight } = wx.getWindowInfo();
|
||||||
|
// const printWidth = A4.width;
|
||||||
|
// const printHeight = A4.height;
|
||||||
|
// @ts-ignore
|
||||||
|
const originWidth = canvas._width || windowWidth;
|
||||||
|
// @ts-ignore
|
||||||
|
const originHeight = canvas._height || windowHeight;
|
||||||
|
|
||||||
|
console.log('originWidth---:', originWidth);
|
||||||
|
console.log('originHeight---:', originHeight);
|
||||||
|
|
||||||
|
canvas.width = A4.width;
|
||||||
|
canvas.height = A4.height;
|
||||||
|
console.log('canvas----:', canvas);
|
||||||
|
|
||||||
|
// 计算显示比例
|
||||||
|
// const scaleRatio = Math.min(originWidth / printWidth, originHeight / printHeight);
|
||||||
|
// console.log('scaleRatio---:', scaleRatio);
|
||||||
|
// console.log('dpr---:', dpr);
|
||||||
|
// 设置坐标系
|
||||||
|
// ctx.scale(scaleRatio * dpr, scaleRatio * dpr);
|
||||||
|
},
|
||||||
|
|
||||||
// 绘制完整游戏界面
|
// 绘制完整游戏界面
|
||||||
drawGameBoard(ctx?: RenderingContext) {
|
drawGameBoard(ctx?: RenderingContext) {
|
||||||
|
const canvas = this.canvas as Canvas;
|
||||||
ctx = ctx || (this.ctx as RenderingContext);
|
ctx = ctx || (this.ctx as RenderingContext);
|
||||||
ctx.clearRect(0, 0, 2480, 3508);
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
ctx.fillStyle = '#333'; // 设置填充色为白色
|
||||||
|
ctx.fillRect(0, 0, 2480, 3508); // 覆盖整个A4画布
|
||||||
|
|
||||||
// 绘制标题
|
// 绘制标题
|
||||||
ctx.font = 'bold 80px "Microsoft Yahei"';
|
ctx.font = 'bold 80px "Microsoft Yahei"';
|
||||||
@@ -78,11 +102,12 @@ Page({
|
|||||||
|
|
||||||
// 绘制颜色示例
|
// 绘制颜色示例
|
||||||
drawColorLegend(ctx: RenderingContext, y: number) {
|
drawColorLegend(ctx: RenderingContext, y: number) {
|
||||||
|
console.log('this.data:', this.data);
|
||||||
let x = 500;
|
let x = 500;
|
||||||
this.data.characters.forEach((char) => {
|
this.data.characters.forEach((char) => {
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(x, y, 50, 0, Math.PI * 2);
|
ctx.arc(x, y, 50, 0, Math.PI * 2);
|
||||||
ctx.fillStyle = this.data.colorMap.get(char) as string;
|
ctx.fillStyle = this.data.colorMap[char] as string;
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
ctx.strokeStyle = '#333';
|
ctx.strokeStyle = '#333';
|
||||||
ctx.lineWidth = 4;
|
ctx.lineWidth = 4;
|
||||||
@@ -95,8 +120,10 @@ Page({
|
|||||||
drawCharacterMatrix(ctx: RenderingContext, startY: number) {
|
drawCharacterMatrix(ctx: RenderingContext, startY: number) {
|
||||||
const cols = 6;
|
const cols = 6;
|
||||||
const cellSize = 350; // 每个单元格大小
|
const cellSize = 350; // 每个单元格大小
|
||||||
|
const colorMap = this.data.colorMap;
|
||||||
|
|
||||||
this.data.matrix.forEach((char, index) => {
|
this.data.matrix.forEach((char: string, index) => {
|
||||||
|
char = char || '';
|
||||||
const row = Math.floor(index / cols);
|
const row = Math.floor(index / cols);
|
||||||
const col = index % cols;
|
const col = index % cols;
|
||||||
|
|
||||||
@@ -115,7 +142,7 @@ Page({
|
|||||||
|
|
||||||
// 绘制汉字
|
// 绘制汉字
|
||||||
ctx.font = 'bold 100px "Microsoft Yahei"';
|
ctx.font = 'bold 100px "Microsoft Yahei"';
|
||||||
ctx.fillStyle = this.data.colorMap.get(char) || '';
|
ctx.fillStyle = (colorMap[char] as string) || '';
|
||||||
ctx.textAlign = 'center';
|
ctx.textAlign = 'center';
|
||||||
ctx.textBaseline = 'middle';
|
ctx.textBaseline = 'middle';
|
||||||
ctx.fillText(char, x, y);
|
ctx.fillText(char, x, y);
|
||||||
@@ -127,7 +154,7 @@ Page({
|
|||||||
const index = e.currentTarget.dataset.index;
|
const index = e.currentTarget.dataset.index;
|
||||||
const selectedChar = this.data.characters[index];
|
const selectedChar = this.data.characters[index];
|
||||||
this.setData({
|
this.setData({
|
||||||
selectedColor: this.data.colorMap.get(selectedChar),
|
selectedColor: this.data.colorMap[selectedChar],
|
||||||
selectedChar,
|
selectedChar,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -137,7 +164,9 @@ Page({
|
|||||||
const index = e.currentTarget.dataset.index;
|
const index = e.currentTarget.dataset.index;
|
||||||
if (!this.data.selectedColor) return;
|
if (!this.data.selectedColor) return;
|
||||||
|
|
||||||
const matrix = this.data.matrix.map((char, i) => (i === index ? this.data.selectedChar : char));
|
const matrix = this.data.matrix.map((char, i) =>
|
||||||
|
i === index ? this.data.selectedChar : char,
|
||||||
|
);
|
||||||
|
|
||||||
this.setData({ matrix }, () => {
|
this.setData({ matrix }, () => {
|
||||||
this.drawGameBoard();
|
this.drawGameBoard();
|
||||||
@@ -146,12 +175,18 @@ Page({
|
|||||||
|
|
||||||
// 导出A4图片
|
// 导出A4图片
|
||||||
exportToPrint() {
|
exportToPrint() {
|
||||||
|
console.log('this.canvas:', this.canvas);
|
||||||
if (this.canvas) {
|
if (this.canvas) {
|
||||||
wx.canvasToTempFilePath({
|
wx.canvasToTempFilePath({
|
||||||
canvas: this.canvas,
|
canvas: this.canvas,
|
||||||
fileType: 'png',
|
fileType: 'png',
|
||||||
quality: 1,
|
quality: 1,
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
|
wx.getImageInfo({
|
||||||
|
src: res.tempFilePath,
|
||||||
|
success: (res) =>
|
||||||
|
console.log('getImageInfo image size :', res.width, res.height), // 应输出2480x3508
|
||||||
|
});
|
||||||
wx.saveImageToPhotosAlbum({
|
wx.saveImageToPhotosAlbum({
|
||||||
filePath: res.tempFilePath,
|
filePath: res.tempFilePath,
|
||||||
success: () => wx.showToast({ title: '保存成功' }),
|
success: () => wx.showToast({ title: '保存成功' }),
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<view class="container">
|
<view class="container">
|
||||||
<!-- 颜色选择区 -->
|
<!-- 颜色选择区 -->
|
||||||
<view class="color-picker">
|
<!-- <view class="color-picker">
|
||||||
<block wx:for="{{characters}}" wx:key="index">
|
<block wx:for="{{characters}}" wx:key="index">
|
||||||
<view
|
<view
|
||||||
class="color-circle"
|
class="color-circle"
|
||||||
@@ -8,10 +8,10 @@
|
|||||||
bindtap="handleColorSelect"
|
bindtap="handleColorSelect"
|
||||||
data-index="{{index}}"></view>
|
data-index="{{index}}"></view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view> -->
|
||||||
|
|
||||||
<!-- 画布容器 -->
|
<!-- 画布容器 -->
|
||||||
<canvas type="2d" id="canvas" style="width: 100%; height: 80vh" />
|
<canvas type="2d" id="textCanvas" class="canvas-container" />
|
||||||
|
|
||||||
<!-- 操作按钮 -->
|
<!-- 操作按钮 -->
|
||||||
<button class="action-btn" bindtap="exportToPrint">导出A4图片</button>
|
<button class="action-btn" bindtap="exportToPrint">导出A4图片</button>
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ Page({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 1,
|
key: 1,
|
||||||
title: '文本绘制',
|
title: '文本绘制2',
|
||||||
url: '/demoPages/textPaint/textPaint',
|
url: '/demoPages/textPaint2/textPaint',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 2,
|
key: 2,
|
||||||
@@ -23,4 +23,10 @@ Page({
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
tapCard(e: WechatMiniprogram.TouchEvent) {
|
||||||
|
const { url } = e.currentTarget.dataset;
|
||||||
|
console.log('navigateTo url:', url);
|
||||||
|
wx.navigateTo({ url });
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,9 +2,10 @@
|
|||||||
<scroll-view class="scroll-view" scroll-y type="list">
|
<scroll-view class="scroll-view" scroll-y type="list">
|
||||||
<view
|
<view
|
||||||
class="card"
|
class="card"
|
||||||
x:for="{{cards}}"
|
wx:for="{{cards}}"
|
||||||
wx:for-item="card"
|
wx:for-item="card"
|
||||||
bindtap="tabCard"
|
wx:key="*this"
|
||||||
|
bindtap="tapCard"
|
||||||
data-url="{{card.url}}">
|
data-url="{{card.url}}">
|
||||||
<view class="card-title">{{card.title}}</view>
|
<view class="card-title">{{card.title}}</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@
|
|||||||
"postcss": false,
|
"postcss": false,
|
||||||
"minified": true,
|
"minified": true,
|
||||||
"minifyWXSS": true,
|
"minifyWXSS": true,
|
||||||
"enhance": true,
|
"enhance": false,
|
||||||
"showShadowRootInWxmlPanel": false,
|
"showShadowRootInWxmlPanel": false,
|
||||||
"packNpmRelationList": [
|
"packNpmRelationList": [
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"ignoreUploadUnusedFiles": true,
|
"ignoreUploadUnusedFiles": true,
|
||||||
"compileHotReLoad": false,
|
"compileHotReLoad": false,
|
||||||
"skylineRenderEnable": true,
|
"skylineRenderEnable": true,
|
||||||
"es6": true,
|
"es6": false,
|
||||||
"packNpmManually": true
|
"packNpmManually": true
|
||||||
},
|
},
|
||||||
"simulatorType": "wechat",
|
"simulatorType": "wechat",
|
||||||
|
|||||||
@@ -4,5 +4,23 @@
|
|||||||
"setting": {
|
"setting": {
|
||||||
"compileHotReLoad": true
|
"compileHotReLoad": true
|
||||||
},
|
},
|
||||||
"libVersion": "2.32.3"
|
"libVersion": "3.7.10",
|
||||||
|
"condition": {
|
||||||
|
"miniprogram": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"name": "textPaint2",
|
||||||
|
"pathName": "demoPages/textPaint2/textPaint",
|
||||||
|
"query": "",
|
||||||
|
"launchMode": "default",
|
||||||
|
"scene": null
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "db guide",
|
||||||
|
"pathName": "pages/databaseGuide/databaseGuide",
|
||||||
|
"query": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
// 全局声明
|
// 全局声明
|
||||||
type Canvas = WechatMiniprogram.Canvas;
|
type Canvas = WechatMiniprogram.Canvas;
|
||||||
type RenderingContext = WechatMiniprogram.CanvasRenderingContext;
|
type RenderingContext = WechatMiniprogram.CanvasRenderingContext2D;
|
||||||
|
type TouchEvent = WechatMiniprogram.TouchEvent;
|
||||||
|
|||||||
Reference in New Issue
Block a user