mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Rotation support (#1099)
* rotate rectanble with fixed angle * rotate dashed rectangle with fixed angle * fix rotate handler rect * fix canvas size with rotation * angle in element base * fix bug in calculating canvas size * trial only for rectangle * hitTest for rectangle rotation * properly resize rotated rectangle * fix canvas size calculation * giving up... workaround for now * **experimental** handler to rotate rectangle * remove rotation on copy for debugging * update snapshots * better rotation handler with atan2 * rotate when drawImage * add rotation handler * hitTest for any shapes * fix hitTest for curved lines * rotate text element * rotation locking * hint messaage for rotating * show proper handlers on mobile (a workaround, there should be a better way) * refactor hitTest * support exporting png * support exporting svg * fix rotating curved line * refactor drawElementFromCanvas with getElementAbsoluteCoords * fix export png and svg * adjust resize positions for lines (N, E, S, W) * do not make handlers big on mobile * Update src/locales/en.json Alright! Co-Authored-By: Lipis <lipiridis@gmail.com> * do not show rotation/resizing hints on mobile * proper calculation for N and W positions * simplify calculation * use "rotation" as property name for clarification (may increase bundle size) * update snapshots excluding rotation handle * refactor with adjustPositionWithRotation * refactor with adjustXYWithRotation * forgot to rename rotation * rename internal function * initialize element angle on restore * rotate wysiwyg editor * fix shift-rotate around 270deg * improve rotation locking * refactor adjustXYWithRotation * avoid rotation degree becomes >=360 * refactor with generateHandler Co-authored-by: Lipis <lipiridis@gmail.com> Co-authored-by: dwelle <luzar.david@gmail.com>
This commit is contained in:
parent
3e3ce18755
commit
65be7973be
23 changed files with 664 additions and 108 deletions
|
@ -2,16 +2,13 @@ import { distanceBetweenPointAndSegment } from "../math";
|
|||
|
||||
import { ExcalidrawElement } from "./types";
|
||||
|
||||
import {
|
||||
getDiamondPoints,
|
||||
getElementAbsoluteCoords,
|
||||
getLinearElementAbsoluteBounds,
|
||||
} from "./bounds";
|
||||
import { getDiamondPoints, getElementAbsoluteCoords } from "./bounds";
|
||||
import { Point } from "../types";
|
||||
import { Drawable, OpSet } from "roughjs/bin/core";
|
||||
import { AppState } from "../types";
|
||||
import { getShapeForElement } from "../renderer/renderElement";
|
||||
import { isLinearElement } from "./typeChecks";
|
||||
import { rotate } from "../math";
|
||||
|
||||
function isElementDraggableFromInside(
|
||||
element: ExcalidrawElement,
|
||||
|
@ -34,6 +31,12 @@ export function hitTest(
|
|||
// of the click is less than x pixels of any of the lines that the shape is composed of
|
||||
const lineThreshold = 10 / zoom;
|
||||
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||
const cx = (x1 + x2) / 2;
|
||||
const cy = (y1 + y2) / 2;
|
||||
// reverse rotate the pointer
|
||||
[x, y] = rotate(x, y, cx, cy, -element.angle);
|
||||
|
||||
if (element.type === "ellipse") {
|
||||
// https://stackoverflow.com/a/46007540/232122
|
||||
const px = Math.abs(x - element.x - element.width / 2);
|
||||
|
@ -75,8 +78,6 @@ export function hitTest(
|
|||
}
|
||||
return Math.hypot(a * tx - px, b * ty - py) < lineThreshold;
|
||||
} else if (element.type === "rectangle") {
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||
|
||||
if (isElementDraggableFromInside(element, appState)) {
|
||||
return (
|
||||
x > x1 - lineThreshold &&
|
||||
|
@ -165,7 +166,6 @@ export function hitTest(
|
|||
}
|
||||
const shape = getShapeForElement(element) as Drawable[];
|
||||
|
||||
const [x1, y1, x2, y2] = getLinearElementAbsoluteBounds(element);
|
||||
if (
|
||||
x < x1 - lineThreshold ||
|
||||
y < y1 - lineThreshold ||
|
||||
|
@ -183,8 +183,6 @@ export function hitTest(
|
|||
hitTestRoughShape(subshape.sets, relX, relY, lineThreshold),
|
||||
);
|
||||
} else if (element.type === "text") {
|
||||
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
|
||||
|
||||
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
|
||||
} else if (element.type === "selection") {
|
||||
console.warn("This should not happen, we need to investigate why it does.");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue