Skip to content

Commit

Permalink
feat: use mouse to control canvas size
Browse files Browse the repository at this point in the history
  • Loading branch information
Lisianthus-A committed May 20, 2024
1 parent 72266bc commit 06a0bcb
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 34 deletions.
58 changes: 56 additions & 2 deletions src/layout/Canvas/Canvas.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,48 @@
background-color: #fafafa;
scrollbar-width: thin;

.resize-preview {
display: none;
pointer-events: none;
position: absolute;
left: 0;
top: 0;
border: 1px dotted #aaa;
}

.block-r,
.block-b,
.block-br {
position: absolute;
width: 8px;
height: 8px;
background-color: #fff;
border: 1px solid #aaa;
}

.block-r {
right: -4px;
top: 50%;
transform: translateY(-50%);
z-index: 1;
cursor: ew-resize;
}

.block-b {
left: 50%;
bottom: -4px;
transform: translateX(-50%);
z-index: 1;
cursor: ns-resize;
}

.block-br {
bottom: -4px;
right: -4px;
z-index: 1;
cursor: nwse-resize;
}

&::-webkit-scrollbar {
display: block;
width: 12px;
Expand All @@ -25,8 +67,20 @@
top: 0;
width: 1280px;
height: 720px;
background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%),
linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%);
background-image: linear-gradient(
45deg,
#eee 25%,
transparent 25%,
transparent 75%,
#eee 75%
),
linear-gradient(
45deg,
#eee 25%,
transparent 25%,
transparent 75%,
#eee 75%
);
background-size: 24px 24px;
background-position: 0 0, 12px 12px;
border: 1px solid #e6e6e6;
Expand Down
62 changes: 61 additions & 1 deletion src/layout/Canvas/Canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import { CanvasModel } from "@/models";
import EventBus from "@/utils/event";
import { canvasRef as storeCanvasRef } from "@/store";
import styles from "./Canvas.module.scss";
import type { MouseEvent as ReactMouseEvent } from "react";

function Canvas() {
const canvasData = useContext(CanvasDataContext);
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const previewRef = useRef<HTMLDivElement | null>(null);

const handleClick = () => {
const canvas = storeCanvasRef.current;
Expand All @@ -18,6 +20,50 @@ function Canvas() {
}
};

const handleMouseDown = (evt: ReactMouseEvent, type: string) => {
const el = previewRef.current;
const canvas = storeCanvasRef.current;
if (!el || !canvas) {
return;
}
evt.preventDefault();

const size = canvas.getSize();
const initPos = { x: evt.pageX, y: evt.pageY };
const allowX = type.indexOf("r") >= 0;
const allowY = type.indexOf("b") >= 0;

const onMouseMove = (evt: MouseEvent) => {
const width = allowX
? Math.max(0, size.width + evt.pageX - initPos.x)
: size.width;
const height = allowY
? Math.max(0, size.height + evt.pageY - initPos.y)
: size.height;
el.style.setProperty("width", `${width}px`);
el.style.setProperty("height", `${height}px`);
};
const onMouseUp = (evt: MouseEvent) => {
const width = allowX
? Math.max(0, size.width + evt.pageX - initPos.x)
: size.width;
const height = allowY
? Math.max(0, size.height + evt.pageY - initPos.y)
: size.height;
canvas.resize(width, height);

el.style.setProperty("display", "none");
window.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp);
};

el.style.setProperty("display", "block");
el.style.setProperty("width", `${size.width}px`);
el.style.setProperty("height", `${size.height}px`);
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("mouseup", onMouseUp);
};

useLayoutEffect(() => {
if (!canvasRef.current) {
return;
Expand Down Expand Up @@ -106,7 +152,21 @@ function Canvas() {

return (
<div className={styles.canvas} onClick={handleClick}>
<div id="grid" className="gap" />
<div id="grid" className="gap">
<div ref={previewRef} className={styles["resize-preview"]} />
<div
className={styles["block-r"]}
onMouseDown={(evt) => handleMouseDown(evt, "r")}
/>
<div
className={styles["block-b"]}
onMouseDown={(evt) => handleMouseDown(evt, "b")}
/>
<div
className={styles["block-br"]}
onMouseDown={(evt) => handleMouseDown(evt, "br")}
/>
</div>
<canvas className="gap" ref={canvasRef} />
</div>
);
Expand Down
14 changes: 7 additions & 7 deletions src/layout/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import styles from "./Sidebar.module.scss";
import Attr from "./Attr";
import Material from "./Material";
import Text from "./Text";
import My from "./My";
// import My from "./My";
import Shape from "./Shape";

const tabs = [
Expand Down Expand Up @@ -37,11 +37,11 @@ const tabs = [
iconType: "icon-attr",
text: "属性",
},
{
id: "my",
iconType: "icon-my",
text: "我的",
},
// {
// id: "my",
// iconType: "icon-my",
// text: "我的",
// },
];

function Sidebar() {
Expand Down Expand Up @@ -94,7 +94,7 @@ function Sidebar() {
{currentTab === "text" && <Text />}
{currentTab === "shape" && <Shape />}
{currentTab === "attr" && <Attr />}
{currentTab === "my" && <My />}
{/* {currentTab === "my" && <My />} */}
</div>
</div>
);
Expand Down
57 changes: 33 additions & 24 deletions src/models/CanvasModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ class CanvasModel {
this.disableSave = false;

this.loadFromJson = this.loadFromJson.bind(this);
this.getSize = this.getSize.bind(this);
this.resize = this.resize.bind(this);
this.replaceBackgroundImage = this.replaceBackgroundImage.bind(this);
this.removeBackgroundImage = this.removeBackgroundImage.bind(this);
Expand Down Expand Up @@ -328,6 +329,14 @@ class CanvasModel {
};
}

// 获取当前宽高
getSize() {
return {
width: this.width,
height: this.height,
};
}

// 设置宽高
resize(width: number, height: number) {
this.width = width;
Expand Down Expand Up @@ -518,32 +527,32 @@ class CanvasModel {
return base64String;
}

// 保存为 json
toJson(local?: boolean) {
const data = {
type: "canvas",
width: this.width,
height: this.height,
backgroundImage: this.backgroundImage,
backgroundColor: this.backgroundColor,
bgFilter: this.bgFilter,
children: this.children.map((child) => child.getData()),
};
// 保存为 json
toJson(local?: boolean) {
const data = {
type: "canvas",
width: this.width,
height: this.height,
backgroundImage: this.backgroundImage,
backgroundColor: this.backgroundColor,
bgFilter: this.bgFilter,
children: this.children.map((child) => child.getData()),
};

if (local) {
const blob = new Blob([JSON.stringify(data)], {
type: "application/json",
});
const a = document.createElement("a");
const url = URL.createObjectURL(blob);
a.href = url;
a.download = `data-${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
}
if (local) {
const blob = new Blob([JSON.stringify(data)], {
type: "application/json",
});
const a = document.createElement("a");
const url = URL.createObjectURL(blob);
a.href = url;
a.download = `data-${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
}

return data;
}
return data;
}

render() {
this.instance.renderAll();
Expand Down

0 comments on commit 06a0bcb

Please sign in to comment.