From b4de99a7d23b7dbb085a15602f8d56d8631a6c1d Mon Sep 17 00:00:00 2001
From: Hannah L
Date: Sat, 22 Mar 2025 10:25:42 -0500
Subject: [PATCH 1/6] Adds scale to percentage updates - user input and display
will be in percentage instead of a decimal scale. Styles the open pdf message
a little bit more. Changes the styling of the scale message (see if you like
it or not, it takes up a bit more screen real estate)
---
app/[locale]/calibrate/page.tsx | 8 +++--
app/[locale]/globals.css | 39 +++++++++++++++++++++
app/_components/canvases/overlay-canvas.tsx | 4 ---
app/_components/header.tsx | 4 ++-
app/_components/menus/scale-menu.tsx | 26 +++++++++++---
app/_components/menus/side-menu.tsx | 5 ++-
app/_components/modifiers-banner.tsx | 30 ++++++++++++++++
app/_components/pdf-viewer.tsx | 21 +++++++++--
app/_components/theme/colors.ts | 4 +--
app/_components/theme/styles.ts | 6 ++++
app/_lib/drawing.ts | 28 ++++++---------
app/_lib/remove-non-digits.ts | 13 +++++++
app/_reducers/patternScaleReducer.ts | 6 ++--
messages/en.json | 5 +--
tailwind.config.ts | 13 +++++++
15 files changed, 173 insertions(+), 39 deletions(-)
create mode 100644 app/_components/modifiers-banner.tsx
diff --git a/app/[locale]/calibrate/page.tsx b/app/[locale]/calibrate/page.tsx
index bbd0931a..145bddde 100644
--- a/app/[locale]/calibrate/page.tsx
+++ b/app/[locale]/calibrate/page.tsx
@@ -75,6 +75,7 @@ import { Button } from "@/_components/buttons/button";
import { erosionFilter } from "@/_lib/erode";
import SvgViewer from "@/_components/svg-viewer";
import { toggleFullScreen } from "@/_lib/full-screen";
+import ModifiersBanner from "@/_components/modifiers-banner";
const defaultStitchSettings = {
lineCount: 1,
@@ -296,7 +297,7 @@ export default function Page() {
setMeasuring(false);
setPageCount(0);
setLayers({});
- dispatchPatternScaleAction({ type: "set", scale: "1.00" });
+ dispatchPatternScaleAction({ type: "set", scale: "1.000" });
const lineThicknessString = localStorage.getItem(
`lineThickness:${files[0].name}`,
);
@@ -703,10 +704,11 @@ export default function Page() {
}
+ noData={
+
+
{t("noDataFirst")}
+
+
{t("noDataLast")}
+
+ }
error={{t("error")}
}
onLoadError={() => setFileLoadStatus(LoadStatusEnum.FAILED)}
>
diff --git a/app/_components/theme/colors.ts b/app/_components/theme/colors.ts
index f7c4c54a..f063ac2a 100644
--- a/app/_components/theme/colors.ts
+++ b/app/_components/theme/colors.ts
@@ -29,8 +29,8 @@ export function getColorClasses(
}
case ButtonColor.PURPLE: {
return style === ButtonStyle.OUTLINE
- ? "text-purple-700 border-purple-700 hover:bg-purple-800 focus:ring-purple-300 dark:border-purple-500 dark:text-purple-500 dark:hover:bg-purple-500 dark:focus:ring-purple-800"
- : "bg-purple-700 hover:bg-purple-800 focus:ring-purple-300 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-800";
+ ? "btn-primary-outline"
+ : "btn-primary";
}
}
}
diff --git a/app/_components/theme/styles.ts b/app/_components/theme/styles.ts
index 75aedb73..5a7052f3 100644
--- a/app/_components/theme/styles.ts
+++ b/app/_components/theme/styles.ts
@@ -9,4 +9,10 @@ export function getButtonStyleClasses(style: ButtonStyle) {
: `flex gap-2 items-center text-white focus:ring-4 font-medium rounded-lg text-sm px-5 py-2.5 focus:outline-none`;
}
+export function getStaticButtonStyleClasses(style: ButtonStyle) {
+ return style === ButtonStyle.OUTLINE
+ ? `flex gap-2 dark:bg-black bg-white items-center border border-2 border-solid focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center`
+ : `flex gap-2 items-center text-white font-medium rounded-lg text-sm px-5 py-2.5`;
+}
+
export const sideMenuStyles = `flex flex-col gap-2 p-2 w-64 items-start bg-white dark:bg-black border-b border-r border-gray-200 dark:border-gray-700`;
diff --git a/app/_lib/drawing.ts b/app/_lib/drawing.ts
index 282ee017..2a773c26 100644
--- a/app/_lib/drawing.ts
+++ b/app/_lib/drawing.ts
@@ -41,7 +41,6 @@ export class CanvasState {
public magnifying: boolean,
public restoreTransforms: RestoreTransforms | null,
public t: any,
- public patternScale: string | null,
) {
this.isConcave = checkIsConcave(this.points);
}
@@ -113,15 +112,8 @@ export function drawPolygon(
}
export function drawOverlays(cs: CanvasState) {
- const {
- ctx,
- displaySettings,
- zoomedOut,
- t,
- magnifying,
- restoreTransforms,
- patternScale,
- } = cs;
+ const { ctx, displaySettings, zoomedOut, t, magnifying, restoreTransforms } =
+ cs;
const { grid, border, paper, flipLines, flippedPattern, disabled } =
displaySettings.overlay;
const { theme } = displaySettings;
@@ -153,14 +145,14 @@ export function drawOverlays(cs: CanvasState) {
if (flippedPattern && cs.isFlipped) {
drawFlippedPattern(cs);
}
- if (patternScale && Number(patternScale) !== 1) {
- drawMessage(
- cs,
- t.rich("scaled", {
- scale: () => String(Number(patternScale).toFixed(2)),
- }),
- );
- }
+ // if (patternScale && Number(patternScale) !== 1) {
+ // drawMessage(
+ // cs,
+ // t.rich("scaled", {
+ // scale: () => String(Number(patternScale).toFixed(2)),
+ // }),
+ // );
+ // }
}
}
diff --git a/app/_lib/remove-non-digits.ts b/app/_lib/remove-non-digits.ts
index 68dc42a3..9b6c5028 100644
--- a/app/_lib/remove-non-digits.ts
+++ b/app/_lib/remove-non-digits.ts
@@ -14,6 +14,19 @@ export default function removeNonDigits(
}
}
+export function roundTo(num: number, decimalDigits: number) {
+ const factor = 10 ** decimalDigits; // Takes 10^num
+ return Math.round(num * factor) / factor;
+}
+
+export function decimalToString(num: number, decimalDigits: number) {
+ const roundedNum = roundTo(num, decimalDigits);
+ if (Number.isInteger(roundedNum)) {
+ return num.toFixed(0);
+ }
+ return num.toFixed(decimalDigits);
+}
+
export function allowInteger(
s: string,
allowNegative: boolean = false,
diff --git a/app/_reducers/patternScaleReducer.ts b/app/_reducers/patternScaleReducer.ts
index 0f78efbe..301969aa 100644
--- a/app/_reducers/patternScaleReducer.ts
+++ b/app/_reducers/patternScaleReducer.ts
@@ -1,3 +1,5 @@
+import { roundTo } from "@/_lib/remove-non-digits";
+
interface DeltaAction {
type: "delta";
delta: number;
@@ -19,8 +21,8 @@ export default function PatternScaleReducer(
return action.scale;
}
case "delta": {
- const n = action.delta + Number(patternScale);
- const hm = n > 0 ? String(n.toFixed(2)) : patternScale;
+ const n = roundTo(action.delta + Number(patternScale), 3);
+ const hm = n > 0 ? n.toFixed(3) : patternScale;
return hm;
}
}
diff --git a/messages/en.json b/messages/en.json
index b141bd2e..3017140b 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -325,10 +325,11 @@
"OverlayCanvas": {
"zoomedOut": "click pattern to zoom in",
"magnifying": "click pattern to stop magnifying",
- "scaled": "× scale"
+ "scaled": "%"
},
"PdfViewer": {
"error": "Failed to load pattern",
- "noData": "Press the \"Open\" button to load a pattern"
+ "noDataFirst": "Press the",
+ "noDataLast": "button to load a pattern"
}
}
diff --git a/tailwind.config.ts b/tailwind.config.ts
index 4e0fa799..87e4f8a2 100644
--- a/tailwind.config.ts
+++ b/tailwind.config.ts
@@ -14,5 +14,18 @@ const config: Config = {
require("@tailwindcss/typography"),
require("@tailwindcss/aspect-ratio"),
],
+ theme: {
+ extend: {
+ keyframes: {
+ breathe: {
+ "0%, 100%": { color: "" }, // Primary color
+ "50%": { color: "#FACC15" }, // Secondary color
+ },
+ },
+ animation: {
+ breathe: "breathe 1.5s ease-in-out infinite",
+ },
+ },
+ },
};
export default config;
From 2ee3ed3f9b49b1c6c88bf508b471bbcf17cea1cf Mon Sep 17 00:00:00 2001
From: Hannah L
Date: Sat, 22 Mar 2025 10:26:21 -0500
Subject: [PATCH 2/6] removes patternScale from overlay canvas in favor of a
colored bar
---
app/[locale]/calibrate/page.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/[locale]/calibrate/page.tsx b/app/[locale]/calibrate/page.tsx
index 145bddde..d2afbcc0 100644
--- a/app/[locale]/calibrate/page.tsx
+++ b/app/[locale]/calibrate/page.tsx
@@ -699,7 +699,7 @@ export default function Page() {
zoomedOut={zoomedOut}
magnifying={magnifying}
restoreTransforms={restoreTransforms}
- patternScale={String(patternScaleFactor)}
+ // patternScale={String(patternScaleFactor)}
/>
From d906bceab7dcebb65df5177ae3375d6bed05601b Mon Sep 17 00:00:00 2001
From: Hannah L
Date: Sat, 22 Mar 2025 10:28:49 -0500
Subject: [PATCH 3/6] Added changelog and fixed build error
---
CHANGELOG.md | 3 ++-
app/[locale]/globals.css | 14 +++++++-------
app/_components/canvases/calibration-canvas.tsx | 1 -
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fb4d6551..5b99c79b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,12 +10,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Side menu for stitch, layers, and scale menus
-- Scale menu for changing the pattern scale
+- Scale menu for changing the pattern scale (modified to use percentage instead of decimal)
- "Open With Pattern Projector" for PDF files on desktop, when installed with Chrome/Edge
- Show a pop up when there's an error
- Change page range in stitch menu with +/- (use + to throw beginning pages at the end e.g. for instruction pages)
- Option to arrange stitched pages by column order
- Support for SVG (with layer visibility toggling), PNG, and JPEG
+- Modified open pdf message slightly to add styling
### Changed
diff --git a/app/[locale]/globals.css b/app/[locale]/globals.css
index a3041fa2..5d28ae7c 100644
--- a/app/[locale]/globals.css
+++ b/app/[locale]/globals.css
@@ -29,11 +29,11 @@
/* Button base classes */
.btn-outline {
- @apply flex gap-2 dark:bg-black bg-white items-center border-2 border-solid focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center
+ @apply flex gap-2 dark:bg-black bg-white items-center border-2 border-solid focus:outline-none font-medium rounded-lg text-sm px-5 py-2.5 text-center;
}
.btn {
- @apply flex gap-2 items-center text-white font-medium rounded-lg text-sm px-5 py-2.5
+ @apply flex gap-2 items-center text-white font-medium rounded-lg text-sm px-5 py-2.5;
}
/* Primary color button */
@@ -42,24 +42,24 @@
}
.btn-primary-static {
- @apply btn bg-purple-700 dark:bg-purple-600
+ @apply btn bg-purple-700 dark:bg-purple-600;
}
.btn-primary-outline {
- @apply btn-primary-static-outline hover:bg-purple-800 focus:ring-purple-300 dark:hover:bg-purple-500 dark:focus:ring-purple-800
+ @apply btn-primary-static-outline hover:bg-purple-800 focus:ring-purple-300 dark:hover:bg-purple-500 dark:focus:ring-purple-800;
}
.btn-primary {
- @apply btn-primary-static hover:bg-purple-800 focus:ring-purple-300 dark:hover:bg-purple-700 dark:focus:ring-purple-800
+ @apply btn-primary-static hover:bg-purple-800 focus:ring-purple-300 dark:hover:bg-purple-700 dark:focus:ring-purple-800;
}
/* Secondary color button */
.btn-secondary-outline-static {
- @apply text-blue-700 border-blue-700 dark:border-blue-500 dark:text-blue-500
+ @apply text-blue-700 border-blue-700 dark:border-blue-500 dark:text-blue-500;
}
.btn-secondary-static {
- @apply bg-blue-700 dark:bg-blue-600
+ @apply bg-blue-700 dark:bg-blue-600;
}
}
diff --git a/app/_components/canvases/calibration-canvas.tsx b/app/_components/canvases/calibration-canvas.tsx
index a7498eda..cb969ed7 100644
--- a/app/_components/canvases/calibration-canvas.tsx
+++ b/app/_components/canvases/calibration-canvas.tsx
@@ -95,7 +95,6 @@ export default function CalibrationCanvas({
false,
null,
null,
- null,
);
draw(cs);
}
From f165ac1c09dd32e65bc112db1fd895ade6d7e9d6 Mon Sep 17 00:00:00 2001
From: Hannah L
Date: Sat, 22 Mar 2025 11:03:31 -0500
Subject: [PATCH 4/6] Adds modifications based on Sasha's comments and a
subsequent discussion over DM. Does not modify the input value to percentage,
but instead uses the new proposed styling to add both units to the display
bar
---
app/_components/menus/scale-menu.tsx | 4 ++--
app/_components/modifiers-banner.tsx | 7 ++++++-
messages/en.json | 2 +-
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/app/_components/menus/scale-menu.tsx b/app/_components/menus/scale-menu.tsx
index 31363291..e5e5e574 100644
--- a/app/_components/menus/scale-menu.tsx
+++ b/app/_components/menus/scale-menu.tsx
@@ -17,9 +17,9 @@ export default function ScaleMenu({
const scaleValue: string = useMemo(() => {
const number = +patternScale;
if (Number.isNaN(number)) {
- return "100%";
+ return "1";
}
- return `${decimalToString(number * 100, 1)}%`;
+ return decimalToString(number, 2);
}, [patternScale]);
const convertInputToScale = (newString: string, oldString: string) => {
diff --git a/app/_components/modifiers-banner.tsx b/app/_components/modifiers-banner.tsx
index 2a52c07e..fbe9bf30 100644
--- a/app/_components/modifiers-banner.tsx
+++ b/app/_components/modifiers-banner.tsx
@@ -1,12 +1,14 @@
import React, { useMemo } from "react";
import { visible } from "@/_components/theme/css-functions";
import { decimalToString } from "@/_lib/remove-non-digits";
+import { useTranslations } from "next-intl";
export default function ModifiersBanner({
patternScale,
}: {
patternScale?: number;
}) {
+ const t = useTranslations("OverlayCanvas");
const hidden = useMemo(() => {
if (!patternScale || patternScale === 1) {
return true;
@@ -16,7 +18,10 @@ export default function ModifiersBanner({
const text = useMemo(() => {
if (patternScale && patternScale !== 1) {
- return `${decimalToString(patternScale * 100, 1)}%`;
+ return t.rich("scaled", {
+ scale: () => decimalToString(patternScale, 2),
+ scaleP: () => decimalToString(patternScale * 100, 1),
+ });
}
}, [patternScale]);
diff --git a/messages/en.json b/messages/en.json
index 3017140b..c3eb80ae 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -325,7 +325,7 @@
"OverlayCanvas": {
"zoomedOut": "click pattern to zoom in",
"magnifying": "click pattern to stop magnifying",
- "scaled": "%"
+ "scaled": "Scaled to x (%)"
},
"PdfViewer": {
"error": "Failed to load pattern",
From b212093d008c18013a304318b30e5a4c1cad5381 Mon Sep 17 00:00:00 2001
From: Hannah L
Date: Sat, 22 Mar 2025 11:57:55 -0500
Subject: [PATCH 5/6] Resized text to original size after previewing on vercel.
My transforms must be different locally
---
app/_components/pdf-viewer.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/_components/pdf-viewer.tsx b/app/_components/pdf-viewer.tsx
index 7527fe39..f41b83a4 100644
--- a/app/_components/pdf-viewer.tsx
+++ b/app/_components/pdf-viewer.tsx
@@ -173,10 +173,10 @@ export default function PdfViewer({
file={file}
onLoadSuccess={onDocumentLoadSuccess}
noData={
-
+
{t("noDataFirst")}
-
+