mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
stuff
This commit is contained in:
@@ -13,6 +13,24 @@ export function Handlebars({ children }: HandlebarsProps) {
|
||||
const [leftHandle, setLeftHandle] = useState(0);
|
||||
const [rightHandle, setRightHandle] = useState(0);
|
||||
|
||||
const widthRef = useRef(0);
|
||||
const leftHandlePositionRef = useRef(0);
|
||||
const rightHandlePositionRef = useRef(0);
|
||||
|
||||
const dragRef = useRef<{
|
||||
isDragging: boolean;
|
||||
side: "left" | "right" | null;
|
||||
pointerId: number | null;
|
||||
startX: number;
|
||||
initialPosition: number;
|
||||
}>({
|
||||
isDragging: false,
|
||||
side: null,
|
||||
pointerId: null,
|
||||
startX: 0,
|
||||
initialPosition: 0,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const el = containerRef.current;
|
||||
if (!el) return;
|
||||
@@ -31,85 +49,85 @@ export function Handlebars({ children }: HandlebarsProps) {
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const leftEl = leftHandleRef.current;
|
||||
const rightEl = rightHandleRef.current;
|
||||
if (!leftEl || !rightEl) return;
|
||||
|
||||
let isDraggingLeft = false;
|
||||
let isDraggingRight = false;
|
||||
let startX = 0;
|
||||
let initialPosition = 0;
|
||||
|
||||
const handleMouseDown = (e: MouseEvent, isLeft: boolean) => {
|
||||
e.preventDefault();
|
||||
startX = e.clientX;
|
||||
|
||||
if (isLeft) {
|
||||
isDraggingLeft = true;
|
||||
initialPosition = leftHandle;
|
||||
} else {
|
||||
isDraggingRight = true;
|
||||
initialPosition = rightHandle;
|
||||
}
|
||||
|
||||
document.addEventListener("mousemove", handleMouseMove);
|
||||
document.addEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
const deltaX = e.clientX - startX;
|
||||
|
||||
if (isDraggingLeft) {
|
||||
const newPosition = Math.max(0, Math.min(rightHandle - 60, initialPosition + deltaX));
|
||||
setLeftHandle(newPosition);
|
||||
if (leftEl) {
|
||||
leftEl.style.transform = `translateX(${newPosition}px)`;
|
||||
}
|
||||
} else if (isDraggingRight) {
|
||||
const newPosition = Math.max(leftHandle + 60, Math.min(width, initialPosition + deltaX));
|
||||
setRightHandle(newPosition);
|
||||
if (rightEl) {
|
||||
rightEl.style.transform = `translateX(${newPosition}px)`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDraggingLeft = false;
|
||||
isDraggingRight = false;
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
|
||||
const leftMouseDown = (e: MouseEvent) => handleMouseDown(e, true);
|
||||
const rightMouseDown = (e: MouseEvent) => handleMouseDown(e, false);
|
||||
|
||||
leftEl.addEventListener("mousedown", leftMouseDown);
|
||||
rightEl.addEventListener("mousedown", rightMouseDown);
|
||||
|
||||
return () => {
|
||||
leftEl.removeEventListener("mousedown", leftMouseDown);
|
||||
rightEl.removeEventListener("mousedown", rightMouseDown);
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
widthRef.current = width;
|
||||
leftHandlePositionRef.current = leftHandle;
|
||||
rightHandlePositionRef.current = rightHandle;
|
||||
}, [leftHandle, rightHandle, width]);
|
||||
|
||||
useEffect(() => {
|
||||
const handlePointerMove = (event: PointerEvent) => {
|
||||
const { isDragging, side, pointerId, startX, initialPosition } =
|
||||
dragRef.current;
|
||||
|
||||
if (!isDragging) return;
|
||||
if (pointerId !== null && event.pointerId !== pointerId) return;
|
||||
if (!side) return;
|
||||
|
||||
const deltaX = event.clientX - startX;
|
||||
|
||||
if (side === "left") {
|
||||
const maxLeft = Math.max(0, rightHandlePositionRef.current - 60);
|
||||
const nextLeftHandle = Math.max(
|
||||
0,
|
||||
Math.min(maxLeft, initialPosition + deltaX),
|
||||
);
|
||||
setLeftHandle(nextLeftHandle);
|
||||
return;
|
||||
}
|
||||
|
||||
const minRight = Math.min(
|
||||
widthRef.current,
|
||||
leftHandlePositionRef.current + 60,
|
||||
);
|
||||
const nextRightHandle = Math.max(
|
||||
minRight,
|
||||
Math.min(widthRef.current, initialPosition + deltaX),
|
||||
);
|
||||
setRightHandle(nextRightHandle);
|
||||
};
|
||||
|
||||
const handlePointerEnd = (event: PointerEvent) => {
|
||||
const { pointerId } = dragRef.current;
|
||||
if (pointerId !== null && event.pointerId !== pointerId) return;
|
||||
|
||||
dragRef.current.isDragging = false;
|
||||
dragRef.current.side = null;
|
||||
dragRef.current.pointerId = null;
|
||||
};
|
||||
|
||||
window.addEventListener("pointermove", handlePointerMove);
|
||||
window.addEventListener("pointerup", handlePointerEnd);
|
||||
window.addEventListener("pointercancel", handlePointerEnd);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("pointermove", handlePointerMove);
|
||||
window.removeEventListener("pointerup", handlePointerEnd);
|
||||
window.removeEventListener("pointercancel", handlePointerEnd);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const leftGradientPercent = width > 0 ? (leftHandle / (width - 10)) * 100 : 0;
|
||||
const rightGradientPercent = width > 0 ? (rightHandle / (width + 10)) * 100 : 0;
|
||||
const rightGradientPercent =
|
||||
width > 0 ? (rightHandle / (width + 10)) * 100 : 0;
|
||||
|
||||
return (
|
||||
<div className="leading-16 -z-10 flex justify-center gap-4">
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="relative -z-10 mt-0.5 -rotate-[2.76deg]"
|
||||
>
|
||||
<div className="absolute inset-0 flex h-full w-full justify-between rounded-2xl border border-yellow-500">
|
||||
<div className="leading-16 flex justify-center gap-4">
|
||||
<div ref={containerRef} className="relative mt-0.5 -rotate-[2.76deg]">
|
||||
<div className="absolute inset-0 z-10 flex h-full w-full justify-between rounded-2xl border border-yellow-500">
|
||||
<div
|
||||
ref={leftHandleRef}
|
||||
className="bg-background absolute left-0 flex h-full w-7 select-none items-center justify-center rounded-full border border-yellow-500 cursor-grab hover:scale-105 transition-transform"
|
||||
className="bg-background absolute left-0 z-20 flex h-full w-7 cursor-ew-resize touch-none select-none items-center justify-center rounded-full border border-yellow-500"
|
||||
style={{
|
||||
transform: `translateX(${leftHandle}px)`,
|
||||
translate: `${leftHandle}px 0`,
|
||||
}}
|
||||
onPointerDown={(event) => {
|
||||
event.preventDefault();
|
||||
leftHandleRef.current?.setPointerCapture(event.pointerId);
|
||||
dragRef.current.isDragging = true;
|
||||
dragRef.current.side = "left";
|
||||
dragRef.current.pointerId = event.pointerId;
|
||||
dragRef.current.startX = event.clientX;
|
||||
dragRef.current.initialPosition = leftHandlePositionRef.current;
|
||||
}}
|
||||
>
|
||||
<div className="h-8 w-2 rounded-full bg-yellow-500" />
|
||||
@@ -117,9 +135,18 @@ export function Handlebars({ children }: HandlebarsProps) {
|
||||
|
||||
<div
|
||||
ref={rightHandleRef}
|
||||
className="bg-background absolute -left-[30px] flex h-full w-7 select-none items-center justify-center rounded-full border border-yellow-500 cursor-grab hover:scale-105 transition-transform]"
|
||||
className="bg-background absolute -left-[30px] z-20 flex h-full w-7 cursor-ew-resize touch-none select-none items-center justify-center rounded-full border border-yellow-500"
|
||||
style={{
|
||||
transform: `translateX(${rightHandle}px)`,
|
||||
translate: `${rightHandle}px 0`,
|
||||
}}
|
||||
onPointerDown={(event) => {
|
||||
event.preventDefault();
|
||||
rightHandleRef.current?.setPointerCapture(event.pointerId);
|
||||
dragRef.current.isDragging = true;
|
||||
dragRef.current.side = "right";
|
||||
dragRef.current.pointerId = event.pointerId;
|
||||
dragRef.current.startX = event.clientX;
|
||||
dragRef.current.initialPosition = rightHandlePositionRef.current;
|
||||
}}
|
||||
>
|
||||
<div className="h-8 w-2 rounded-full bg-yellow-500" />
|
||||
@@ -127,7 +154,7 @@ export function Handlebars({ children }: HandlebarsProps) {
|
||||
</div>
|
||||
|
||||
<span
|
||||
className="relative inline-flex h-full w-full items-center justify-center rounded-2xl px-9 will-change-auto"
|
||||
className="relative z-0 inline-flex h-full w-full items-center justify-center rounded-2xl px-9 will-change-auto"
|
||||
style={{
|
||||
mask: `linear-gradient(90deg,
|
||||
rgba(255, 255, 255, 0) 0%,
|
||||
|
||||
Reference in New Issue
Block a user