From 1dbdcfdb58cce1df3b9de2da0e604da1ef04eed6 Mon Sep 17 00:00:00 2001 From: VPS 4 Deploy Agent Date: Mon, 1 Jun 2026 01:30:18 +0200 Subject: [PATCH] =?UTF-8?q?feat(clipboard):=20adiciona=20funcionalidade=20?= =?UTF-8?q?de=20copiar=20imagem=20transformada=20para=20a=20=C3=A1rea=20de?= =?UTF-8?q?=20transfer=C3=AAncia?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pages/ImageDetailsPage.jsx | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/dental-server/dental-client/src/pages/ImageDetailsPage.jsx b/dental-server/dental-client/src/pages/ImageDetailsPage.jsx index c11aeb8..5ca7e5e 100644 --- a/dental-server/dental-client/src/pages/ImageDetailsPage.jsx +++ b/dental-server/dental-client/src/pages/ImageDetailsPage.jsx @@ -246,6 +246,49 @@ export default function ImageDetailsPage() { img.src = url; }; + const copyImageToClipboard = () => { + const url = imageUrl; + const img = new Image(); + img.crossOrigin = 'anonymous'; + img.onload = () => { + try { + const w = img.naturalWidth, h = img.naturalHeight; + const deg = totalRotation; + const fH = baseFlipH; + const fV = baseFlipV; + const rad = (deg * Math.PI) / 180; + const cos = Math.abs(Math.cos(rad)), sin = Math.abs(Math.sin(rad)); + const cw = Math.round(w * cos + h * sin); + const ch = Math.round(w * sin + h * cos); + const canvas = document.createElement('canvas'); + canvas.width = cw; canvas.height = ch; + const ctx = canvas.getContext('2d'); + ctx.translate(cw / 2, ch / 2); + ctx.scale(fH ? -1 : 1, fV ? -1 : 1); + ctx.rotate(rad); + ctx.drawImage(img, -w / 2, -h / 2); + canvas.toBlob(async (blob) => { + try { + await navigator.clipboard.write([ + new ClipboardItem({ + 'image/png': blob + }) + ]); + showToast('Imagem copiada para a área de transferência!', 'success'); + } catch (err) { + showToast('Erro ao copiar imagem para clipboard.', 'error'); + console.error(err); + } + }, 'image/png'); + } catch (e) { + showToast('Erro ao processar imagem para cópia.', 'error'); + console.error(e); + } + }; + img.onerror = () => showToast('Erro ao carregar imagem para cópia.', 'error'); + img.src = url; + }; + const markGtoSent = async (gtoId, sent) => { try { await api.post(`/gtos/${gtoId}/sent`, { sent }); @@ -502,6 +545,14 @@ export default function ImageDetailsPage() { > {saving ? '⏳ Salvando Alterações...' : '💾 Salvar'} +