Skip to content

Commit 1f2e112

Browse files
authored
Merge pull request #908 from MaterArc/center-text
Align to Center
2 parents 42863d7 + a9ec980 commit 1f2e112

File tree

5 files changed

+155
-0
lines changed

5 files changed

+155
-0
lines changed

features/align-to-center/data.json

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"title": "Align to Center",
3+
"description": "Allows you to align text in Instructions and Notes & Credits boxes to the center of the input.",
4+
"credits": [
5+
{
6+
"username": "Brass_Glass",
7+
"url": "https://scratch.mit.edu/users/Brass_Glass/"
8+
},
9+
{
10+
"username": "MaterArc",
11+
"url": "https://scratch.mit.edu/users/MaterArc/"
12+
}
13+
],
14+
"type": ["Website"],
15+
"tags": ["New", "Recommended"],
16+
"dynamic": true,
17+
"scripts": [{ "file": "script.js", "runOn": "/projects/*" }],
18+
"styles": [{ "file": "style.css", "runOn": "/projects/*" }],
19+
"resources": [{ "name": "center-align", "path": "/icon.svg" }],
20+
"options": [{ "id": "use-align-hotkey", "name": "Use Hotkey (Ctrl + U)", "type": "boolean" }],
21+
"components": [
22+
{
23+
"type": "info",
24+
"content": "For Mac users, use Command + U when the hotkey option is enabled to center text.",
25+
"if": {
26+
"type": "all",
27+
"conditions": [
28+
{
29+
"type": "os",
30+
"value": "Macintosh"
31+
}
32+
]
33+
}
34+
}
35+
]
36+
}

features/align-to-center/icon.svg

Lines changed: 1 addition & 0 deletions
Loading

features/align-to-center/script.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
export default async function ({ feature, console }) {
2+
const availableWidth = 405;
3+
4+
function getSpaceWidth() {
5+
const span = document.createElement("span");
6+
span.style.visibility = "hidden";
7+
span.style.whiteSpace = "pre";
8+
span.textContent = " ";
9+
document.body.appendChild(span);
10+
const spaceWidth = span.getBoundingClientRect().width;
11+
document.body.removeChild(span);
12+
return spaceWidth;
13+
}
14+
15+
function getTextWidth(text) {
16+
const span = document.createElement("span");
17+
span.style.visibility = "hidden";
18+
span.style.whiteSpace = "pre";
19+
span.textContent = text;
20+
document.body.appendChild(span);
21+
const textWidth = span.getBoundingClientRect().width;
22+
document.body.removeChild(span);
23+
return textWidth;
24+
}
25+
26+
function clearCenterAlignment(textarea) {
27+
const lines = textarea.value.split("\n");
28+
const uncenteredLines = lines.map((line) => {
29+
return line.replace(/^\s+/, "");
30+
});
31+
textarea.value = uncenteredLines.join("\n");
32+
}
33+
34+
function centerAlignText(textarea) {
35+
if (!feature.self.enabled) return;
36+
37+
const form = document.querySelector(".project-notes");
38+
if (form) {
39+
const activeElement = textarea || document.activeElement;
40+
if (
41+
activeElement.tagName === "TEXTAREA" &&
42+
form.contains(activeElement)
43+
) {
44+
clearCenterAlignment(activeElement);
45+
46+
const spaceWidth = getSpaceWidth();
47+
const lines = activeElement.value.split("\n");
48+
const centeredLines = lines.map((line) => {
49+
const textWidth = getTextWidth(line);
50+
const totalSpaces = (availableWidth - textWidth) / spaceWidth / 2;
51+
const spaces =
52+
totalSpaces > 0 ? " ".repeat(Math.floor(totalSpaces)) : "";
53+
return spaces + line;
54+
});
55+
activeElement.value = centeredLines.join("\n");
56+
}
57+
}
58+
}
59+
60+
window.addEventListener("keydown", (event) => {
61+
if ((event.ctrlKey || event.metaKey) && event.key === "u") {
62+
if (feature.settings.get("use-align-hotkey")) {
63+
centerAlignText();
64+
}
65+
}
66+
});
67+
68+
console.log("hey");
69+
70+
ScratchTools.waitForElements(
71+
".project-notes .project-textlabel",
72+
function (div) {
73+
if (div.querySelector(".ste-align-center")) return;
74+
75+
let textarea = div.parentElement.querySelector("textarea");
76+
77+
let img = document.createElement("img");
78+
img.src = feature.self.getResource("center-align");
79+
img.className = "ste-align-center";
80+
img.addEventListener("click", function () {
81+
centerAlignText(textarea);
82+
});
83+
feature.self.hideOnDisable(img);
84+
85+
div.appendChild(img);
86+
87+
textarea.addEventListener("focusin", function () {
88+
img.classList.add("show");
89+
});
90+
91+
textarea.addEventListener("focusout", function () {
92+
img.classList.remove("show");
93+
});
94+
}
95+
);
96+
}

features/align-to-center/style.css

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.project-notes .project-textlabel {
2+
position: relative;
3+
width: 100%;
4+
}
5+
6+
.ste-align-center {
7+
position: absolute;
8+
right: 0px;
9+
top: 0px;
10+
height: 100%;
11+
cursor: pointer;
12+
display: none;
13+
}
14+
15+
.ste-align-center.show {
16+
display: block;
17+
}

features/features.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
[
2+
{
3+
"version": 2,
4+
"id": "align-to-center",
5+
"versionAdded": "v4.0.0"
6+
},
27
{
38
"version": 2,
49
"id": "more-editor-fonts",

0 commit comments

Comments
 (0)