Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hack for power users to deal with transform scale #9014

Closed
wants to merge 8 commits into from
Closed

Hack for power users to deal with transform scale #9014

wants to merge 8 commits into from

Conversation

pakastin
Copy link
Contributor

@pakastin pakastin commented Nov 22, 2019

This is more for power users, but if you show map inside scaled element (transform: scale), mouse events won't work. It was also impossible to change map rendering pixel ratio. To get round with the issue, I did following things:

  • fixed one file with window.devicePixelRatio to browser.devicePixelRatio
  • exposed browser in index.js to make it possible to change the getter
  • added hidden _scaleRatio to canvas container to make it possible to fix scale issue

So when there's transform: scale applied, I do following:

import { browser } from 'mapbox-gl';

...

Object.defineProperty(browser, 'devicePixelRatio', {
  get () {
    return window.devicePixelRatio * scale;
  }
});

map._canvasContainer._scaleRatio = scale;
map.resize();
  • devicePixelRatio getter tricks map to render in lower pixel density
  • _scaleRatio fixes mouse/touch events

You can see the working version here when you click the printing button. It'll scale map to fit A4 portrait and landscape paper sizes. Also before exporting image, it'll use higher pixel density.

Launch Checklist

  • briefly describe the changes in this PR

@pakastin
Copy link
Contributor Author

Related to #6079, #7701 and #1953

@pakastin
Copy link
Contributor Author

I'm not familiar with Flow, if someone could help to fix type issue

@ryanhamley
Copy link
Contributor

Am I correct that this is not a self-contained solution but exposes some hooks that allow for the users to implement a hack in their client? I think we'd rather have self-contained solutions to these issues in GL JS. The print feature on your site is impressive but I don't think this is the way we'd want to go in the library.

@pakastin
Copy link
Contributor Author

You're right, I'll check how usage could be enhanced.. 👍

@kkaefer
Copy link
Contributor

kkaefer commented Dec 3, 2019

I looked into this a bit. I think this pull request conflates two things:

  • Correct locations when interacting with a map that is scaled through CSS transforms
  • Logically scaling the contents of the map by modifying the devicePixelRatio.

I worked on an alternative fix for the former in #9057. It works for scaled maps without additional code in the surrounding page (i.e. it doesn't use the custom _scaleRatio property).

The latter is ticketed in #1953. The problem with devicePixelRatio is that it's a global property that could also affect other maps on the same page. Instead of messing with devicePixelRatio, we could introduce a pixelRatio property on the map constructor that defaults to devicePixelRatio, but that also allows passing in other properties to render high resolution maps. We could also seed its initial value based on el.clientWidth / el.getBoundingClientRect().width.

@kkaefer
Copy link
Contributor

kkaefer commented Dec 4, 2019

Pulled the window -> browser.devicePixelRatio into a separate PR: #9063

The other changes in this PR are split up into #1953 (devicePixelRatio) and #9057 (mouse position with CSS transforms).

Thanks for contributing to Mapbox GL JS!

@beniaminrychter
Copy link

I know that this is very old thread, but I can't force higher devicePixelRatio on my mapbox-gl implementation. I'm trying to do it before rendering a map, but still no matter what I do, map is renderer with window.devicePixelRatio instead of browser.devicePixelRatio.

@pakastin Can you maybe help me with that, and give more information how you handled this in your application that this started to working properly?

Or maybe it's not possible without your changes in this PR? Because I just imported the browser like this:

import browser from 'mapbox-gl/src/util/browser';

and now I'm thinking if I even changing same object that mapbox-gl uses.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants