feat:V2.5.2 颜色找规律
This commit is contained in:
@@ -17,12 +17,30 @@ export const SHAPE_SYMBOL_SHAPES: ShapeSymbolShape[] = [
|
||||
{ id: 'ellipse', name: '椭圆' },
|
||||
{ id: 'star', name: '五角星' },
|
||||
{ id: 'pentagon', name: '五边形' },
|
||||
{ id: 'hexagon', name: '六边形' },
|
||||
{ id: 'octagon', name: '八边形' },
|
||||
{ id: 'cross', name: '十字形' },
|
||||
{ id: 'rectangle', name: '长方形' },
|
||||
{ id: 'sector', name: '扇形' },
|
||||
{ id: 'heart', name: '心形' },
|
||||
];
|
||||
|
||||
/**
|
||||
* 绘制图形(无边框,仅填充)
|
||||
* 绘制图形选项
|
||||
*/
|
||||
export interface DrawShapeOptions {
|
||||
/** 填充颜色,如果为 null 则不填充 */
|
||||
fillColor?: string | null;
|
||||
/** 边框颜色,如果为 null 则不绘制边框 */
|
||||
strokeColor?: string | null;
|
||||
/** 边框宽度,默认为 1.5 */
|
||||
strokeWidth?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制图形(支持边框和填充控制)
|
||||
* 所有图形保持相同的大小
|
||||
* @overload 旧的方式:drawShapeSymbolShape(ctx, shapeId, x, y, size, fillColor)
|
||||
*/
|
||||
export function drawShapeSymbolShape(
|
||||
ctx: RenderingContext,
|
||||
@@ -31,32 +49,110 @@ export function drawShapeSymbolShape(
|
||||
y: number,
|
||||
size: number,
|
||||
fillColor: string,
|
||||
options?: DrawShapeOptions,
|
||||
): void;
|
||||
/**
|
||||
* 绘制图形(支持边框和填充控制)
|
||||
* 所有图形保持相同的大小
|
||||
* @overload 新的方式:drawShapeSymbolShape(ctx, shapeId, x, y, size, options)
|
||||
*/
|
||||
export function drawShapeSymbolShape(
|
||||
ctx: RenderingContext,
|
||||
shapeId: string,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
options: DrawShapeOptions,
|
||||
): void;
|
||||
/**
|
||||
* 绘制图形(支持边框和填充控制)
|
||||
* 所有图形保持相同的大小
|
||||
*/
|
||||
export function drawShapeSymbolShape(
|
||||
ctx: RenderingContext,
|
||||
shapeId: string,
|
||||
x: number,
|
||||
y: number,
|
||||
size: number,
|
||||
fillColorOrOptions: string | DrawShapeOptions,
|
||||
options?: DrawShapeOptions,
|
||||
): void {
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
|
||||
const radius = size / 2;
|
||||
|
||||
ctx.fillStyle = fillColor;
|
||||
// 兼容旧的调用方式:drawShapeSymbolShape(ctx, shapeId, x, y, size, fillColor)
|
||||
let fillColor: string | null = null;
|
||||
let drawOptions: DrawShapeOptions = {};
|
||||
|
||||
if (typeof fillColorOrOptions === 'string') {
|
||||
// 旧的方式:fillColor 是字符串
|
||||
fillColor = fillColorOrOptions;
|
||||
drawOptions = options || {};
|
||||
} else {
|
||||
// 新的方式:第一个参数是 options
|
||||
drawOptions = fillColorOrOptions || {};
|
||||
fillColor = drawOptions.fillColor || null;
|
||||
}
|
||||
|
||||
// 设置填充和描边样式
|
||||
if (fillColor) {
|
||||
ctx.fillStyle = fillColor;
|
||||
}
|
||||
if (drawOptions.strokeColor) {
|
||||
ctx.strokeStyle = drawOptions.strokeColor;
|
||||
ctx.lineWidth = drawOptions.strokeWidth || 1.5;
|
||||
}
|
||||
|
||||
// 统一的填充和描边处理函数
|
||||
const drawPath = () => {
|
||||
if (fillColor) {
|
||||
ctx.fill();
|
||||
}
|
||||
if (drawOptions.strokeColor) {
|
||||
ctx.stroke();
|
||||
}
|
||||
};
|
||||
|
||||
switch (shapeId) {
|
||||
case 'circle':
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'square':
|
||||
ctx.fillRect(-radius, -radius, size, size);
|
||||
// 正方形缩小为原来的0.9倍
|
||||
const squareSize = size * 0.9;
|
||||
const squareRadius = squareSize / 2;
|
||||
if (fillColor) {
|
||||
ctx.fillRect(
|
||||
-squareRadius,
|
||||
-squareRadius,
|
||||
squareSize,
|
||||
squareSize,
|
||||
);
|
||||
}
|
||||
if (drawOptions.strokeColor) {
|
||||
ctx.strokeRect(
|
||||
-squareRadius,
|
||||
-squareRadius,
|
||||
squareSize,
|
||||
squareSize,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'triangle':
|
||||
// 三角形缩小为原来的0.9倍
|
||||
const triangleRadius = radius * 0.9;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, -radius);
|
||||
ctx.lineTo(-radius, radius);
|
||||
ctx.lineTo(radius, radius);
|
||||
ctx.moveTo(0, -triangleRadius);
|
||||
ctx.lineTo(-triangleRadius, triangleRadius);
|
||||
ctx.lineTo(triangleRadius, triangleRadius);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'diamond':
|
||||
@@ -66,7 +162,7 @@ export function drawShapeSymbolShape(
|
||||
ctx.lineTo(0, radius);
|
||||
ctx.lineTo(-radius, 0);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'trapezoid':
|
||||
@@ -77,13 +173,13 @@ export function drawShapeSymbolShape(
|
||||
ctx.lineTo(radius, radius * 0.7);
|
||||
ctx.lineTo(-radius, radius * 0.7);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'ellipse':
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(0, 0, radius * 0.8, radius * 0.6, 0, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'star':
|
||||
@@ -106,7 +202,7 @@ export function drawShapeSymbolShape(
|
||||
ctx.lineTo(x2, y2);
|
||||
}
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'pentagon':
|
||||
@@ -119,7 +215,94 @@ export function drawShapeSymbolShape(
|
||||
else ctx.lineTo(px, py);
|
||||
}
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'hexagon':
|
||||
// 六边形
|
||||
ctx.beginPath();
|
||||
for (let i = 0; i < 6; i++) {
|
||||
const angle = (i * 2 * Math.PI) / 6 - 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();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'octagon':
|
||||
// 八边形
|
||||
ctx.beginPath();
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const angle = (i * 2 * Math.PI) / 8 - 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();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'cross':
|
||||
// 十字形
|
||||
const crossWidth = radius * 0.3; // 十字的宽度
|
||||
if (fillColor) {
|
||||
// 竖条
|
||||
ctx.fillRect(-crossWidth, -radius, crossWidth * 2, size);
|
||||
// 横条
|
||||
ctx.fillRect(-radius, -crossWidth, size, crossWidth * 2);
|
||||
}
|
||||
if (drawOptions.strokeColor) {
|
||||
// 竖条
|
||||
ctx.strokeRect(-crossWidth, -radius, crossWidth * 2, size);
|
||||
// 横条
|
||||
ctx.strokeRect(-radius, -crossWidth, size, crossWidth * 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'rectangle':
|
||||
// 长方形(横向,宽度是高度的1.2倍)
|
||||
const rectWidth = radius * 1.1;
|
||||
const rectHeight = radius * 0.7;
|
||||
if (fillColor) {
|
||||
ctx.fillRect(
|
||||
-rectWidth,
|
||||
-rectHeight,
|
||||
rectWidth * 2,
|
||||
rectHeight * 2,
|
||||
);
|
||||
}
|
||||
if (drawOptions.strokeColor) {
|
||||
ctx.strokeRect(
|
||||
-rectWidth,
|
||||
-rectHeight,
|
||||
rectWidth * 2,
|
||||
rectHeight * 2,
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
// 扇形
|
||||
case 'sector':
|
||||
// 扇形(90度扇形),圆心在格子中心点偏左二分之一的位置
|
||||
const sectorCenterX = -radius / 2; // 向左偏移半径的一半
|
||||
const sectorCenterY = 0;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(sectorCenterX, sectorCenterY);
|
||||
ctx.arc(
|
||||
sectorCenterX,
|
||||
sectorCenterY,
|
||||
radius,
|
||||
-Math.PI / 4,
|
||||
Math.PI / 4,
|
||||
false,
|
||||
);
|
||||
ctx.lineTo(sectorCenterX, sectorCenterY);
|
||||
ctx.closePath();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
case 'heart':
|
||||
@@ -141,14 +324,14 @@ export function drawShapeSymbolShape(
|
||||
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();
|
||||
drawPath();
|
||||
break;
|
||||
|
||||
default:
|
||||
// 默认绘制圆形
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, radius, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
drawPath();
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
|
||||
Reference in New Issue
Block a user