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:
Bakhtiiar Muzakparov 2020-01-15 22:07:19 +03:00 committed by Timur Khazamov
parent 42968ef44d
commit 8db8827c6f
8 changed files with 61 additions and 5 deletions

View File

@ -33,6 +33,7 @@ const Picker = function({
title={color}
tabIndex={0}
style={{ backgroundColor: color }}
key={color}
>
{color === "transparent" ? (
<div className="color-picker-transparent"></div>

View File

@ -48,3 +48,12 @@ export function getArrowPoints(element: ExcalidrawElement) {
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];
}

View File

@ -4,7 +4,8 @@ import { ExcalidrawElement } from "./types";
import {
getArrowPoints,
getDiamondPoints,
getElementAbsoluteCoords
getElementAbsoluteCoords,
getLinePoints
} from "./bounds";
export function hitTest(
@ -153,6 +154,13 @@ export function hitTest(
// /
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") {
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);

View File

@ -76,7 +76,7 @@ export function handlerRectangles(
8
]; // se
if (element.type === "arrow") {
if (element.type === "arrow" || element.type === "line") {
return {
nw: handlers.nw,
se: handlers.se

View File

@ -2,7 +2,8 @@ export { newElement, duplicateElement } from "./newElement";
export {
getElementAbsoluteCoords,
getDiamondPoints,
getArrowPoints
getArrowPoints,
getLinePoints
} from "./bounds";
export { handlerRectangles } from "./handlerRectangles";

View File

@ -1,6 +1,10 @@
import { ExcalidrawElement } from "../element/types";
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 { Drawable } from "roughjs/bin/core";
@ -118,6 +122,22 @@ export function renderElement(
(element.shape as Drawable[]).forEach(shape => rc.draw(shape));
context.globalAlpha = 1;
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)) {
context.globalAlpha = element.opacity / 100;
const font = context.font;

View File

@ -18,7 +18,8 @@ export const hasStroke = (elements: readonly ExcalidrawElement[]) =>
(element.type === "rectangle" ||
element.type === "ellipse" ||
element.type === "diamond" ||
element.type === "arrow")
element.type === "arrow" ||
element.type === "line")
);
export const hasText = (elements: readonly ExcalidrawElement[]) =>

View File

@ -55,6 +55,22 @@ export const SHAPES = [
</svg>
),
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"
}
];