From 15be7daab1d6304c34dd70bb31f9913d84a48662 Mon Sep 17 00:00:00 2001 From: wass Date: Sat, 8 Jun 2024 15:28:44 +0200 Subject: [PATCH] fallback style focus for foreign objects --- src/components/panzoom/lib_panzoommodal.js | 14 +++++++ src/components/panzoom/lib_svg_filters.js | 2 +- src/components/panzoom/lib_svg_utils.js | 49 ++++++++++++++-------- src/components/panzoom/panzoommodal.astro | 3 +- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/components/panzoom/lib_panzoommodal.js b/src/components/panzoom/lib_panzoommodal.js index d79a3f1..afbfccf 100644 --- a/src/components/panzoom/lib_panzoommodal.js +++ b/src/components/panzoom/lib_panzoommodal.js @@ -7,6 +7,19 @@ const zoomOptions = { //autocenter:true } +function addFocusStyles(shadowRoot) { + if (!shadowRoot.getElementById('glowStyles')) { + const style = document.createElement('style'); + style.id = 'focusStyles'; + style.textContent = ` + .focus-effect { + font-weight: bold; + } + `; + shadowRoot.appendChild(style); + } +} + async function appendShadowSVG(center,svg){ //cannot detatch a shadow root, so check existing before creation let shadowRoot = center.shadowRoot @@ -15,6 +28,7 @@ async function appendShadowSVG(center,svg){ } const div = document.createElement("div")//needed for the panzoom as it takes the parent shadowRoot.appendChild(div) + addFocusStyles(shadowRoot) let new_svg const clone_fails_with_SVGjs = true if(clone_fails_with_SVGjs){ diff --git a/src/components/panzoom/lib_svg_filters.js b/src/components/panzoom/lib_svg_filters.js index ac813a4..717a4ba 100644 --- a/src/components/panzoom/lib_svg_filters.js +++ b/src/components/panzoom/lib_svg_filters.js @@ -109,7 +109,6 @@ function startAnimation(svg,element,filter){ anim.beginElement(); if(!(anim.getAttribute("repeatDur") == "indefinite")){ const duration_ms = dur_to_ms(anim.getAttribute("dur")); - console.log(`will detach after ${duration_ms} ms`); setTimeout(()=>{ detachFilter(element,filter); },duration_ms); @@ -118,6 +117,7 @@ function startAnimation(svg,element,filter){ function glow(svg, element, color, dur = 500){ const glow = createGlowFilter(svg,color,dur) + console.log(`playing glow animation for ${dur} ms`); startAnimation(svg,element,glow) setTimeout(()=>removeFilter(svg,glow),dur+100) } diff --git a/src/components/panzoom/lib_svg_utils.js b/src/components/panzoom/lib_svg_utils.js index 0fdab5d..2f569ad 100644 --- a/src/components/panzoom/lib_svg_utils.js +++ b/src/components/panzoom/lib_svg_utils.js @@ -63,25 +63,40 @@ async function svg_text_focus(modal_content,svg,text,pzref){ let text_hits = text_array.filter(obj => obj.node.innerHTML == text); if(text_hits.length > 0){ let targetText = text_hits[0] - if(typeof targetText.bbox === "function"){ - const bbox = targetText.bbox(); - let box_center_x = bbox.x + bbox.width / 2; - let box_center_y = bbox.y + bbox.height / 2; - const svg_cx = svg.getAttribute("width").replace(/px$/, '')/2 - const svg_cy = svg.getAttribute("height").replace(/px$/, '')/2 - //console.log(`svg center (${svg_cx},${svg_cy})`) - const shift_x = svg_cx - box_center_x - const shift_y = svg_cy - box_center_y - //console.log(`moveTo (${shift_x},${shift_y})`) - setTimeout(()=>{pzref.smoothMoveTo(shift_x, shift_y)}, 400) - setTimeout(()=>{pzref.smoothZoom(svg_cx, svg_cy, 1.4)}, 800) - setTimeout(()=>{glow(svg, targetText.node, '#0f0');},1500) + let bbox + if(targetText.node.namespaceURI == "http://www.w3.org/2000/svg"){ + bbox = targetText.bbox() + }else if(targetText.node.namespaceURI == "http://www.w3.org/1999/xhtml"){ + const node_bbox = targetText.node.getBoundingClientRect() + // Adjust coordinates to SVG coordinate space + let svgRect = svg.getBoundingClientRect(); + bbox = { + x: node_bbox.left - svgRect.left, + y: node_bbox.top - svgRect.top, + width: node_bbox.width, + height: node_bbox.height + }; + }else{ + console.warn(`not handled namespaceURI ${targetText.node.namespaceURI}`) + return } - else{ - console.warn(`targetText not an SVG element has no bbox function`) - console.log(targetText) + console.log(bbox) + let box_center_x = bbox.x + bbox.width / 2; + let box_center_y = bbox.y + bbox.height / 2; + const svg_cx = svg.getAttribute("width").replace(/px$/, '')/2 + const svg_cy = svg.getAttribute("height").replace(/px$/, '')/2 + console.log(`svg center (${svg_cx},${svg_cy})`) + const shift_x = svg_cx - box_center_x + const shift_y = svg_cy - box_center_y + console.log(`moveTo (${shift_x},${shift_y})`) + setTimeout(()=>{pzref.smoothMoveTo(shift_x, shift_y)}, 400) + setTimeout(()=>{pzref.smoothZoom(svg_cx, svg_cy, 1.4)}, 800) + if(targetText.node.namespaceURI == "http://www.w3.org/2000/svg"){ + setTimeout(()=>{glow(svg, targetText.node, '#0f0');},1500) + }else{ + setTimeout(()=>{targetText.node.classList.add("focus-effect");},1500) + setTimeout(()=>{targetText.node.classList.remove("focus-effect");},2000) } - } } diff --git a/src/components/panzoom/panzoommodal.astro b/src/components/panzoom/panzoommodal.astro index 6a4a911..fa18935 100644 --- a/src/components/panzoom/panzoommodal.astro +++ b/src/components/panzoom/panzoommodal.astro @@ -80,8 +80,7 @@ const {url} = Astro.props as Props; cursor: pointer; background:#ddd; } -.modal-header:hover > span{ +.modal-header:hover > span.close-x{ color: #000; - }