feat: add line shape (#371)
* feat: add line shape * fix: align line tool * fix: hitbox bug sw to ne * fix: add stroke width n sloppiness for line * fix: center line inside a panel box * fix: use color as a unique key
This commit is contained in:
parent
42968ef44d
commit
8db8827c6f
@ -33,6 +33,7 @@ const Picker = function({
|
|||||||
title={color}
|
title={color}
|
||||||
tabIndex={0}
|
tabIndex={0}
|
||||||
style={{ backgroundColor: color }}
|
style={{ backgroundColor: color }}
|
||||||
|
key={color}
|
||||||
>
|
>
|
||||||
{color === "transparent" ? (
|
{color === "transparent" ? (
|
||||||
<div className="color-picker-transparent"></div>
|
<div className="color-picker-transparent"></div>
|
||||||
|
@ -48,3 +48,12 @@ export function getArrowPoints(element: ExcalidrawElement) {
|
|||||||
|
|
||||||
return [x1, y1, x2, y2, x3, y3, x4, y4];
|
return [x1, y1, x2, y2, x3, y3, x4, y4];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getLinePoints(element: ExcalidrawElement) {
|
||||||
|
const x1 = 0;
|
||||||
|
const y1 = 0;
|
||||||
|
const x2 = element.width;
|
||||||
|
const y2 = element.height;
|
||||||
|
|
||||||
|
return [x1, y1, x2, y2];
|
||||||
|
}
|
||||||
|
@ -4,7 +4,8 @@ import { ExcalidrawElement } from "./types";
|
|||||||
import {
|
import {
|
||||||
getArrowPoints,
|
getArrowPoints,
|
||||||
getDiamondPoints,
|
getDiamondPoints,
|
||||||
getElementAbsoluteCoords
|
getElementAbsoluteCoords,
|
||||||
|
getLinePoints
|
||||||
} from "./bounds";
|
} from "./bounds";
|
||||||
|
|
||||||
export function hitTest(
|
export function hitTest(
|
||||||
@ -153,6 +154,13 @@ export function hitTest(
|
|||||||
// /
|
// /
|
||||||
distanceBetweenPointAndSegment(x, y, x4, y4, x2, y2) < lineThreshold
|
distanceBetweenPointAndSegment(x, y, x4, y4, x2, y2) < lineThreshold
|
||||||
);
|
);
|
||||||
|
} else if (element.type === "line") {
|
||||||
|
const [x1, y1, x2, y2] = getLinePoints(element);
|
||||||
|
// The computation is done at the origin, we need to add a translation
|
||||||
|
x -= element.x;
|
||||||
|
y -= element.y;
|
||||||
|
|
||||||
|
return distanceBetweenPointAndSegment(x, y, x1, y1, x2, y2) < lineThreshold;
|
||||||
} else if (element.type === "text") {
|
} else if (element.type === "text") {
|
||||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ export function handlerRectangles(
|
|||||||
8
|
8
|
||||||
]; // se
|
]; // se
|
||||||
|
|
||||||
if (element.type === "arrow") {
|
if (element.type === "arrow" || element.type === "line") {
|
||||||
return {
|
return {
|
||||||
nw: handlers.nw,
|
nw: handlers.nw,
|
||||||
se: handlers.se
|
se: handlers.se
|
||||||
|
@ -2,7 +2,8 @@ export { newElement, duplicateElement } from "./newElement";
|
|||||||
export {
|
export {
|
||||||
getElementAbsoluteCoords,
|
getElementAbsoluteCoords,
|
||||||
getDiamondPoints,
|
getDiamondPoints,
|
||||||
getArrowPoints
|
getArrowPoints,
|
||||||
|
getLinePoints
|
||||||
} from "./bounds";
|
} from "./bounds";
|
||||||
|
|
||||||
export { handlerRectangles } from "./handlerRectangles";
|
export { handlerRectangles } from "./handlerRectangles";
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
import { ExcalidrawElement } from "../element/types";
|
import { ExcalidrawElement } from "../element/types";
|
||||||
import { isTextElement } from "../element/typeChecks";
|
import { isTextElement } from "../element/typeChecks";
|
||||||
import { getDiamondPoints, getArrowPoints } from "../element/bounds";
|
import {
|
||||||
|
getDiamondPoints,
|
||||||
|
getArrowPoints,
|
||||||
|
getLinePoints
|
||||||
|
} from "../element/bounds";
|
||||||
import { RoughCanvas } from "roughjs/bin/canvas";
|
import { RoughCanvas } from "roughjs/bin/canvas";
|
||||||
import { Drawable } from "roughjs/bin/core";
|
import { Drawable } from "roughjs/bin/core";
|
||||||
|
|
||||||
@ -118,6 +122,22 @@ export function renderElement(
|
|||||||
(element.shape as Drawable[]).forEach(shape => rc.draw(shape));
|
(element.shape as Drawable[]).forEach(shape => rc.draw(shape));
|
||||||
context.globalAlpha = 1;
|
context.globalAlpha = 1;
|
||||||
return;
|
return;
|
||||||
|
} else if (element.type === "line") {
|
||||||
|
const [x1, y1, x2, y2] = getLinePoints(element);
|
||||||
|
const options = {
|
||||||
|
stroke: element.strokeColor,
|
||||||
|
strokeWidth: element.strokeWidth,
|
||||||
|
roughness: element.roughness,
|
||||||
|
seed: element.seed
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!element.shape) {
|
||||||
|
element.shape = generator.line(x1, y1, x2, y2, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
context.globalAlpha = element.opacity / 100;
|
||||||
|
rc.draw(element.shape as Drawable);
|
||||||
|
context.globalAlpha = 1;
|
||||||
} else if (isTextElement(element)) {
|
} else if (isTextElement(element)) {
|
||||||
context.globalAlpha = element.opacity / 100;
|
context.globalAlpha = element.opacity / 100;
|
||||||
const font = context.font;
|
const font = context.font;
|
||||||
|
@ -18,7 +18,8 @@ export const hasStroke = (elements: readonly ExcalidrawElement[]) =>
|
|||||||
(element.type === "rectangle" ||
|
(element.type === "rectangle" ||
|
||||||
element.type === "ellipse" ||
|
element.type === "ellipse" ||
|
||||||
element.type === "diamond" ||
|
element.type === "diamond" ||
|
||||||
element.type === "arrow")
|
element.type === "arrow" ||
|
||||||
|
element.type === "line")
|
||||||
);
|
);
|
||||||
|
|
||||||
export const hasText = (elements: readonly ExcalidrawElement[]) =>
|
export const hasText = (elements: readonly ExcalidrawElement[]) =>
|
||||||
|
@ -55,6 +55,22 @@ export const SHAPES = [
|
|||||||
</svg>
|
</svg>
|
||||||
),
|
),
|
||||||
value: "text"
|
value: "text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
icon: (
|
||||||
|
// custom
|
||||||
|
<svg viewBox="0 0 6 6">
|
||||||
|
<line
|
||||||
|
x1="0"
|
||||||
|
y1="3"
|
||||||
|
x2="6"
|
||||||
|
y2="3"
|
||||||
|
stroke="black"
|
||||||
|
strokeLinecap="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
),
|
||||||
|
value: "line"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user