Proper text sizing
This commit is contained in:
parent
47e626f510
commit
9dc19dde1d
89
src/index.js
89
src/index.js
@ -15,7 +15,6 @@ function newElement(type, x, y) {
|
|||||||
height: 0,
|
height: 0,
|
||||||
isSelected: false
|
isSelected: false
|
||||||
};
|
};
|
||||||
generateShape(element);
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +33,10 @@ var generator = rough.generator();
|
|||||||
function generateShape(element) {
|
function generateShape(element) {
|
||||||
if (element.type === "selection") {
|
if (element.type === "selection") {
|
||||||
element.draw = (rc, context) => {
|
element.draw = (rc, context) => {
|
||||||
|
const fillStyle = context.fillStyle;
|
||||||
context.fillStyle = "rgba(0, 0, 255, 0.10)";
|
context.fillStyle = "rgba(0, 0, 255, 0.10)";
|
||||||
context.fillRect(element.x, element.y, element.width, element.height);
|
context.fillRect(element.x, element.y, element.width, element.height);
|
||||||
|
context.fillStyle = fillStyle;
|
||||||
};
|
};
|
||||||
} else if (element.type === "rectangle") {
|
} else if (element.type === "rectangle") {
|
||||||
const shape = generator.rectangle(
|
const shape = generator.rectangle(
|
||||||
@ -85,29 +86,37 @@ function generateShape(element) {
|
|||||||
};
|
};
|
||||||
return;
|
return;
|
||||||
} else if (element.type === "text") {
|
} else if (element.type === "text") {
|
||||||
if (element.text === undefined) {
|
|
||||||
element.text = prompt("What text do you want?");
|
|
||||||
}
|
|
||||||
element.draw = (rc, context) => {
|
element.draw = (rc, context) => {
|
||||||
context.font = "20px Virgil";
|
const font = context.font;
|
||||||
const measure = context.measureText(element.text);
|
context.font = element.font;
|
||||||
const height =
|
const height =
|
||||||
measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent;
|
element.measure.actualBoundingBoxAscent +
|
||||||
|
element.measure.actualBoundingBoxDescent;
|
||||||
context.fillText(
|
context.fillText(
|
||||||
element.text,
|
element.text,
|
||||||
element.x - measure.width / 2,
|
element.x,
|
||||||
element.y + measure.actualBoundingBoxAscent - height / 2
|
element.y + 2 * element.measure.actualBoundingBoxAscent - height / 2
|
||||||
);
|
);
|
||||||
|
context.font = font;
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
throw new Error("Unimplemented type " + element.type);
|
throw new Error("Unimplemented type " + element.type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSelection(selection) {
|
||||||
|
elements.forEach(element => {
|
||||||
|
element.isSelected =
|
||||||
|
selection.x < element.x &&
|
||||||
|
selection.y < element.y &&
|
||||||
|
selection.x + selection.width > element.x + element.width &&
|
||||||
|
selection.y + selection.height > element.y + element.height;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [draggingElement, setDraggingElement] = React.useState(null);
|
const [draggingElement, setDraggingElement] = React.useState(null);
|
||||||
const [elementType, setElementType] = React.useState("selection");
|
const [elementType, setElementType] = React.useState("selection");
|
||||||
const [selectedElements, setSelectedElements] = React.useState([]);
|
|
||||||
function ElementOption({ type, children }) {
|
function ElementOption({ type, children }) {
|
||||||
return (
|
return (
|
||||||
<label>
|
<label>
|
||||||
@ -132,21 +141,42 @@ function App() {
|
|||||||
width={window.innerWidth}
|
width={window.innerWidth}
|
||||||
height={window.innerHeight}
|
height={window.innerHeight}
|
||||||
onMouseDown={e => {
|
onMouseDown={e => {
|
||||||
const element = newElement(
|
const x = e.clientX - e.target.offsetLeft;
|
||||||
elementType,
|
const y = e.clientY - e.target.offsetTop;
|
||||||
e.clientX - e.target.offsetLeft,
|
const element = newElement(elementType, x, y);
|
||||||
e.clientY - e.target.offsetTop
|
|
||||||
);
|
if (elementType === "text") {
|
||||||
|
element.text = prompt("What text do you want?");
|
||||||
|
element.font = "20px Virgil";
|
||||||
|
const font = context.font;
|
||||||
|
context.font = element.font;
|
||||||
|
element.measure = context.measureText(element.text);
|
||||||
|
context.font = font;
|
||||||
|
const height =
|
||||||
|
element.measure.actualBoundingBoxAscent +
|
||||||
|
element.measure.actualBoundingBoxDescent;
|
||||||
|
// Center the text
|
||||||
|
element.x -= element.measure.width / 2;
|
||||||
|
element.y -= element.measure.actualBoundingBoxAscent;
|
||||||
|
element.width = element.measure.width;
|
||||||
|
element.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateShape(element);
|
||||||
elements.push(element);
|
elements.push(element);
|
||||||
setDraggingElement(element);
|
if (elementType === "text") {
|
||||||
|
setDraggingElement(null);
|
||||||
|
} else {
|
||||||
|
setDraggingElement(element);
|
||||||
|
}
|
||||||
drawScene();
|
drawScene();
|
||||||
}}
|
}}
|
||||||
onMouseUp={e => {
|
onMouseUp={e => {
|
||||||
setDraggingElement(null);
|
setDraggingElement(null);
|
||||||
if (elementType === "selection") {
|
if (elementType === "selection") {
|
||||||
elements.forEach(element => {
|
// Remove actual selection element
|
||||||
element.isSelected = false;
|
elements.pop();
|
||||||
});
|
setSelection(draggingElement);
|
||||||
}
|
}
|
||||||
drawScene();
|
drawScene();
|
||||||
}}
|
}}
|
||||||
@ -157,18 +187,11 @@ function App() {
|
|||||||
draggingElement.width = width;
|
draggingElement.width = width;
|
||||||
// Make a perfect square or circle when shift is enabled
|
// Make a perfect square or circle when shift is enabled
|
||||||
draggingElement.height = e.shiftKey ? width : height;
|
draggingElement.height = e.shiftKey ? width : height;
|
||||||
|
|
||||||
generateShape(draggingElement);
|
generateShape(draggingElement);
|
||||||
|
|
||||||
if (elementType === "selection") {
|
if (elementType === "selection") {
|
||||||
elements.forEach(element => {
|
setSelection(draggingElement);
|
||||||
element.isSelected =
|
|
||||||
draggingElement.x <= element.x &&
|
|
||||||
draggingElement.y <= element.y &&
|
|
||||||
draggingElement.x + draggingElement.width >=
|
|
||||||
element.x + element.width &&
|
|
||||||
draggingElement.y + draggingElement.height >=
|
|
||||||
element.y + element.height;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
drawScene();
|
drawScene();
|
||||||
}}
|
}}
|
||||||
@ -177,19 +200,21 @@ function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
const rootElement = document.getElementById("root");
|
const rootElement = document.getElementById("root");
|
||||||
|
ReactDOM.render(<App />, rootElement);
|
||||||
|
const canvas = document.getElementById("canvas");
|
||||||
|
const rc = rough.canvas(canvas);
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
|
||||||
function drawScene() {
|
function drawScene() {
|
||||||
ReactDOM.render(<App />, rootElement);
|
ReactDOM.render(<App />, rootElement);
|
||||||
|
|
||||||
const canvas = document.getElementById("canvas");
|
|
||||||
const rc = rough.canvas(canvas);
|
|
||||||
const context = canvas.getContext("2d");
|
|
||||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
elements.forEach(element => {
|
elements.forEach(element => {
|
||||||
element.draw(rc, context);
|
element.draw(rc, context);
|
||||||
if (element.isSelected) {
|
if (element.isSelected) {
|
||||||
const margin = 4;
|
const margin = 4;
|
||||||
|
const lineDash = context.getLineDash();
|
||||||
context.setLineDash([8, 4]);
|
context.setLineDash([8, 4]);
|
||||||
context.strokeRect(
|
context.strokeRect(
|
||||||
element.x - margin,
|
element.x - margin,
|
||||||
@ -197,7 +222,7 @@ function drawScene() {
|
|||||||
element.width + margin * 2,
|
element.width + margin * 2,
|
||||||
element.height + margin * 2
|
element.height + margin * 2
|
||||||
);
|
);
|
||||||
context.setLineDash([]);
|
context.setLineDash(lineDash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user