mapbox-developer-group / Mapbox-Tech-Q-A

在提问之前请自行查看文档哦,养成好习惯:https://docs.mapbox.com/
32 stars 1 forks source link

【Web】如何在zoom或者bearing,pitch时保持图形视觉大小布标,现在是近大远小 #37

Open Momohanfeng opened 4 years ago

Momohanfeng commented 4 years ago

我遇到的问题

添加一个Threejs的layer,里面绘制一个导航箭头,希望他能够无论是缩放,还是旋转,还是移动地图,在视觉上呈现的大小是一致的。但是现在会放大缩小。Mapboxgl自带的marker由于部分原因不能满足功能,所以没有使用Marker。

我遇到的问题截图

qqq

该问题的类别

当前是开发的Web应用。

@dazhi1011 还请抽空指点一下,感谢~

goldenlimit commented 4 years ago

來自iOS方向的佈道小助手,好奇幫你搜了下這個問題,不知道國內能否看到stackoverflow,找到一個類似的問題:https://stackoverflow.com/questions/40446915/three-js-keep-label-size-on-zoom

I figure you could calculate the distance from each label to the camera then come up with some sort of scaling factor based on that.

And it's very simple. Let's say, a THREE.Sprite() object (label) is a child of a THREE.Mesh() object (planet), then in your animation loop you need to do

var scaleVector = new THREE.Vector3();
var scaleFactor = 4;
var sprite = planet.children[0];
var scale = scaleVector.subVectors(planet.position, camera.position).length() / scaleFactor;
sprite.scale.set(scale, scale, 1); 

I've made a very simple example of the Solar System, using this technique.

你可以參考下 原問題著提供的一個保持symbol大小的demo

Momohanfeng commented 4 years ago

@goldenlimit 感謝解答,但是我發現demo中的sprite的position是不斷變化的,所以可以計算與camera的distance來計算scale,但是添加到mapboxgl中的threejs中的圖形的position不會隨著地圖的縮放或者移動旋轉等發生變化,這也是我目前遇到的問題的原因。

所以我現在想請教,有沒有什麼方法計算自定義圖層中的obj對應mapbox的camera的距離的算法?

dazhi1011 commented 4 years ago

好例子,赞 @goldenlim 这个距离的定义有点模糊,暂且把它理解成obj的深度好了,伪代码写下

//计算深度的
var mercator=mapboxgl.MercatorCoordinate.fromLngLat({ lng: 0, lat: 0}, 0)
var pos=matrix*vec4(mercator.x,mercator.y,0,1)  
var z=pos.z/pos.w

matrix为custom layer的render方法中传入的参数

//计算比例,z_aflter表示变化后深度, z_before表示变化前深度
scale=z_aflter/z_before

@Momohanfeng 试一试看可以不