104 lines
3.0 KiB
TypeScript
104 lines
3.0 KiB
TypeScript
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();
|
|
}
|