From 8517102b631d35ba58afc8ea227b9c4f0f71a3fd Mon Sep 17 00:00:00 2001 From: Cristian Felipe Cruz Buitron Date: Sun, 6 Sep 2026 19:18:11 +0000 Subject: [PATCH] =?UTF-8?q?feat(product-gallery):=20zoom=20autom=C3=A1tico?= =?UTF-8?q?=20de=20la=20imagen=20al=20pasar=20el=20cursor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Antes el único zoom era el modal interactivo (click -> Dialog con scale/ drag). Ahora la imagen principal también hace zoom estilo lupa (2.2x) que sigue la posición del cursor con mousemove/transform-origin, sin tocar el modal existente (sigue abriéndose igual con el click). Solo mouse -- mousemove no dispara de forma continua en touch, así que en mobile simplemente no aparece el efecto, sin romper nada ahí. Verificado: tsc --noEmit limpio, página de producto renderiza 200 con datos mock y el nuevo markup presente. No se pudo verificar visualmente el hover en un navegador real (sin chromium-cli ni claude-in-chrome disponibles en este shell headless). Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01THZFwPzrwv6VAbuwmaf5vR --- .../components/product/product-gallery.tsx | 39 +++++++++++++++++-- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/workloads/ecommerce/components/product/product-gallery.tsx b/workloads/ecommerce/components/product/product-gallery.tsx index 83843e0..92d059f 100644 --- a/workloads/ecommerce/components/product/product-gallery.tsx +++ b/workloads/ecommerce/components/product/product-gallery.tsx @@ -2,19 +2,36 @@ import Image from "next/image"; import { Maximize2, Minus, Plus, RotateCcw, ZoomIn } from "lucide-react"; -import { PointerEvent, WheelEvent, useRef, useState } from "react"; +import { MouseEvent, PointerEvent, WheelEvent, useRef, useState } from "react"; import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"; interface Offset { x: number; y: number } interface DragState { pointerId: number; startX: number; startY: number; originX: number; originY: number } +interface HoverZoomOrigin { x: number; y: number } + +// Zoom automatico al pasar el cursor (estilo lupa clasico de e-commerce) +// sobre la imagen principal -- solo mouse (mousemove no dispara de forma +// continua en touch, asi que en mobile simplemente no aparece el efecto, +// sin romper nada). Independiente del zoom interactivo del modal +// (click -> Dialog con scale/drag), que sigue igual. +const HOVER_ZOOM_SCALE = 2.2; export function ProductGallery({ images, name }: { images: string[]; name: string }) { const [selected, setSelected] = useState(images[0] ?? ""); const [open, setOpen] = useState(false); const [scale, setScale] = useState(1); const [offset, setOffset] = useState({ x: 0, y: 0 }); + const [hoverZoom, setHoverZoom] = useState(null); const drag = useRef(null); + const trackHoverZoom = (event: MouseEvent) => { + const rect = event.currentTarget.getBoundingClientRect(); + setHoverZoom({ + x: ((event.clientX - rect.left) / rect.width) * 100, + y: ((event.clientY - rect.top) / rect.height) * 100, + }); + }; + const applyScale = (next: number) => { const value = Math.min(3, Math.max(1, Number(next.toFixed(2)))); setScale(value); @@ -44,8 +61,24 @@ export function ProductGallery({ images, name }: { images: string[]; name: strin -