compact resize ratio picker
This commit is contained in:
parent
6c1583a2fa
commit
f32146b3f3
@ -5,7 +5,7 @@ import { createPortal } from "react-dom";
|
||||
import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useTheme } from "next-themes";
|
||||
import { X, Check, Undo, Trash2, Scissors, Sparkles, Download, Expand, Move, Maximize2, ZoomIn, ZoomOut, Loader2, Move3D, Layers, Upload as UploadIcon, Image as ImageIcon, Droplet, Redo, MousePointer2 } from "lucide-react";
|
||||
import { X, Check, Undo, Trash2, Scissors, Sparkles, Download, Expand, Move, Maximize2, ZoomIn, ZoomOut, Loader2, Move3D, Layers, Upload as UploadIcon, Image as ImageIcon, Droplet, Redo, MousePointer2, ChevronDown } from "lucide-react";
|
||||
import { Button } from "./ui/button";
|
||||
import { Input } from "./ui/input";
|
||||
import { Slider } from "./ui/slider";
|
||||
@ -20,6 +20,7 @@ import {
|
||||
DialogDescription,
|
||||
} from "@/components/ui/dialog";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
@ -327,6 +328,7 @@ export function ImageAnnotator({
|
||||
const [dragStart, setDragStart] = useState<{ x: number; y: number } | null>(null);
|
||||
const [selectedAspectRatio, setSelectedAspectRatio] = useState<string | null>(null); // 选中的比例,null表示自定义
|
||||
const [isResizing, setIsResizing] = useState(false); // 尺寸调整处理中状态
|
||||
const [resizeRatioPickerOpen, setResizeRatioPickerOpen] = useState(false);
|
||||
const resizeCanvasRef = useRef<HTMLCanvasElement>(null);
|
||||
const resizeContainerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@ -400,6 +402,10 @@ export function ImageAnnotator({
|
||||
}
|
||||
};
|
||||
|
||||
const currentAspectRatioLabel =
|
||||
aspectRatios.find((ratio) => ratio.value === selectedAspectRatio)?.label ||
|
||||
(selectedAspectRatio ? selectedAspectRatio : "自定义");
|
||||
|
||||
const handleResizeQuickPresetSelect = (
|
||||
preset: (typeof resizeQuickPresets)[number]
|
||||
) => {
|
||||
@ -1737,26 +1743,48 @@ export function ImageAnnotator({
|
||||
<div className="absolute bottom-8 left-1/2 z-20 w-[min(92vw,1120px)] -translate-x-1/2 pointer-events-none">
|
||||
<div className="pointer-events-auto flex items-center justify-between gap-3 overflow-x-auto rounded-[28px] border border-border/50 bg-background/95 px-3 py-2 shadow-2xl backdrop-blur-xl scrollbar-hide">
|
||||
<div className="flex min-w-max items-center gap-2">
|
||||
<div className="flex items-center gap-1 rounded-[22px] bg-muted/35 px-1 py-1">
|
||||
{aspectRatios.map((ratio) => (
|
||||
<Popover open={resizeRatioPickerOpen} onOpenChange={setResizeRatioPickerOpen}>
|
||||
<PopoverTrigger asChild>
|
||||
<Button
|
||||
key={ratio.value}
|
||||
variant={selectedAspectRatio === ratio.value ? "secondary" : "ghost"}
|
||||
size="sm"
|
||||
onClick={() =>
|
||||
handleAspectRatioSelect(
|
||||
ratio.value === selectedAspectRatio ? null : ratio.value
|
||||
)
|
||||
}
|
||||
className={cn(
|
||||
"h-8 rounded-[18px] px-3 text-xs font-medium",
|
||||
selectedAspectRatio === ratio.value && "shadow-sm"
|
||||
)}
|
||||
variant="ghost"
|
||||
className="h-10 shrink-0 rounded-[20px] bg-muted/35 px-4 text-xs font-medium text-foreground hover:bg-muted/45"
|
||||
>
|
||||
{ratio.label}
|
||||
比例
|
||||
<span className="ml-2 text-foreground/80">{currentAspectRatioLabel}</span>
|
||||
<ChevronDown className="ml-2 h-4 w-4 text-muted-foreground" />
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
align="start"
|
||||
side="top"
|
||||
className="w-[320px] rounded-[22px] border-border/60 bg-background/96 p-3 backdrop-blur-xl"
|
||||
>
|
||||
<div className="mb-2 text-xs font-medium text-muted-foreground">
|
||||
选择画布比例
|
||||
</div>
|
||||
<div className="grid grid-cols-4 gap-2">
|
||||
{aspectRatios.map((ratio) => (
|
||||
<Button
|
||||
key={ratio.value}
|
||||
variant={selectedAspectRatio === ratio.value ? "secondary" : "ghost"}
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
handleAspectRatioSelect(
|
||||
ratio.value === selectedAspectRatio ? null : ratio.value
|
||||
);
|
||||
setResizeRatioPickerOpen(false);
|
||||
}}
|
||||
className={cn(
|
||||
"h-9 rounded-[16px] px-3 text-xs font-medium",
|
||||
selectedAspectRatio === ratio.value && "shadow-sm"
|
||||
)}
|
||||
>
|
||||
{ratio.label}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
<div className="h-7 w-px shrink-0 bg-border/60" />
|
||||
<div className="flex items-center gap-2 rounded-[20px] bg-muted/30 px-2 py-1">
|
||||
<Input
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user