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:
Daishi Kato 2020-04-02 17:40:26 +09:00 committed by GitHub
parent 3e3ce18755
commit 65be7973be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 664 additions and 108 deletions

View file

@ -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.");