Open
Description
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
First, thank you for implementing this package. It was the only one among canvas drawing packages that supported various devices.
To enhance the user experience, I hope to see where the cursor is positioned and current stroke width.
Something like this!
Describe the solution you'd like
A clear and concise description of what you want to happen.
To solve this problem, I made a custom hook to implement this.
It quite works well, and I think this feature would make this package better!
import { forwardRef, useEffect, useRef, useState } from "react";
interface StrokePreviewProps {
top: string;
left: string;
strokeWidth: number;
}
const StrokePreview = forwardRef<HTMLDivElement, StrokePreviewProps>(
({ top, left, strokeWidth }, ref) => (
<div
style={{
top,
left,
width: `${strokeWidth}px`,
height: `${strokeWidth}px`,
transform: "translate(-50%, -50%)"
}}
className="absolute rounded-full bg-[rgba(182,146,246,0.75)]"
ref={ref}
/>
)
);
function useStrokePreview() {
const [top, setTop] = useState<string>("0px");
const [left, setLeft] = useState<string>("0px");
const canvasContainerRef = useRef<HTMLDivElement>(null);
const cursorFollowerRef = useRef<HTMLDivElement>(null);
const timeoutId = useRef<ReturnType<typeof setTimeout>>();
useEffect(() => {
const positionCursorFollower = (e: MouseEvent | PointerEvent) => {
timeoutId.current = setTimeout(() => {
if (canvasContainerRef.current) {
const { offsetHeight, offsetWidth } = canvasContainerRef.current;
setTop(`${Math.min(offsetHeight, Math.max(0, e.offsetY))}px`);
setLeft(`${Math.min(offsetWidth, Math.max(0, e.offsetX))}px`);
}
}, 1);
};
if (canvasContainerRef.current) {
canvasContainerRef.current.addEventListener(
"mousemove",
positionCursorFollower
);
canvasContainerRef.current.addEventListener(
"pointermove",
positionCursorFollower
);
}
return () => {
if (timeoutId.current) {
clearTimeout(timeoutId.current);
}
canvasContainerRef?.current?.removeEventListener(
"mousemove",
positionCursorFollower
);
canvasContainerRef?.current?.removeEventListener(
"pointermove",
positionCursorFollower
);
};
}, [!!canvasContainerRef.current]);
return { top, left, canvasContainerRef, cursorFollowerRef };
}
export default StrokePreview;
export { useStrokePreview };
<div className="relative">
<StrokePreview
top={strokeTop}
left={strokeLeft}
strokeWidth={strokeWidth}
ref={cursorFollowerRef}
/>
<div className="mb-[20px] flex flex-col" ref={canvasContainerRef}>
<img src={imgSrc} alt="original" />
<ReactSketchCanvas
style={{
position: "absolute",
top: 0,
left: 0,
cursor: "none"
}}
canvasColor="transparent"
strokeColor="rgba(182, 146, 246, 0.75)"
strokeWidth={strokeWidth}
eraserWidth={strokeWidth}
onStroke={onChange}
ref={skectchCanvasRef}
/>
</div>
</div>
And the result seems like this.
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
Additional context
Add any other context or screenshots about the feature request here.
As I am novice in handling interactions with devices like tablets and mobile phones, I think I may have missed sth.
Thank you for reading!
Metadata
Metadata
Assignees
Labels
No labels