Files
starr-philproperties/lib/bs/src/modules/client/hooks/rescript/canvas/SketchCanvas.js
T
kennethobsequio fbef7cb6e6 ready to test
Testing

Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
2026-06-22 10:07:20 +08:00

193 lines
4.8 KiB
JavaScript

// Generated by ReScript, PLEASE EDIT WITH CARE
import * as React from "react";
import * as UseSketch from "./useSketch.js";
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
import * as JsxRuntime from "react/jsx-runtime";
import SketchToolbarJsx from "./SketchToolbar.jsx";
let make = SketchToolbarJsx;
let SketchToolbar = {
make: make
};
function SketchCanvas(props) {
let onClear = props.onClear;
let onSave = props.onSave;
let color = props.color;
let tool = props.tool;
let isActive = props.isActive;
let canvasRef = React.useRef(null);
let isDrawing = React.useRef(false);
let lastPoint = React.useRef(undefined);
React.useEffect(() => {
let el = canvasRef.current;
if (!(el == null)) {
let parent = el.parentElement;
el.width = parent.offsetWidth;
el.height = parent.offsetHeight;
}
}, [isActive]);
let getPos = (e, canvas) => {
let rect = canvas.getBoundingClientRect();
return {
x: e.clientX - rect.left,
y: e.clientY - rect.top
};
};
let startDraw = e => {
let el = canvasRef.current;
if (el == null) {
return;
}
isDrawing.current = true;
let pos = getPos(e, el);
lastPoint.current = pos;
if (tool === "Highlighter") {
let ctx = el.getContext("2d");
let hex = UseSketch.colorToHex(color);
let width = UseSketch.toolToWidth(tool, 2.0);
ctx.globalAlpha = 0.25;
ctx.globalCompositeOperation = "source-over";
ctx.strokeStyle = hex;
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
return;
}
if (tool !== "Text") {
return;
}
let text = el.ownerDocument.defaultView.prompt("Enter text:", "");
if (text == null) {
return;
}
let ctx$1 = el.getContext("2d");
let hex$1 = UseSketch.colorToHex(color);
ctx$1.globalAlpha = 1.0;
ctx$1.fillStyle = hex$1;
ctx$1.font = "bold 16px sans-serif";
ctx$1.fillText(text, pos.x, pos.y);
};
let draw = e => {
if (!(isDrawing.current && tool !== "Text")) {
return;
}
let el = canvasRef.current;
if (el == null) {
return;
}
let last = lastPoint.current;
if (last === undefined) {
return;
}
let ctx = el.getContext("2d");
let pos = getPos(e, el);
let hex = UseSketch.colorToHex(color);
let width = UseSketch.toolToWidth(tool, 2.0);
let exit = 0;
switch (tool) {
case "Highlighter" :
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
break;
case "Pen" :
case "Text" :
exit = 1;
break;
}
if (exit === 1) {
ctx.globalAlpha = 1.0;
ctx.strokeStyle = hex;
ctx.lineWidth = width;
ctx.lineCap = "round";
ctx.lineJoin = "round";
ctx.beginPath();
ctx.moveTo(last.x, last.y);
ctx.quadraticCurveTo(last.x + (pos.x - last.x) / 2.0, last.y + (pos.y - last.y) / 2.0, pos.x, pos.y);
ctx.stroke();
}
lastPoint.current = pos;
};
let stopDraw = _e => {
if (tool === "Highlighter") {
let el = canvasRef.current;
if (!(el == null)) {
let ctx = el.getContext("2d");
ctx.stroke();
ctx.globalAlpha = 1.0;
ctx.globalCompositeOperation = "source-over";
}
}
isDrawing.current = false;
lastPoint.current = undefined;
};
let handleClear = () => {
let el = canvasRef.current;
if (el == null) {
return;
}
let ctx = el.getContext("2d");
ctx.clearRect(0, 0, el.width, el.height);
onClear();
};
let handleSave = () => {
let el = canvasRef.current;
if (el == null) {
return;
}
let dataUrl = el.toDataURL("image/png");
let link = document.createElement("a");
link.href = dataUrl;
link.download = "sketch.png";
link.click();
onSave();
};
if (isActive) {
return JsxRuntime.jsxs("div", {
children: [
JsxRuntime.jsx(make, {
state: {
isActive: isActive,
tool: tool,
color: color,
strokeWidth: 2.0
},
onSetTool: props.onSetTool,
onSetColor: props.onSetColor,
onClear: handleClear,
onSave: handleSave,
onClose: props.onClose
}),
JsxRuntime.jsx("canvas", {
ref: Primitive_option.some(canvasRef),
className: "w-full h-full cursor-crosshair",
height: "100%",
width: "100%",
onMouseDown: startDraw,
onMouseLeave: stopDraw,
onMouseMove: draw,
onMouseUp: stopDraw
})
],
className: "absolute inset-0 z-10",
style: {
pointerEvents: isActive ? "all" : "none"
}
});
} else {
return null;
}
}
let make$1 = SketchCanvas;
export {
SketchToolbar,
make$1 as make,
}
/* make Not a pure module */