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)
imagem.jpg
cursor: zoom-in
Modal aberto (normal)
imagem.jpg
cursor: zoom-in
Zoom 2x (após click)
imagem.jpg (2x)
cursor: zoom-out
Rotacionado 90°
90°
rotation: 90deg
Real src/views/chat-attendance/Index.vue:628
<!-- 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 zoomApplied.
Na entrada: transform-origin = ponto do click.
Na saída: volta para center center.
Scale: 2x.
Pan (mousemove)
Durante zoom: atualiza --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 (@click.self)
• Botão X (XIcon)
• Tecla Escape (keydown listener)
Real src/components/ExpandableImage.vue
<!-- 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

NomeTipoDefaultObrig.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

EventoPayloadDescriçã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 / ClasseValor
z-index999999 (maior que qualquer overlay Vuesax)
Overlay backgroundrgba(0, 0, 0, 0.7)
Image max width/height100vh × 100vh
Image border-radius10px
Zoom scale2x
Rotation transitiontransform 0.3s ease
--offsetX / --offsetYCSS custom props para zoom-origin dinâmico
.zoomedscale(2), cursor zoom-out
Cursor normalzoom-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)