ExpandableImage
src/components/ExpandableImage.vue
Overlay
Medium
2 usos
Viewer fullscreen de imagem com zoom 2x via click, pan/tracking do mouse durante zoom, e rotação em 90°. Modal fixo z-index: 999999 com overlay escuro. Fecha ao clicar no overlay ou pressionar Escape. Usado exclusivamente no chat de atendimento para ampliar imagens recebidas.
Viewer Fullscreen — Estados
Todos os estados do viewer: thumbnail com hover, modal aberto normal, modal com zoom 2x, e modal com imagem rotacionada 90°. O pai controla active e passa a src da imagem.
Thumbnail (hover)
cursor: zoom-in
imagem.jpg
Modal aberto (normal)
cursor: zoom-in
imagem.jpg
Zoom 2x (após click)
cursor: zoom-out
Rotacionado 90°
rotation: 90deg
90°
<!-- No template: -->
<expandable-image
:active="openExpandImagePopUp"
:src="expandImageSrc"
@closeImage="openExpandImagePopUp = false"
/>
<!-- No data(): -->
<!-- openExpandImagePopUp: false, -->
<!-- expandImageSrc: '', -->
<!-- No methods: -->
<!-- expandImagePopup(imageSrc) { -->
<!-- this.openExpandImagePopUp = true -->
<!-- this.expandImageSrc = imageSrc -->
<!-- } -->
Interações — Zoom e Pan
O zoom preserva o ponto de clique como origem do transform via CSS custom properties --offsetX e --offsetY. Durante o zoom, mover o mouse faz pan em tempo real. A rotação ajusta o mapeamento das coordenadas do mouse para compensar a orientação.
Zoom (click)
Click na imagem: toggle
Na entrada:
Na saída: volta para
Scale: 2x.
zoomApplied.Na entrada:
transform-origin = ponto do click.Na saída: volta para
center center.Scale: 2x.
Pan (mousemove)
Durante zoom: atualiza
Usa
--offsetX / --offsetY em tempo real.Usa
getBoundingClientRect() para % relativo ao elemento.
Rotação (botão)
Botão RotateCwIcon: acumula +90° a cada click (0 → 90 → 180 → 270 → 0).
setAxios() remapeia coordenadas do mouse compensando a rotação atual.
Fechar
3 formas:
• Click no overlay (
• Botão X (XIcon)
• Tecla
• Click no overlay (
@click.self)• Botão X (XIcon)
• Tecla
Escape (keydown listener)
<!-- active: Boolean obrigatório — v-if do modal. -->
<!-- src: String obrigatório — URL da imagem. -->
<!-- @closeImage: emitido ao fechar (click overlay, botão X, Escape). -->
<expandable-image
:active="showImageModal"
:src="selectedImageUrl"
@closeImage="showImageModal = false"
/>
API
Props
| Nome | Tipo | Default | Obrig. | Descrição |
|---|---|---|---|---|
active |
Boolean | — | Sim | Controla visibilidade do modal (v-if). O pai gerencia o estado de abertura/fechamento. |
src |
String | — | Sim | URL da imagem a ser exibida no viewer. |
Eventos
| Evento | Payload | Descrição |
|---|---|---|
@closeImage |
— | Emitido ao fechar o modal (click no overlay, botão X, ou tecla Escape). O pai deve setar active=false. |
CSS — Valores internos
| Token / Classe | Valor |
|---|---|
z-index | 999999 (maior que qualquer overlay Vuesax) |
| Overlay background | rgba(0, 0, 0, 0.7) |
| Image max width/height | 100vh × 100vh |
| Image border-radius | 10px |
| Zoom scale | 2x |
| Rotation transition | transform 0.3s ease |
--offsetX / --offsetY | CSS custom props para zoom-origin dinâmico |
| .zoomed | scale(2), cursor zoom-out |
| Cursor normal | zoom-in |
Dependências
feather-icon: RotateCwIcon, XIcon
Onde é usado (2 usos)
src/views/chat-attendance/Index.vue:628
src/views/chat-attendance/NewIndex.vue (padrão idêntico)