如何在 Mapbox GL 中修复画布大小?

问题描述 投票:0回答:9

我正在使用 Mapbox GL 显示地图并从其中心裁剪固定大小的图像。它非常适合我设计的特定分辨率(1920x1080),但是当我开始使页面响应,其中地图样式

width
height
发生变化时,画布大小也开始发生变化!

因此,当我裁剪图像时,大小应该始终不同,因为 900 像素画布上的 300 像素与 2000 像素画布上的 300 像素不是同一地图区域。如果我在 Chrome 中将设备类型从桌面更改为移动,画布大小甚至会发生巨大变化。

有什么方法可以让画布 DOM 大小固定,同时使用 CSS 属性缩放整个地图,就像在正常情况下完成的那样

canvas
?我尝试做
trackResize: false
并且画布 DOM 大小保持固定,但地图也没有缩放以适合容器。

mapbox-gl mapbox-gl-js
9个回答
18
投票

对于版本:“mapbox-gl”:“^1.2.1”,设置canvas地图容器类的高度:

.mapboxgl-canvas-container {

    height: 100vh;

}

然后在地图加载事件上:

onMapLoaded(event) {

    event.map.resize();

}

16
投票
map.on('idle',function(){
map.resize()
})

试试这个。它对我来说效果很好。(仅适用于 Mapbox 用户)


2
投票

我认为最好的方法是在加载之前使地图的大小无效,迫使其自行调整大小。

角度/离子

import { AfterViewInit, Component, OnInit } from '@angular/core'
import * as  mapboxgl from 'mapbox-gl'

@Component({
  selector: 'app-map',
  templateUrl: 'map.page.html',
  styleUrls: ['map.page.scss']
})
export class MapPage implements AfterViewInit, OnInit {
  private map: mapboxgl.Map  

  constructor() {
    mapboxgl.accessToken = "<YOUR_TOKEN>"
  }

  ngOnInit() {
    setTimeout(() => this.buildMap(), 0);
  }

  ngAfterViewInit() {
    setTimeout(() => this.map.invalidateSize(), 0);
  }

  buildMap() {
    let conf = {
      container: 'map',
      style: '<YOUR_CUSTOM_STYLE>'
      zoom: 13,
      center: [lng, lat]
    }
    this.map = new mapboxgl.Map(conf)  
    // Add map controls
    this.map.addControl(new mapboxgl.NavigationControl())
  }
}

1
投票

如果我理解正确的话,您希望地图始终显示地理区域,无论地图容器有多大或多小?这与大多数网络地图的标准行为相反,大多数网络地图保持比例相同,并扩大或缩小覆盖区域。

如果这就是您想要的,您可以通过在窗口调整大小时调用

map.fitBounds()
来实现。


0
投票

根据 @davejoem 的回答,我可以通过在

buildMap()
函数之外放置 setTimeout 来显示完整的地图高度,而无需拉伸。我不必使用
invalidateSize()
,因为它会抛出此错误:

错误 TS2339:类型“Map”上不存在属性“invalidateSize”。

不过,我不得不将

setTimeout
buildMap()
放入
ngAfterViewInit()
函数中,并将 2000 放在 setTimeout 的第二个参数上,因为有时硬刷新,地图不是全高。

希望这可以帮助彻底解决问题。


0
投票

我正在使用 Angular 9,这对我来说是这样的:

ngAfterViewInit() {
    setTimeout(() => this.buildMap(), 2000);
  }


0
投票

我不知道这是否会对某人有帮助,但由于某种原因,桌面中窗口的设备像素比是 1,而移动设备中的设备像素比是不同的。

如果您尝试使地图具有响应性,但在切换到移动设备时出现问题,是因为您的设备像素比在不同平台上有所不同。

尝试使用以下方法获取您的设备像素比:

window.devicePixelRatio

并使用它。

在我的例子中,我正在使用片段着色器,尝试结合地图上的位置和缩放来绘制圆圈。但由于片段着色器使用 canvas.width (而不是 canvas.clientWidth)工作,当我切换到移动设备时,表示 100 米的像素数量发生了变化,因此我使用设备像素比率,然后使用设备像素将更大数量的像素转换为米比例...

如果有人在使用 MapboxGL-JS 片段着色器和像素到米的转换时遇到问题:

uniform float u_dpr; // the window.devicePixelRatio

//v_rad is radius in meters
//40075017.0 circunference of earth
//cos(-0.296) is based on my latitude
//etc.. 
//multiply the final value by the pixel ratio to get responsiveness working 

float maxDist = (v_rad / (40075017.0*cos(-0.296)/pow(2.0, (u_zoom+9.0)))*u_dpr);

0
投票

我正在使用 Angular 10.2.x,下面的代码对我有用

ngAfterViewInit() {        
    setTimeout(() => this.buildMap(), 200);
}

-2
投票

解决方案

<div
    ref={el => this.mapContainer = el}
    style={{
            position: 'absolute',
            top: 0,
            bottom: 0,
            width: '100%',
            height: '100vh',
     }}
 />
© www.soinside.com 2019 - 2024. All rights reserved.