mirror of
https://github.com/ramvignesh-b/pi-ku.git
synced 2026-05-04 08:56:52 +00:00
fix: adjust canvas for responsiveness
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
|||||||
} from "react";
|
} from "react";
|
||||||
|
|
||||||
const PAD = 36;
|
const PAD = 36;
|
||||||
|
const BASE_WIDTH = 680;
|
||||||
|
|
||||||
export interface FabricObjectJSON {
|
export interface FabricObjectJSON {
|
||||||
type: string;
|
type: string;
|
||||||
@@ -28,6 +29,8 @@ export interface FabricImageJSON extends FabricObjectJSON {
|
|||||||
export interface CanvasJSON {
|
export interface CanvasJSON {
|
||||||
version: string;
|
version: string;
|
||||||
objects: (FabricObjectJSON | FabricImageJSON)[];
|
objects: (FabricObjectJSON | FabricImageJSON)[];
|
||||||
|
canvasWidth?: number;
|
||||||
|
canvasHeight?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CanvasTools = {
|
export type CanvasTools = {
|
||||||
@@ -59,15 +62,15 @@ const waitForLayout = (wrapper: HTMLDivElement): Promise<number> => {
|
|||||||
/**
|
/**
|
||||||
* Creates the primary text box for the letter.
|
* Creates the primary text box for the letter.
|
||||||
*/
|
*/
|
||||||
const createMainTextbox = (width: number): fabric.Textbox => {
|
const createMainTextbox = (): fabric.Textbox => {
|
||||||
return new fabric.Textbox("Take a deep breath...", {
|
return new fabric.Textbox("Take a deep breath...", {
|
||||||
name: "main-textbox",
|
name: "main-textbox",
|
||||||
originX: "left",
|
originX: "left",
|
||||||
originY: "top",
|
originY: "top",
|
||||||
left: PAD,
|
left: PAD,
|
||||||
top: PAD,
|
top: PAD,
|
||||||
width: width - PAD * 2,
|
width: BASE_WIDTH - PAD * 2,
|
||||||
fontSize: 16,
|
fontSize: 18,
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
fontFamily: "Playfair Display Variable",
|
fontFamily: "Playfair Display Variable",
|
||||||
fill: "#000",
|
fill: "#000",
|
||||||
@@ -108,11 +111,14 @@ const handleResize = (
|
|||||||
wrapper: HTMLDivElement | null,
|
wrapper: HTMLDivElement | null,
|
||||||
) => {
|
) => {
|
||||||
if (!wrapper) return;
|
if (!wrapper) return;
|
||||||
const neededHeight = textbox.top + textbox.height + PAD;
|
const scale = fCanvas.viewportTransform?.[0] || 1;
|
||||||
if (neededHeight > fCanvas.height) {
|
const neededLogicalHeight = textbox.top + textbox.height + PAD;
|
||||||
const newH = neededHeight + PAD;
|
const currentLogicalHeight = fCanvas.height / scale;
|
||||||
fCanvas.setDimensions({ height: newH });
|
|
||||||
wrapper.style.height = `${newH}px`;
|
if (neededLogicalHeight > currentLogicalHeight) {
|
||||||
|
const newPhysicalHeight = (neededLogicalHeight + PAD) * scale;
|
||||||
|
fCanvas.setDimensions({ height: newPhysicalHeight });
|
||||||
|
wrapper.style.height = `${newPhysicalHeight}px`;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,8 +184,12 @@ export const ComposeCanvas = forwardRef<
|
|||||||
async (
|
async (
|
||||||
canvas: fabric.Canvas,
|
canvas: fabric.Canvas,
|
||||||
data: CanvasJSON | null,
|
data: CanvasJSON | null,
|
||||||
width: number,
|
containerWidth: number,
|
||||||
): Promise<fabric.Textbox | null> => {
|
): Promise<fabric.Textbox | null> => {
|
||||||
|
// Always establish the scale relative to BASE_WIDTH
|
||||||
|
const scale = containerWidth / BASE_WIDTH;
|
||||||
|
canvas.setViewportTransform([scale, 0, 0, scale, 0, 0]);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await canvas.loadFromJSON(data);
|
await canvas.loadFromJSON(data);
|
||||||
if (readOnly) {
|
if (readOnly) {
|
||||||
@@ -190,7 +200,7 @@ export const ComposeCanvas = forwardRef<
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const textbox = createMainTextbox(width);
|
const textbox = createMainTextbox();
|
||||||
canvas.add(textbox);
|
canvas.add(textbox);
|
||||||
return textbox;
|
return textbox;
|
||||||
},
|
},
|
||||||
@@ -221,6 +231,7 @@ export const ComposeCanvas = forwardRef<
|
|||||||
fabricRef.current = canvas;
|
fabricRef.current = canvas;
|
||||||
|
|
||||||
const textbox = await loadContent(canvas, initialData, finalWidth);
|
const textbox = await loadContent(canvas, initialData, finalWidth);
|
||||||
|
|
||||||
if (textbox) {
|
if (textbox) {
|
||||||
textboxRef.current = textbox;
|
textboxRef.current = textbox;
|
||||||
setupTextboxInteractions(canvas, textbox);
|
setupTextboxInteractions(canvas, textbox);
|
||||||
@@ -256,7 +267,12 @@ export const ComposeCanvas = forwardRef<
|
|||||||
},
|
},
|
||||||
getData: () => {
|
getData: () => {
|
||||||
if (!fabricRef.current) return { version: "", objects: [] };
|
if (!fabricRef.current) return { version: "", objects: [] };
|
||||||
return fabricRef.current.toJSON() as CanvasJSON;
|
const json = fabricRef.current.toJSON() as CanvasJSON;
|
||||||
|
json.canvasWidth = BASE_WIDTH;
|
||||||
|
json.canvasHeight =
|
||||||
|
fabricRef.current.getHeight() /
|
||||||
|
(fabricRef.current.viewportTransform?.[3] || 1);
|
||||||
|
return json;
|
||||||
},
|
},
|
||||||
getJsonData: () => {
|
getJsonData: () => {
|
||||||
if (!fabricRef.current) return "";
|
if (!fabricRef.current) return "";
|
||||||
@@ -273,11 +289,10 @@ export const ComposeCanvas = forwardRef<
|
|||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
loadData: async (data: CanvasJSON) => {
|
loadData: async (data: CanvasJSON) => {
|
||||||
if (!fabricRef.current) return;
|
if (!(fabricRef.current && wrapperRef.current)) return;
|
||||||
await fabricRef.current.loadFromJSON(data);
|
const width = wrapperRef.current.clientWidth;
|
||||||
const textboxes = fabricRef.current.getObjects("Textbox");
|
const textbox = await loadContent(fabricRef.current, data, width);
|
||||||
if (textboxes.length > 0) {
|
if (textbox) {
|
||||||
const textbox = textboxes[0] as fabric.Textbox;
|
|
||||||
textboxRef.current = textbox;
|
textboxRef.current = textbox;
|
||||||
setupTextboxInteractions(fabricRef.current, textbox);
|
setupTextboxInteractions(fabricRef.current, textbox);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -265,7 +265,7 @@ export default function Editor() {
|
|||||||
placeholder="Someone dear..."
|
placeholder="Someone dear..."
|
||||||
value={recipient}
|
value={recipient}
|
||||||
onChange={(e) => setRecipient(e.target.value)}
|
onChange={(e) => setRecipient(e.target.value)}
|
||||||
className="bg-transparent border-none outline-none text-4xl font-serif text-base-content placeholder:text-base-content/10 w-full"
|
className="bg-transparent border-none outline-none text-2xl md:text-3xl lg:text-4xl font-serif text-base-content placeholder:text-base-content/10 w-full"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<DateDisplay />
|
<DateDisplay />
|
||||||
|
|||||||
Reference in New Issue
Block a user