Creating a text near the center of a shape should put it in the center (#270)

* Snap to element center

* Fixed typo

* Added comment

* Reduced threshold to 30

* Skip snapping if alt key is pressed

* Fixed creating text with shape tool
This commit is contained in:
Timur Khazamov 2020-01-09 01:09:09 +05:00 committed by GitHub
parent 068dca604f
commit 1739540f00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 90 additions and 12 deletions

View file

@ -26,7 +26,8 @@ import {
hasBackground,
hasStroke,
getElementAtPosition,
createScene
createScene,
getElementContainingPosition
} from "./scene";
import { renderScene } from "./renderer";
@ -110,6 +111,7 @@ function addTextElement(
const ELEMENT_SHIFT_TRANSLATE_AMOUNT = 5;
const ELEMENT_TRANSLATE_AMOUNT = 1;
const TEXT_TO_CENTER_SNAP_THRESHOLD = 30;
let lastCanvasWidth = -1;
let lastCanvasHeight = -1;
@ -702,10 +704,25 @@ class App extends React.Component<{}, AppState> {
}
if (isTextElement(element)) {
let textX = e.clientX;
let textY = e.clientY;
if (!e.altKey) {
const snappedToCenterPosition = this.getTextWysiwygSnappedToCenterPosition(
x,
y
);
if (snappedToCenterPosition) {
element.x = snappedToCenterPosition.elementCenterX;
element.y = snappedToCenterPosition.elementCenterY;
textX = snappedToCenterPosition.wysiwygX;
textY = snappedToCenterPosition.wysiwygY;
}
}
textWysiwyg({
initText: "",
x: e.clientX,
y: e.clientY,
x: textX,
y: textY,
strokeColor: this.state.currentItemStrokeColor,
font: this.state.currentItemFont,
onSubmit: text => {
@ -932,12 +949,6 @@ class App extends React.Component<{}, AppState> {
e.clientX - CANVAS_WINDOW_OFFSET_LEFT - this.state.scrollX;
const y = e.clientY - CANVAS_WINDOW_OFFSET_TOP - this.state.scrollY;
const elementAtPosition = getElementAtPosition(elements, x, y);
if (elementAtPosition && !isTextElement(elementAtPosition)) {
return;
} else if (elementAtPosition) {
elements.splice(elements.indexOf(elementAtPosition), 1);
this.forceUpdate();
}
const element = newElement(
"text",
@ -954,7 +965,11 @@ class App extends React.Component<{}, AppState> {
let initText = "";
let textX = e.clientX;
let textY = e.clientY;
if (elementAtPosition) {
if (elementAtPosition && isTextElement(elementAtPosition)) {
elements.splice(elements.indexOf(elementAtPosition), 1);
this.forceUpdate();
Object.assign(element, elementAtPosition);
// x and y will change after calling addTextElement function
element.x = elementAtPosition.x + elementAtPosition.width / 2;
@ -970,6 +985,18 @@ class App extends React.Component<{}, AppState> {
elementAtPosition.y +
CANVAS_WINDOW_OFFSET_TOP +
elementAtPosition.height / 2;
} else if (!e.altKey) {
const snappedToCenterPosition = this.getTextWysiwygSnappedToCenterPosition(
x,
y
);
if (snappedToCenterPosition) {
element.x = snappedToCenterPosition.elementCenterX;
element.y = snappedToCenterPosition.elementCenterY;
textX = snappedToCenterPosition.wysiwygX;
textY = snappedToCenterPosition.wysiwygY;
}
}
textWysiwyg({
@ -1036,6 +1063,35 @@ class App extends React.Component<{}, AppState> {
}
};
private getTextWysiwygSnappedToCenterPosition(x: number, y: number) {
const elementClickedInside = getElementContainingPosition(elements, x, y);
if (elementClickedInside) {
const elementCenterX =
elementClickedInside.x + elementClickedInside.width / 2;
const elementCenterY =
elementClickedInside.y + elementClickedInside.height / 2;
const distanceToCenter = Math.hypot(
x - elementCenterX,
y - elementCenterY
);
const isSnappedToCenter =
distanceToCenter < TEXT_TO_CENTER_SNAP_THRESHOLD;
if (isSnappedToCenter) {
const wysiwygX =
this.state.scrollX +
elementClickedInside.x +
CANVAS_WINDOW_OFFSET_LEFT +
elementClickedInside.width / 2;
const wysiwygY =
this.state.scrollY +
elementClickedInside.y +
CANVAS_WINDOW_OFFSET_TOP +
elementClickedInside.height / 2;
return { wysiwygX, wysiwygY, elementCenterX, elementCenterY };
}
}
}
componentDidUpdate() {
renderScene(elements, rc, canvas, {
scrollX: this.state.scrollX,