skip to Main Content

First of

I work on a html/js/css module injected in third party page which is autoscaled using CSS zoom. I cannot remove the zoom property from the parent element as it is automatically added using some polling mechanism. I have NO access to the code and the customer will NOT change it.

Problem

My own embedded code is basically another third party library, lets call it THS. The THS library does make use of event.pageX and event.pageY values in its event handlers. Since the whole code is wrapped in an element using zoom the event coordinates are not correct anymore. So I have clicks and hovers on wrong positions.

Showcase

I can only edit html code within the div#custom-container element. The div#main-container is the element which gets zoom automatically applied.

const mainContainer = document.getElementById('main-container')

// enable / disable zoom
const zoomCb = document.getElementById('zoom-enabled')
zoomCb.addEventListener('click', () => {
    mainContainer.style.zoom = zoomCb.checked ? '50%' : ''
})

const workspace = document.getElementById('custom-container')

// Sample pageX and pageY are wrong when using zoom
workspace.addEventListener('click', e => {
    const point = document.getElementById('point')
    point.style.left = e.pageX + 'px'
    point.style.top = e.pageY + 'px'
})
#point {
    position: absolute;
    background-color: red;
    height: 25px;
    width: 25px;
}

#main-container {
    width: 100%;
    height: 300px;
}

#custom-container {
    width: 100%;
    height: 100%;
}


   
 <p>Click somewhere to move the red square</p>
  <label>
    enable zoom
    <input type="checkbox" id="zoom-enabled">
</label>


<div id="main-container">
    <div id="custom-container">
        <div id="point"></div>
    </div>

</div>

When zoom is disabled the #point div element is moved to correct place. With enabled zoom it is not.. I read in the documentation that the boundaries of the elements is changed when using css zoom and that’s why these coordinates are wrong, but again, I cannot remove the zoom property.

What I tried / found

CSS transform can replace zoom fully wihtout changing element boundaries. So click events provide propper coordinates.

So I tried to reset the zoom in the root of my custom module and apply transform accordingly. But Setting zoom: reset has no effect on my elements, the reset value is not regonised in most recent versions of firefox/chrome/edge

I have no clue what I could try instead of rewriting like all the THS modules code but that will cost me weeks plus bringing the changes to the third party hoster etc.

last

  • If anything is unclear, let me know.
  • The code snippet showcases my problem and is only sandbox reproduction.
  • Again, zoom is unavoidable in my scenario. Answers pointing out I should NOT use zoom do not help at all.
  • Any other ideas are appreciated.

TY for reading, I value your time!>

Edit1

The answer of @Tom4nt does not help me since The code which reads event.pageY resp. event.pageY is out of my reach.

2

Answers


  1. Chosen as BEST ANSWER

    Thanks to a comment of @Cbroe it is possible to apply the reverse zoom to my custom container to mitigate the zoom effect.

    //calculate reverse zoom factor of css zoom rule value
    function reverseZoom(factorStr) {
        const factor = parseFloat(factorStr)
    
        // Allow units in factorStr like percentage
        const unit = factorStr.replace((''+factor), '')
        const reverse = 100 / factor
        return (100 * reverse) + unit
    } 
    
    const mainContainer = document.getElementById('main-container')
    const workspace = document.getElementById('custom-container')
    
    // enable / disable zoom
    const zoomCb = document.getElementById('zoom-enabled')
    zoomCb.addEventListener('click', () => {
    
        var zoomFactor = ''
        var reverseFactor = ''
    
        if(zoomCb.checked) {
            zoomFactor = '50%'
            reverseFactor = reverseZoom(zoomFactor)
        }
    
        mainContainer.style.zoom = zoomFactor
        workspace.style.zoom = reverseFactor
    })
    
    
    // Sample pageX and pageY are wrong when using zoom
    workspace.addEventListener('click', e => {
        const point = document.getElementById('point')
        point.style.left = e.pageX + 'px'
        point.style.top = e.pageY + 'px'
    })
    #point {
        position: absolute;
        background-color: red;
        height: 25px;
        width: 25px;
    }
    
    #main-container {
        width: 100%;
        height: 300px;
    }
    
    #custom-container {
        width: 100%;
        height: 100%;
    }
    
    
       
     <p>Click somewhere to move the red square</p>
      <label>
        enable zoom
        <input type="checkbox" id="zoom-enabled">
    </label>
    
    
    <div id="main-container">
        <div id="custom-container">
            <div id="point"></div>
        </div>
    
    </div>

    With zoom removed it is now possible to apply transform css property to make container still fit in size but allow correct click coordinates. I do not cover the follow up step here.


  2. Try dividing the coordinates by the current zoom level.

    const mainContainer = document.getElementById('main-container')
    
    // enable / disable zoom
    const zoomCb = document.getElementById('zoom-enabled')
    zoomCb.addEventListener('click', () => {
        mainContainer.style.zoom = zoomCb.checked ? '50%' : ''
    })
    
    const workspace = document.getElementById('custom-container')
    
    // Sample pageX and pageY are wrong when using zoom
    workspace.addEventListener('click', e => {
        const zoomLevel = getComputedStyle(mainContainer).zoom
    
        const point = document.getElementById('point')
        point.style.left = e.pageX / zoomLevel + 'px'
        point.style.top = e.pageY / zoomLevel + 'px'
    })
    #point {
        position: absolute;
        background-color: red;
        height: 25px;
        width: 25px;
    }
    
    #main-container {
        width: 100%;
        height: 300px;
    }
    
    #custom-container {
        width: 100%;
        height: 100%;
    }
    
    
       
     <p>Click somewhere to move the red square</p>
      <label>
        enable zoom
        <input type="checkbox" id="zoom-enabled">
    </label>
    
    
    <div id="main-container">
        <div id="custom-container">
            <div id="point"></div>
        </div>
    
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search