diff --git a/dist/iwmlib.js b/dist/iwmlib.js index 3cd4f82..f4d2426 100644 --- a/dist/iwmlib.js +++ b/dist/iwmlib.js @@ -2480,6 +2480,8 @@ onMouseWheel(event) { if (this.capture(event) && this.target.onMouseWheel) { this.target.onMouseWheel(event); + } else { + //console.warn('Target has no onMouseWheel callback') } } @@ -2683,6 +2685,8 @@ } if (this.target.onMouseWheel) { this.target.onMouseWheel(event); + } else { + //console.warn('Target has no onMouseWheel callback', this.target) } } } @@ -7602,6 +7606,8 @@ /** To avoid problems with relative URL paths, we use inline data URI to load svg icons. */ + const enableNearestNeighborTaps = false; + /** * A class that collects static methods to maintain the states and parts of * EyeVisit like cards. @@ -8225,6 +8231,23 @@ return requestedSame } + static _calculateCenterRelativeTo(target, image) { + console.log("_calculateCenterRelativeTo", target, image); + let bbox = image.getBBox(); + let width = bbox.width; + let height = bbox.height; + let cx = target.getAttribute('cx'); + let cy = target.getAttribute('cy'); + let r = target.getAttribute('r'); + let radius = r.endsWith('%') ? (parseFloat(r) / 100) * width : parseFloat(r); + + + let x = cx.endsWith('%') ? (parseFloat(cx) / 100) * width : cx; + let y = cy.endsWith('%') ? (parseFloat(cy) / 100) * height : cx; + console.log({x, y, width, height , radius}); + return { x, y } + } + /** * Opens a popup for a highlight. Typically used as a onlick handler of a link. * @@ -8233,14 +8256,16 @@ * @returns {bool} false - Returns false to prevent default click action * @memberof Card */ - static loadHighlightPopup(event) { - if (this.debug) console.log('Load Highlight Popup: ', event); - let node; - if (event.firstTarget) { - node = event.firstTarget; - } else { - node = event.target; + static loadHighlightPopup(event, node=null) { + if (this.debug) console.log('Card.loadHighlightPopup', event, node); + if (node == null) { + if (event.firstTarget) { + node = event.firstTarget; + } else { + node = event.target; + } } + let context = this.getContext(node); event.stopPropagation(); @@ -8259,27 +8284,29 @@ animation: Card.highlightAnimation, onExpanded: () => { // We assume it's always a circle. This may break, when other svg shapes are used. - let x = node.getAttribute('cx'); - let y = node.getAttribute('cy'); - let position = { x, y }; - - let radius = parseFloat(node.getAttribute('r')); + + let svgRoot = node.closest('svg'); + let image = svgRoot.querySelector('image'); + let position = Card._calculateCenterRelativeTo(node, image); + /* As the popup is appended directly to the card. We have to transform the location from the subcard-/svg-space to the card space. */ - let svgRoot = node.closest('svg'); + // let svgRoot = node.closest('svg') let svgPoint = svgRoot.createSVGPoint(); svgPoint.x = position.x; - svgPoint.y = position.y - radius; + svgPoint.y = position.y; let matrix = node.getCTM(); let point = svgPoint.matrixTransform(matrix); - let global = Points.fromNodeToPage(node.closest('div'), point); + let closestDiv = node.closest('div'); + console.log("closestDiv", closestDiv, point); + let global = Points.fromNodeToPage(closestDiv, point); let local = Points.fromPageToNode(context, global); let overlay = document.createElement('div'); @@ -8290,7 +8317,7 @@ // we could load the data while the circle is animating. // but for simplicity it's just done here for now. // TODO: Adjust to load while animating (Problem: Unload when cancelled). - console.log(src); + console.log("loadHighlightPopup", src, position, local); this._loadPopupContent(src) .then(content => { this._openPopup(context, src, local, content, { @@ -8985,6 +9012,16 @@ if (this.dynamicHeight) { article.appendChild(iconClone); } + + if (enableNearestNeighborTaps) { + //look for nearby popups on tap + InteractionMapper.on('tap', indexbox, () => { + console.log('Tap handler called', editable); + if (!editable) { + this.findNearbyPopups(event, card); + } + }); + } // Use the 'tap' event for closing. // Otherwise the subcard cannot be closed, // when another subcard is touched. diff --git a/dist/iwmlib.pixi.js b/dist/iwmlib.pixi.js index cf723d0..787e827 100644 --- a/dist/iwmlib.pixi.js +++ b/dist/iwmlib.pixi.js @@ -6011,6 +6011,8 @@ onMouseWheel(event) { if (this.capture(event) && this.target.onMouseWheel) { this.target.onMouseWheel(event); + } else { + //console.warn('Target has no onMouseWheel callback') } } @@ -6214,6 +6216,8 @@ } if (this.target.onMouseWheel) { this.target.onMouseWheel(event); + } else { + //console.warn('Target has no onMouseWheel callback', this.target) } } } diff --git a/lib/card/card.js b/lib/card/card.js index 30a7b4c..0d8f7ac 100644 --- a/lib/card/card.js +++ b/lib/card/card.js @@ -645,6 +645,23 @@ export default class Card { return requestedSame } + static _calculateCenterRelativeTo(target, image) { + console.log("_calculateCenterRelativeTo", target, image) + let bbox = image.getBBox() + let width = bbox.width + let height = bbox.height + let cx = target.getAttribute('cx') + let cy = target.getAttribute('cy') + let r = target.getAttribute('r') + let radius = r.endsWith('%') ? (parseFloat(r) / 100) * width : parseFloat(r) + + + let x = cx.endsWith('%') ? (parseFloat(cx) / 100) * width : cx + let y = cy.endsWith('%') ? (parseFloat(cy) / 100) * height : cx + console.log({x, y, width, height , radius}) + return { x, y } + } + /** * Opens a popup for a highlight. Typically used as a onlick handler of a link. * @@ -653,14 +670,16 @@ export default class Card { * @returns {bool} false - Returns false to prevent default click action * @memberof Card */ - static loadHighlightPopup(event) { - if (this.debug) console.log('Load Highlight Popup: ', event) - let node - if (event.firstTarget) { - node = event.firstTarget - } else { - node = event.target + static loadHighlightPopup(event, node=null) { + if (this.debug) console.log('Card.loadHighlightPopup', event, node) + if (node == null) { + if (event.firstTarget) { + node = event.firstTarget + } else { + node = event.target + } } + let context = this.getContext(node) event.stopPropagation() @@ -679,27 +698,29 @@ export default class Card { animation: Card.highlightAnimation, onExpanded: () => { // We assume it's always a circle. This may break, when other svg shapes are used. - let x = node.getAttribute('cx') - let y = node.getAttribute('cy') - let position = { x, y } - - let radius = parseFloat(node.getAttribute('r')) + + let svgRoot = node.closest('svg') + let image = svgRoot.querySelector('image') + let position = Card._calculateCenterRelativeTo(node, image) + /* As the popup is appended directly to the card. We have to transform the location from the subcard-/svg-space to the card space. */ - let svgRoot = node.closest('svg') + // let svgRoot = node.closest('svg') let svgPoint = svgRoot.createSVGPoint() svgPoint.x = position.x - svgPoint.y = position.y - radius + svgPoint.y = position.y let matrix = node.getCTM() let point = svgPoint.matrixTransform(matrix) - let global = Points.fromNodeToPage(node.closest('div'), point) + let closestDiv = node.closest('div') + console.log("closestDiv", closestDiv, point) + let global = Points.fromNodeToPage(closestDiv, point) let local = Points.fromPageToNode(context, global) let overlay = document.createElement('div') @@ -710,7 +731,7 @@ export default class Card { // we could load the data while the circle is animating. // but for simplicity it's just done here for now. // TODO: Adjust to load while animating (Problem: Unload when cancelled). - console.log(src) + console.log("loadHighlightPopup", src, position, local) this._loadPopupContent(src) .then(content => { this._openPopup(context, src, local, content, { diff --git a/lib/card/index.html b/lib/card/index.html index 5e4e7e4..0cafbe1 100644 --- a/lib/card/index.html +++ b/lib/card/index.html @@ -71,7 +71,7 @@ - @@ -96,8 +96,8 @@ const wrapper2 = new CardWrapper(demoCardWithSelector) wrapper2.handleClicksAsTaps() - wrapper2.onTap('circle', event => { - Card.loadHighlightPopup(event) + wrapper2.onTap('circle', (event, node) => { + Card.loadHighlightPopup(event, node) }) wrapper2.onTap('a', event => {