Skip to content

Commit

Permalink
feat: Add cross shape
Browse files Browse the repository at this point in the history
  • Loading branch information
miyanokomiya committed Apr 3, 2024
1 parent 47f9107 commit 9118cf8
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/assets/icons/shape_cross.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 0 additions & 3 deletions src/assets/icons/shape_diagonal_cross.svg:Zone.Identifier

This file was deleted.

2 changes: 2 additions & 0 deletions src/components/AppToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import iconBubble from "../assets/icons/shape_bubble.svg";
import iconOneSidedArrow from "../assets/icons/shape_one_sided_arrow.svg";
import iconTwoSidedArrow from "../assets/icons/shape_two_sided_arrow.svg";
import iconEllipse from "../assets/icons/shape_ellipse.svg";
import iconCross from "../assets/icons/shape_cross.svg";
import iconDiagonalCross from "../assets/icons/shape_diagonal_cross.svg";

import iconLineStraight from "../assets/icons/shape_line_straight.svg";
Expand Down Expand Up @@ -43,6 +44,7 @@ const shapeList = [
{ type: "bubble", icon: iconBubble },
{ type: "one_sided_arrow", icon: iconOneSidedArrow },
{ type: "two_sided_arrow", icon: iconTwoSidedArrow },
{ type: "cross", icon: iconCross },
{ type: "diagonal_cross", icon: iconDiagonalCross },
];

Expand Down
2 changes: 1 addition & 1 deletion src/composables/shapeHandlers/diagonalCrossHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export function renderMovingDiagonalCrossAnchor(

applyLocalSpace(ctx, { x: shape.p.x, y: shape.p.y, width: shape.width, height: shape.height }, shape.rotation, () => {
if (showLabel) {
renderValueLabel(ctx, shape.crossSize, c, -shape.rotation, scale);
renderValueLabel(ctx, shape.crossSize, c, -shape.rotation, scale, true);
}

applyStrokeStyle(ctx, { color: style.selectionSecondaly, dash: "dot" });
Expand Down
1 change: 1 addition & 0 deletions src/composables/states/appCanvas/selectionHubState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export function newSelectionHubState(option?: Option): AppCanvasState {
return newArrowTwoSelectedState;
case "trapezoid":
return newTrapezoidSelectedState;
case "cross":
case "diagonal_cross":
return newDiagonalCrossSelectedState;
case "cylinder":
Expand Down
2 changes: 2 additions & 0 deletions src/shapes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { struct as oneSidedArrowStruct } from "./oneSidedArrow";
import { struct as twoSidedArrowStruct } from "./twoSidedArrow";
import { struct as textStruct } from "./text";
import { struct as ellipseStruct } from "./ellipse";
import { struct as crossStruct } from "./polygons/cross";
import { struct as diagonalCrossStruct } from "./polygons/diagonalCross";
import { struct as lineStruct } from "./line";
import { struct as imageStruct } from "./image";
Expand Down Expand Up @@ -49,6 +50,7 @@ const SHAPE_STRUCTS: {
two_sided_arrow: twoSidedArrowStruct,
text: textStruct,
ellipse: ellipseStruct,
cross: crossStruct,
diagonal_cross: diagonalCrossStruct,
line: lineStruct,
image: imageStruct,
Expand Down
88 changes: 88 additions & 0 deletions src/shapes/polygons/cross.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { ShapeStruct, createBaseShape } from "../core";
import { SimplePath, SimplePolygonShape, getStructForSimplePolygon } from "../simplePolygon";
import { createFillStyle } from "../../utils/fillStyle";
import { createStrokeStyle } from "../../utils/strokeStyle";

export type CrossShape = SimplePolygonShape & {
crossSize: number;
};

export const struct: ShapeStruct<CrossShape> = {
...getStructForSimplePolygon<CrossShape>(getPath),
label: "Cross",
create(arg = {}) {
return {
...createBaseShape(arg),
type: "cross",
fill: arg.fill ?? createFillStyle(),
stroke: arg.stroke ?? createStrokeStyle(),
width: arg.width ?? 100,
height: arg.height ?? 100,
crossSize: arg.crossSize ?? 20,
};
},
getTextRangeRect: undefined,
getTextPadding: undefined,
patchTextPadding: undefined,
};

function getPath(shape: CrossShape): SimplePath {
const cx = shape.width / 2;
const cy = shape.height / 2;

const size = shape.crossSize;
if (size >= shape.width || size >= shape.height || size <= 0) {
// Fallback to rectangle when the cross size is too big.
const tl = { x: 0, y: 0 };
const tr = { x: shape.width, y: 0 };
const br = { x: shape.width, y: shape.height };
const bl = { x: 0, y: shape.height };
return {
path: [
tl,
tl,
{ x: cx, y: 0 },
tr,
tr,
{ x: shape.width, y: cy },
br,
br,
{ x: cx, y: shape.height },
bl,
bl,
{ x: 0, y: cy },
],
};
}

const d = size / 2;

const x0 = 0;
const y0 = 0;

const x1 = cx - d;
const y1 = cy - d;

const x2 = cx + d;
const y2 = cy + d;

const x3 = shape.width;
const y3 = shape.height;

return {
path: [
{ x: x0, y: y1 },
{ x: x1, y: y1 },
{ x: x1, y: y0 },
{ x: x2, y: y0 },
{ x: x2, y: y1 },
{ x: x3, y: y1 },
{ x: x3, y: y2 },
{ x: x2, y: y2 },
{ x: x2, y: y3 },
{ x: x1, y: y3 },
{ x: x1, y: y2 },
{ x: x0, y: y2 },
],
};
}
14 changes: 11 additions & 3 deletions src/utils/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,23 @@ export function applyDefaultTextStyle(
ctx: CanvasRenderingContext2D,
fontSize = 18,
textAlign: CanvasTextAlign = "left",
middle = false,
) {
ctx.font = `${fontSize}px Arial`;
ctx.setLineDash([]);
ctx.textBaseline = "alphabetic";
ctx.textBaseline = middle ? "middle" : "alphabetic";
ctx.textAlign = textAlign;
}

export function renderValueLabel(ctx: CanvasRenderingContext2D, value: number, p: IVec2, rotation = 0, scale = 1) {
applyDefaultTextStyle(ctx, 18 * scale, "center");
export function renderValueLabel(
ctx: CanvasRenderingContext2D,
value: number,
p: IVec2,
rotation = 0,
scale = 1,
middle = false,
) {
applyDefaultTextStyle(ctx, 18 * scale, "center", middle);
applyStrokeStyle(ctx, { color: COLORS.WHITE, width: 2 * scale });
applyFillStyle(ctx, { color: COLORS.BLACK });
applyRotation(ctx, rotation, p, () => {
Expand Down

0 comments on commit 9118cf8

Please sign in to comment.