feat: 添加控笔页
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { TRACING_COLORS } from '../../../core/data/tracingStyles';
|
||||
import { drawSvgPath } from '../../shared/drawUtils';
|
||||
import type {
|
||||
PenControlPattern,
|
||||
PenControlRenderMode,
|
||||
} from '../data/penControlPatterns';
|
||||
|
||||
export const PEN_CONTROL_VIEW_SIZE = 100;
|
||||
|
||||
export interface PenControlTransform {
|
||||
xOffset: number;
|
||||
yOffset: number;
|
||||
scale: number;
|
||||
}
|
||||
|
||||
export function getPenControlTransform(
|
||||
width: number,
|
||||
height: number,
|
||||
padding: number,
|
||||
): PenControlTransform {
|
||||
const availableWidth = width - 2 * padding;
|
||||
const availableHeight = height - 2 * padding;
|
||||
const scale = Math.min(
|
||||
availableWidth / PEN_CONTROL_VIEW_SIZE,
|
||||
availableHeight / PEN_CONTROL_VIEW_SIZE,
|
||||
);
|
||||
const scaledW = PEN_CONTROL_VIEW_SIZE * scale;
|
||||
const scaledH = PEN_CONTROL_VIEW_SIZE * scale;
|
||||
const xOffset = padding + (availableWidth - scaledW) / 2;
|
||||
const yOffset = padding + (availableHeight - scaledH) / 2;
|
||||
return { xOffset, yOffset, scale };
|
||||
}
|
||||
|
||||
export type PenControlCellStyle = 'reference' | 'guide';
|
||||
|
||||
function colorForStyle(style: PenControlCellStyle): string {
|
||||
return style === 'reference' ? TRACING_COLORS.strong : TRACING_COLORS.guide;
|
||||
}
|
||||
|
||||
function drawPathWithMode(
|
||||
ctx: RenderingContext,
|
||||
pathD: string,
|
||||
render: PenControlRenderMode,
|
||||
color: string,
|
||||
lineWidth: number,
|
||||
dashed: boolean,
|
||||
) {
|
||||
ctx.beginPath();
|
||||
drawSvgPath(ctx, pathD);
|
||||
|
||||
if (render === 'fill' || render === 'both') {
|
||||
ctx.fillStyle = color;
|
||||
ctx.fill();
|
||||
}
|
||||
if (render === 'stroke' || render === 'both') {
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = lineWidth;
|
||||
if (dashed) {
|
||||
// setLineDash 接收一个数组,表示虚线的样式。
|
||||
// 第一个参数 (lineWidth * 2.6):表示每段实线的长度
|
||||
// 第二个参数 (lineWidth * 2.4):表示每段虚线的间隙长度
|
||||
// 旧虚线效果不明显,调整为更清晰的虚线样式
|
||||
ctx.setLineDash([lineWidth * 1.8, lineWidth * 2.3]);
|
||||
} else {
|
||||
ctx.setLineDash([]);
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 在田字格中心绘制控笔图形
|
||||
*/
|
||||
export function drawPenControlInCell(
|
||||
ctx: RenderingContext,
|
||||
pattern: PenControlPattern,
|
||||
cx: number,
|
||||
cy: number,
|
||||
cellSize: number,
|
||||
style: PenControlCellStyle,
|
||||
options?: { dashed?: boolean },
|
||||
) {
|
||||
const color = colorForStyle(style);
|
||||
const padding = cellSize * 0.1;
|
||||
const transform = getPenControlTransform(cellSize, cellSize, padding);
|
||||
const lineWidth =
|
||||
(cellSize * 0.0236 * (pattern.strokeScale ?? 1)) / transform.scale;
|
||||
const dashed = options?.dashed === true;
|
||||
|
||||
ctx.save();
|
||||
ctx.lineCap = 'round';
|
||||
ctx.lineJoin = 'round';
|
||||
ctx.translate(cx - cellSize / 2, cy - cellSize / 2);
|
||||
ctx.translate(transform.xOffset, transform.yOffset);
|
||||
ctx.scale(transform.scale, transform.scale);
|
||||
|
||||
for (const pathD of pattern.paths) {
|
||||
drawPathWithMode(ctx, pathD, pattern.render, color, lineWidth, dashed);
|
||||
}
|
||||
|
||||
ctx.setLineDash([]);
|
||||
ctx.restore();
|
||||
}
|
||||
Reference in New Issue
Block a user