feat:V2.5.5方格推理
This commit is contained in:
@@ -31,7 +31,8 @@
|
||||
"shapeSymbol/shapeSymbol",
|
||||
"colorPattern/colorPattern",
|
||||
"matchConnect/matchConnect",
|
||||
"lineRecognition/lineRecognition"
|
||||
"lineRecognition/lineRecognition",
|
||||
"gridReasoning/gridReasoning"
|
||||
],
|
||||
"independent": false
|
||||
}
|
||||
|
||||
@@ -56,6 +56,14 @@ export const FOCUS_FUNCTION_TYPES: FocusFunctionType[] = [
|
||||
desc: '认识不同线条,画出颜色对应的线条',
|
||||
icon: '📏',
|
||||
},
|
||||
// 方格推理
|
||||
{
|
||||
id: 'grid-reasoning',
|
||||
page: 'gridReasoning',
|
||||
title: '方格推理',
|
||||
desc: '仔细观察,推理出合并方格并连线',
|
||||
icon: '🧩',
|
||||
},
|
||||
// 格子仿画
|
||||
{
|
||||
id: 'grid-drawing-3x3',
|
||||
|
||||
@@ -17,8 +17,9 @@
|
||||
type-actions="{{typeActions}}"
|
||||
bind:select="onSelectType"
|
||||
bind:random="onRandom" />
|
||||
<ad-custom unit-id="adunit-89cff2de998f1146"></ad-custom>
|
||||
</view>
|
||||
<ad-custom unit-id="adunit-89cff2de998f1146"></ad-custom>
|
||||
|
||||
<view class="empty"></view>
|
||||
</view>
|
||||
<math-bottom-buttons
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"navigationBarTitleText": "方格推理",
|
||||
"navigationBarBackgroundColor": "#FFD719",
|
||||
"homeButton": true,
|
||||
"backgroundColor": "#F6F6F6",
|
||||
"enablePullDownRefresh": false,
|
||||
"usingComponents": {
|
||||
"share-guide-popup": "../../components/share-guide-popup/share-guide-popup",
|
||||
"math-bottom-buttons": "../../components/math-bottom-buttons/math-bottom-buttons",
|
||||
"math-type-selector": "../../components/math-type-selector/math-type-selector"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
import GridReasoningDraw from '../shared/service/gridReasoningDraw';
|
||||
import { createFocusPage } from '../shared/common/focusPageMixin';
|
||||
import {
|
||||
GridReasoningData,
|
||||
GridPosition,
|
||||
} from '../shared/service/gridReasoningDraw';
|
||||
import { NUMBER_COLORS } from '../../constants/colors';
|
||||
|
||||
createFocusPage({
|
||||
canvas: null as Canvas | null,
|
||||
ctx: null as RenderingContext | null,
|
||||
boxHeight: 0,
|
||||
boxWidth: 0,
|
||||
drawService: null as GridReasoningDraw | null,
|
||||
gridData: null as GridReasoningData | null,
|
||||
|
||||
data: {
|
||||
pageTitle: '方格推理',
|
||||
functionId: '',
|
||||
hasContent: false,
|
||||
showShareDialog: false,
|
||||
currentOperatorType: 'mixed', // 'addition', 'subtraction', 'mixed'
|
||||
currentOperatorTypeName: '混合运算',
|
||||
operatorTypeActions: [
|
||||
{ name: '加法运算', value: 'addition' },
|
||||
{ name: '减法运算', value: 'subtraction' },
|
||||
{ name: '混合运算', value: 'mixed' },
|
||||
],
|
||||
},
|
||||
|
||||
onLoad(options: { id?: string }) {
|
||||
const functionId = options.id || 'grid-reasoning';
|
||||
this.setData({
|
||||
functionId,
|
||||
});
|
||||
this.initPageInfo(functionId, '方格推理');
|
||||
},
|
||||
|
||||
onReady() {
|
||||
this.initCanvas({
|
||||
createDrawService: (
|
||||
canvas: Canvas,
|
||||
ctx: RenderingContext,
|
||||
options?: Record<string, any>,
|
||||
) => {
|
||||
return new GridReasoningDraw(canvas, ctx, options);
|
||||
},
|
||||
drawServiceOptions: {
|
||||
title: this.data.pageTitle,
|
||||
subTitle: '仔细观察,推理出合并方格并连线',
|
||||
functionId: this.data.functionId,
|
||||
},
|
||||
onCanvasReady: () => {
|
||||
// 初始随机生成
|
||||
this.onRandom();
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 绘制Canvas内容
|
||||
*/
|
||||
async drawCanvas() {
|
||||
if (!this.ctx || !this.drawService || !this.gridData) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.drawService.draw(this.gridData);
|
||||
this.setData({ hasContent: true });
|
||||
} catch (error) {
|
||||
console.error('绘制失败:', error);
|
||||
this.setData({ hasContent: false });
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 选择运算类型
|
||||
*/
|
||||
onSelectType(event: any) {
|
||||
const { name, value } = event.detail;
|
||||
this.setData({
|
||||
currentOperatorType: value,
|
||||
currentOperatorTypeName: name,
|
||||
});
|
||||
// 重新生成题目
|
||||
this.onRandom();
|
||||
},
|
||||
|
||||
/**
|
||||
* 随机生成
|
||||
*/
|
||||
onRandom() {
|
||||
// 随机选择一种颜色
|
||||
const colorKeys = Object.keys(NUMBER_COLORS).map(Number);
|
||||
const randomColorKey =
|
||||
colorKeys[Math.floor(Math.random() * colorKeys.length)];
|
||||
const selectedColor = NUMBER_COLORS[randomColorKey];
|
||||
|
||||
const rows: Array<{
|
||||
grid1: GridPosition[];
|
||||
grid2: GridPosition[];
|
||||
operator: '+' | '-';
|
||||
result: GridPosition[];
|
||||
}> = [];
|
||||
|
||||
const operatorType = this.data.currentOperatorType;
|
||||
|
||||
// 生成5行的数据
|
||||
for (let i = 0; i < 5; i++) {
|
||||
// 根据选中的运算类型选择运算符
|
||||
let operator: '+' | '-';
|
||||
if (operatorType === 'addition') {
|
||||
operator = '+';
|
||||
} else if (operatorType === 'subtraction') {
|
||||
operator = '-';
|
||||
} else {
|
||||
// 混合运算:随机选择运算符
|
||||
operator = Math.random() > 0.5 ? '+' : '-';
|
||||
}
|
||||
|
||||
// 生成第一个网格的涂色位置
|
||||
// 如果是减法运算,第一个网格至少要有2个位置
|
||||
let grid1Count: number;
|
||||
if (operator === '-') {
|
||||
grid1Count = Math.floor(Math.random() * 8) + 2; // 2-9个位置
|
||||
} else {
|
||||
grid1Count = Math.floor(Math.random() * 9) + 1; // 1-9个位置
|
||||
}
|
||||
const grid1Positions = this.generateRandomPositions(grid1Count);
|
||||
|
||||
let grid2Positions: GridPosition[];
|
||||
let resultPositions: GridPosition[];
|
||||
|
||||
if (operator === '+') {
|
||||
// 加法:生成第二个网格的涂色位置(至少1个)
|
||||
const grid2Count = Math.floor(Math.random() * 9) + 1;
|
||||
grid2Positions = this.generateRandomPositions(grid2Count);
|
||||
|
||||
// 结果 = 并集
|
||||
resultPositions = this.unionPositions(
|
||||
grid1Positions,
|
||||
grid2Positions,
|
||||
);
|
||||
} else {
|
||||
// 减法:生成第二个网格的涂色位置(必须少于第一个)
|
||||
const maxGrid2Count = grid1Count - 1;
|
||||
const grid2Count =
|
||||
Math.floor(Math.random() * maxGrid2Count) + 1;
|
||||
grid2Positions = this.generateRandomPositions(grid2Count);
|
||||
|
||||
// 结果 = 差集
|
||||
resultPositions = this.subtractPositions(
|
||||
grid1Positions,
|
||||
grid2Positions,
|
||||
);
|
||||
}
|
||||
|
||||
rows.push({
|
||||
grid1: grid1Positions,
|
||||
grid2: grid2Positions,
|
||||
operator: operator as '+' | '-',
|
||||
result: resultPositions,
|
||||
});
|
||||
}
|
||||
|
||||
// 生成右侧答案选项
|
||||
// 右侧展示左侧5行的结果(result),顺序随机
|
||||
const answerOptions: Array<{
|
||||
positions: GridPosition[];
|
||||
rowIndex: number;
|
||||
}> = [];
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
answerOptions.push({
|
||||
positions: rows[i].result,
|
||||
rowIndex: i,
|
||||
});
|
||||
}
|
||||
|
||||
// 随机打乱顺序
|
||||
answerOptions.sort(() => Math.random() - 0.5);
|
||||
|
||||
this.gridData = {
|
||||
rows,
|
||||
answerOptions,
|
||||
color: selectedColor,
|
||||
};
|
||||
|
||||
this.drawCanvas();
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成随机位置(不重复)
|
||||
*/
|
||||
generateRandomPositions(count: number): GridPosition[] {
|
||||
const allPositions: GridPosition[] = [];
|
||||
for (let y = 0; y < 3; y++) {
|
||||
for (let x = 0; x < 3; x++) {
|
||||
allPositions.push({ x, y });
|
||||
}
|
||||
}
|
||||
|
||||
// 随机打乱
|
||||
const shuffled = [...allPositions].sort(() => Math.random() - 0.5);
|
||||
|
||||
// 返回前count个
|
||||
return shuffled.slice(0, count);
|
||||
},
|
||||
|
||||
/**
|
||||
* 计算位置的并集
|
||||
*/
|
||||
unionPositions(pos1: GridPosition[], pos2: GridPosition[]): GridPosition[] {
|
||||
const set = new Set<string>();
|
||||
const result: GridPosition[] = [];
|
||||
|
||||
// 添加第一个数组的位置
|
||||
for (const pos of pos1) {
|
||||
const key = `${pos.x},${pos.y}`;
|
||||
if (!set.has(key)) {
|
||||
set.add(key);
|
||||
result.push(pos);
|
||||
}
|
||||
}
|
||||
|
||||
// 添加第二个数组的位置(去重)
|
||||
for (const pos of pos2) {
|
||||
const key = `${pos.x},${pos.y}`;
|
||||
if (!set.has(key)) {
|
||||
set.add(key);
|
||||
result.push(pos);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* 计算位置的差集(pos1 - pos2)
|
||||
*/
|
||||
subtractPositions(
|
||||
pos1: GridPosition[],
|
||||
pos2: GridPosition[],
|
||||
): GridPosition[] {
|
||||
const set2 = new Set<string>();
|
||||
for (const pos of pos2) {
|
||||
set2.add(`${pos.x},${pos.y}`);
|
||||
}
|
||||
|
||||
const result: GridPosition[] = [];
|
||||
for (const pos of pos1) {
|
||||
const key = `${pos.x},${pos.y}`;
|
||||
if (!set2.has(key)) {
|
||||
result.push(pos);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
<view class="page-container">
|
||||
<view class="wrapper">
|
||||
<text class="wrapper-title">预览打印效果</text>
|
||||
|
||||
<!-- 预览打印效果 -->
|
||||
<view id="canvasWrapper" class="canvas-wrapper">
|
||||
<canvas
|
||||
type="2d"
|
||||
id="canvasContent"
|
||||
class="canvas-content"
|
||||
style="width:{{boxWidth}}px;height:{{boxHeight}}px" />
|
||||
</view>
|
||||
|
||||
<!-- 类型选择器和随机生成按钮 -->
|
||||
<math-type-selector
|
||||
current-type-name="{{currentOperatorTypeName}}"
|
||||
type-actions="{{operatorTypeActions}}"
|
||||
bind:select="onSelectType"
|
||||
bind:random="onRandom" />
|
||||
<ad-custom unit-id="adunit-89cff2de998f1146"></ad-custom>
|
||||
</view>
|
||||
<view class="empty"></view>
|
||||
</view>
|
||||
<math-bottom-buttons
|
||||
disabled="{{!hasContent}}"
|
||||
bind:share="onShareAppMessage"
|
||||
bind:export="exportToPrint" />
|
||||
<share-guide-popup
|
||||
show="{{showShareDialog}}"
|
||||
bind:onClose="onCloseShareDialog"
|
||||
bind:onShareSuccess="onShareSuccess" />
|
||||
@@ -0,0 +1 @@
|
||||
@import '../../base/baseDrawPage.wxss';
|
||||
@@ -0,0 +1,226 @@
|
||||
/**
|
||||
* 方格推理绘制服务
|
||||
*/
|
||||
|
||||
import { BaseDrawService } from '../../../service/baseDraw';
|
||||
|
||||
/**
|
||||
* 3x3网格中的位置坐标
|
||||
*/
|
||||
export interface GridPosition {
|
||||
x: number; // 0-2
|
||||
y: number; // 0-2
|
||||
}
|
||||
|
||||
/**
|
||||
* 方格推理数据
|
||||
*/
|
||||
export interface GridReasoningData {
|
||||
/** 每行的数据 */
|
||||
rows: Array<{
|
||||
/** 第一个方格涂色位置 */
|
||||
grid1: GridPosition[];
|
||||
/** 第二个方格涂色位置 */
|
||||
grid2: GridPosition[];
|
||||
/** 运算符:+ 或 - */
|
||||
operator: '+' | '-';
|
||||
/** 结果方格涂色位置 */
|
||||
result: GridPosition[];
|
||||
}>;
|
||||
/** 右侧答案选项(随机排列的方格) */
|
||||
answerOptions: Array<{
|
||||
/** 方格涂色位置 */
|
||||
positions: GridPosition[];
|
||||
/** 对应的行索引(用于匹配答案) */
|
||||
rowIndex: number;
|
||||
}>;
|
||||
/** 使用的颜色 */
|
||||
color: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 方格推理绘制服务
|
||||
*/
|
||||
class GridReasoningDraw extends BaseDrawService {
|
||||
gridData: GridReasoningData | null = null;
|
||||
|
||||
constructor(
|
||||
canvas: Canvas,
|
||||
ctx: RenderingContext,
|
||||
options?: Record<string, any>,
|
||||
) {
|
||||
super(canvas, ctx, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制方格推理内容
|
||||
*/
|
||||
async draw(gridData: GridReasoningData) {
|
||||
if (!gridData || !gridData.rows || !gridData.answerOptions) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setPrintConfig();
|
||||
this.gridData = gridData;
|
||||
this.clear();
|
||||
this.setPaper();
|
||||
|
||||
// 绘制Header
|
||||
if (this.headerType !== 'minimal') {
|
||||
await this.drawHeader();
|
||||
} else {
|
||||
this.drawMiniHeader();
|
||||
}
|
||||
|
||||
// 绘制内容区域
|
||||
this.drawDivider();
|
||||
await this.drawContent({
|
||||
canvas: this.canvas,
|
||||
ctx: this.ctx,
|
||||
gridData: this.gridData,
|
||||
canvasWidth: this.canvasWidth,
|
||||
startY: this.currentY,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制内容区域
|
||||
*/
|
||||
private async drawContent(params: {
|
||||
canvas: WechatMiniprogram.Canvas;
|
||||
ctx: RenderingContext;
|
||||
gridData: GridReasoningData;
|
||||
canvasWidth: number;
|
||||
startY: number;
|
||||
}): Promise<void> {
|
||||
const { ctx, gridData, canvasWidth } = params;
|
||||
let { startY } = params;
|
||||
|
||||
startY = startY + 30;
|
||||
|
||||
const margin = 40; // 左右边距
|
||||
const gridSize = 3; // 3x3网格
|
||||
const cellSize = 32; // 每个格子的宽度
|
||||
const gridWidth = cellSize * gridSize;
|
||||
const gridHeight = cellSize * gridSize;
|
||||
|
||||
// 左侧区域宽度(两个网格 + 运算符 + 间距)
|
||||
const gridSpacing = 15; // 两个网格之间的间距
|
||||
const operatorWidth = 40; // 运算符宽度
|
||||
const dotRadius = 7; // 圆点半径
|
||||
const dotSpacing = 20; // 圆点与网格的间距
|
||||
|
||||
// 右侧区域宽度(答案选项网格)
|
||||
const rightAreaWidth = gridWidth;
|
||||
const rightAreaStartX = canvasWidth - margin - rightAreaWidth;
|
||||
|
||||
// 行间距
|
||||
const rowSpacing = 38;
|
||||
|
||||
// 打乱答案选项的顺序,实现随机乱序
|
||||
const shuffledAnswers = [...gridData.answerOptions].sort(
|
||||
() => Math.random() - 0.5,
|
||||
);
|
||||
|
||||
// 绘制5行
|
||||
for (let rowIndex = 0; rowIndex < 5; rowIndex++) {
|
||||
const rowData = gridData.rows[rowIndex];
|
||||
if (!rowData) continue;
|
||||
|
||||
const rowY = startY + rowIndex * (gridHeight + rowSpacing);
|
||||
|
||||
// 绘制左侧第一个网格
|
||||
const grid1X = margin;
|
||||
this.drawGrid(
|
||||
ctx,
|
||||
grid1X,
|
||||
rowY,
|
||||
cellSize,
|
||||
gridSize,
|
||||
rowData.grid1,
|
||||
gridData.color,
|
||||
);
|
||||
|
||||
// 绘制运算符
|
||||
const operatorStartX = grid1X + gridWidth + gridSpacing;
|
||||
const operatorX = operatorStartX + operatorWidth / 2;
|
||||
const operatorY = rowY + gridHeight / 2;
|
||||
const operatorSize = 30; // 运算符大小
|
||||
this.drawSymbol(
|
||||
operatorX,
|
||||
operatorY,
|
||||
rowData.operator,
|
||||
operatorSize,
|
||||
);
|
||||
|
||||
// 绘制左侧第二个网格
|
||||
const grid2X = operatorStartX + operatorWidth + gridSpacing;
|
||||
this.drawGrid(
|
||||
ctx,
|
||||
grid2X,
|
||||
rowY,
|
||||
cellSize,
|
||||
gridSize,
|
||||
rowData.grid2,
|
||||
gridData.color,
|
||||
);
|
||||
|
||||
// 绘制左侧圆点(垂直居中)
|
||||
const leftDotX = grid2X + gridWidth + dotSpacing;
|
||||
const leftDotY = rowY + gridHeight / 2;
|
||||
this.drawDot(ctx, leftDotX, leftDotY, dotRadius);
|
||||
|
||||
// 绘制右侧答案选项(随机乱序)
|
||||
const answerData = shuffledAnswers[rowIndex];
|
||||
if (answerData) {
|
||||
// 绘制右侧圆点(垂直居中)
|
||||
const rightDotX = rightAreaStartX - dotSpacing - dotRadius * 2;
|
||||
const rightDotY = rowY + gridHeight / 2;
|
||||
this.drawDot(ctx, rightDotX, rightDotY, dotRadius);
|
||||
|
||||
// 绘制答案网格
|
||||
this.drawGrid(
|
||||
ctx,
|
||||
rightAreaStartX,
|
||||
rowY,
|
||||
cellSize,
|
||||
gridSize,
|
||||
answerData.positions,
|
||||
gridData.color,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制3x3网格
|
||||
*/
|
||||
private drawGrid(
|
||||
ctx: RenderingContext,
|
||||
x: number,
|
||||
y: number,
|
||||
cellSize: number,
|
||||
gridSize: number,
|
||||
filledPositions: GridPosition[],
|
||||
fillColor: string,
|
||||
) {
|
||||
// 绘制网格线
|
||||
this.drawGridLines(x, y, cellSize, cellSize, gridSize, gridSize);
|
||||
|
||||
// 绘制填充的格子
|
||||
ctx.fillStyle = fillColor;
|
||||
for (const pos of filledPositions) {
|
||||
const cellX = x + pos.x * cellSize;
|
||||
const cellY = y + pos.y * cellSize;
|
||||
ctx.fillRect(cellX, cellY, cellSize, cellSize);
|
||||
}
|
||||
|
||||
// 重新绘制网格线(确保在填充色之上)
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = 1;
|
||||
ctx.setLineDash([]);
|
||||
this.drawGridLines(x, y, cellSize, cellSize, gridSize, gridSize);
|
||||
}
|
||||
}
|
||||
|
||||
export default GridReasoningDraw;
|
||||
@@ -282,4 +282,103 @@ export class BaseDrawService {
|
||||
// 重置为实线(避免影响后续绘制)
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制符号(使用路径绘制)
|
||||
* @param x 符号中心X坐标
|
||||
* @param y 符号中心Y坐标
|
||||
* @param symbol 符号类型:'+', '-', '×', '✓'
|
||||
* @param size 符号大小
|
||||
*/
|
||||
drawSymbol(x: number, y: number, symbol: string, size: number): void {
|
||||
const { ctx } = this;
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
|
||||
const lineWidth = size * 0.15; // 线条宽度
|
||||
const halfSize = size / 2;
|
||||
const strokeLength = halfSize * 0.7; // 线条长度
|
||||
|
||||
ctx.strokeStyle = '#000';
|
||||
ctx.lineWidth = lineWidth;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
|
||||
switch (symbol) {
|
||||
case '+':
|
||||
// 加号:横线和竖线
|
||||
ctx.beginPath();
|
||||
// 横线
|
||||
ctx.moveTo(-strokeLength, 0);
|
||||
ctx.lineTo(strokeLength, 0);
|
||||
// 竖线
|
||||
ctx.moveTo(0, -strokeLength);
|
||||
ctx.lineTo(0, strokeLength);
|
||||
ctx.stroke();
|
||||
break;
|
||||
|
||||
case '-':
|
||||
// 减号:横线
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(-strokeLength, 0);
|
||||
ctx.lineTo(strokeLength, 0);
|
||||
ctx.stroke();
|
||||
break;
|
||||
|
||||
case '×':
|
||||
// 乘号:两条斜线
|
||||
ctx.beginPath();
|
||||
// 左上到右下
|
||||
ctx.moveTo(-strokeLength * 0.7, -strokeLength * 0.7);
|
||||
ctx.lineTo(strokeLength * 0.7, strokeLength * 0.7);
|
||||
// 右上到左下
|
||||
ctx.moveTo(strokeLength * 0.7, -strokeLength * 0.7);
|
||||
ctx.lineTo(-strokeLength * 0.7, strokeLength * 0.7);
|
||||
ctx.stroke();
|
||||
break;
|
||||
|
||||
case '✓':
|
||||
// 对号:勾,整体更大,右侧的线更长
|
||||
const checkScale = 1.2; // 对号整体放大1.2倍
|
||||
ctx.beginPath();
|
||||
const checkStartX = -strokeLength * 0.5 * checkScale;
|
||||
const checkStartY = -strokeLength * 0.2 * checkScale;
|
||||
const checkMidX = -strokeLength * 0.1 * checkScale;
|
||||
const checkMidY = strokeLength * 0.3 * checkScale;
|
||||
const checkEndX = strokeLength * 1.0 * checkScale; // 增加右侧长度
|
||||
const checkEndY = -strokeLength * 0.4 * checkScale; // 稍微向上调整
|
||||
ctx.moveTo(checkStartX, checkStartY);
|
||||
ctx.lineTo(checkMidX, checkMidY);
|
||||
ctx.lineTo(checkEndX, checkEndY);
|
||||
ctx.stroke();
|
||||
break;
|
||||
|
||||
default:
|
||||
// 默认绘制加号
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(-strokeLength, 0);
|
||||
ctx.lineTo(strokeLength, 0);
|
||||
ctx.moveTo(0, -strokeLength);
|
||||
ctx.lineTo(0, strokeLength);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制圆点
|
||||
*/
|
||||
drawDot(
|
||||
ctx: RenderingContext,
|
||||
x: number,
|
||||
y: number,
|
||||
radius: number,
|
||||
fillColor?: string,
|
||||
) {
|
||||
ctx.fillStyle = fillColor ?? '#93D333';
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, radius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user