feat:V2.5.3 图形符号配对
This commit is contained in:
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* 图形符号配对专用的图形定义
|
||||
* 所有图形保持大小一致
|
||||
*/
|
||||
|
||||
export interface ShapeSymbolShape {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const SHAPE_SYMBOL_SHAPES: ShapeSymbolShape[] = [
|
||||
{ id: 'circle', name: '圆形' },
|
||||
{ id: 'square', name: '正方形' },
|
||||
{ id: 'triangle', name: '三角形' },
|
||||
{ id: 'diamond', name: '菱形' },
|
||||
{ id: 'trapezoid', name: '梯形' },
|
||||
{ id: 'ellipse', name: '椭圆' },
|
||||
{ id: 'star', name: '五角星' },
|
||||
{ id: 'pentagon', name: '五边形' },
|
||||
{ id: 'heart', name: '心形' },
|
||||
];
|
||||
|
||||
/**
|
||||
* 绘制图形(无边框,仅填充)
|
||||
* 所有图形保持相同的大小
|
||||
*/
|
||||
export function drawShapeSymbolShape(
|
||||
ctx: RenderingContext,
|
||||
shapeId: string,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
fillColor: string,
|
||||
): void {
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
|
||||
const radius = size / 2;
|
||||
|
||||
ctx.fillStyle = fillColor;
|
||||
|
||||
switch (shapeId) {
|
||||
case 'circle':
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'square':
|
||||
ctx.fillRect(-radius, -radius, size, size);
|
||||
break;
|
||||
|
||||
case 'triangle':
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, -radius);
|
||||
ctx.lineTo(-radius, radius);
|
||||
ctx.lineTo(radius, radius);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'diamond':
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, -radius);
|
||||
ctx.lineTo(radius, 0);
|
||||
ctx.lineTo(0, radius);
|
||||
ctx.lineTo(-radius, 0);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'trapezoid':
|
||||
ctx.beginPath();
|
||||
const topWidth = radius * 0.6;
|
||||
ctx.moveTo(-topWidth, -radius * 0.7);
|
||||
ctx.lineTo(topWidth, -radius * 0.7);
|
||||
ctx.lineTo(radius, radius * 0.7);
|
||||
ctx.lineTo(-radius, radius * 0.7);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'ellipse':
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(0, 0, radius * 0.8, radius * 0.6, 0, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'star':
|
||||
// 五角星
|
||||
ctx.beginPath();
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const angle1 = (i * 2 * Math.PI) / 5 - Math.PI / 2;
|
||||
const angle2 = ((i + 0.5) * 2 * Math.PI) / 5 - Math.PI / 2;
|
||||
const r1 = radius;
|
||||
const r2 = radius * 0.4;
|
||||
const x1 = Math.cos(angle1) * r1;
|
||||
const y1 = Math.sin(angle1) * r1;
|
||||
const x2 = Math.cos(angle2) * r2;
|
||||
const y2 = Math.sin(angle2) * r2;
|
||||
if (i === 0) {
|
||||
ctx.moveTo(x1, y1);
|
||||
} else {
|
||||
ctx.lineTo(x1, y1);
|
||||
}
|
||||
ctx.lineTo(x2, y2);
|
||||
}
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'pentagon':
|
||||
ctx.beginPath();
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const angle = (i * 2 * Math.PI) / 5 - Math.PI / 2;
|
||||
const px = Math.cos(angle) * radius;
|
||||
const py = Math.sin(angle) * radius;
|
||||
if (i === 0) ctx.moveTo(px, py);
|
||||
else ctx.lineTo(px, py);
|
||||
}
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
case 'heart':
|
||||
// 爱心路径(参考 shapes.ts 中的 SVG 路径)
|
||||
// SVG路径:M50,35 C35,20 20,35 25,50 C30,65 50,80 50,80 C50,80 70,65 75,50 C80,35 65,20 50,35Z
|
||||
// SVG中心为(50,50),高度约为60(从y=20到y=80)
|
||||
// 使用scale=60使心形高度约为size,与其他图形保持一致
|
||||
const scale = 60;
|
||||
function tx(px: number) {
|
||||
return ((px - 50) / scale) * size;
|
||||
}
|
||||
function ty(py: number) {
|
||||
return ((py - 50) / scale) * size;
|
||||
}
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(tx(50), ty(35));
|
||||
ctx.bezierCurveTo(tx(35), ty(20), tx(20), ty(35), tx(25), ty(50));
|
||||
ctx.bezierCurveTo(tx(30), ty(65), tx(50), ty(80), tx(50), ty(80));
|
||||
ctx.bezierCurveTo(tx(50), ty(80), tx(70), ty(65), tx(75), ty(50));
|
||||
ctx.bezierCurveTo(tx(80), ty(35), tx(65), ty(20), tx(50), ty(35));
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
break;
|
||||
|
||||
default:
|
||||
// 默认绘制圆形
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
Reference in New Issue
Block a user