2016-09-27 124 views
0

我將紋理圖像映射到球體並將標籤附加到圖像上,但某些標籤重疊,我想要分隔標籤而不更改「lon」和「lat」的值」。我需要知道如何分離標籤或如何重新定位標籤。並且我也上傳了圖片(鏈接)。而且我還上傳了完整的代碼。 請幫我解決這個問題。在這個程序中使用使用JavaScript防止標籤重疊

image link

CSS代碼

div.spritelabel { 
position:absolute; 
top:0px; 
left:0px; 
color:#0000FF; 
font-family: 'Trebuchet MS', sans-serif; 
font-size:15px; 
font-weight:normal; 
line-height:15px; 
text-align: left; 
padding:5px; 

-webkit-box-shadow: 0px 4px 8px -3px rgba(0,0,0,0.75); 
-moz-box-shadow: 0px 4px 8px -3px rgba(0,0,0,0.75); 
box-shadow: 0px 4px 8px -5px rgba(0,0,0,0.75); 
background:rgba(255, 255, 255, 0.8); 
} 
a:link {color: brown; background-color: transparent; text-decoration: none;} 
a:visited{color: green; background-color: transparent; text-decoration: none;} 
a:hover{color: red; background-color: transparent; text-decoration: underline;} 
a:active {color: yellow; background-color: transparent; text-decoration: underline;} 

JavaScript代碼

function createsphere() 
{ 
var spriteboxes = []; 
var sprite,controls,scene,camera,renderer; 
var spritearray = []; 
spritearray[0] = {"name": "North", "lat":0, "lon": 10}; 
spritearray[1] = {"name": "south", "lat":0, "lon": 20}; 
spritearray[2] = {"name": "East", "lat":0, "lon": 30}; 
spritearray[3] = {"name": "west", "lat":0, "lon": 40}; 
spritearray[4] = {"name": "North-west", "lat":0, "lon": 45}; 
spritearray[5] = {"name": "North-east", "lat":0, "lon": 47}; 
spritearray[6] = {"name": "south-east", "lat":0, "lon": 50}; 
function convertlatlonToVec3(lat, lon) 
{ 
    lat = lat * Math.PI/180.0; 
    lon = -lon * Math.PI /180.0; 
    return new THREE.Vector3(
     Math.cos(lat)* Math.sin(lon), 
     Math.sin(lat)* Math.sin(lon), 
     Math.cos(lat)); 

} 

function labelBox(Ncardinal, radius, domElement) 
{ 
    this.screenVector = new THREE.Vector3(0, 0, 0); 
    this.position = convertlatlonToVec3(Ncardinal.lat,Ncardinal.lon).multiplyScalar(radius); 
    this.box = document.createElement('div'); 
    a = document.createElement('a'); 
    a.innerHTML = Ncardinal.name; 
    a.href ='http://www.google.de'; 
    this.box.className = "spritelabel"; 
    this.box.appendChild(a); 

    this.domElement = domElement; 
    this.domElement.appendChild(this.box); 
} 

labelBox.prototype.update = function() 
{ 
this.screenVector.copy(this.position); 
this.screenVector.project(camera); 

var posx = Math.round((this.screenVector.x + 1)* this.domElement.offsetWidth/2); 
var posy = Math.round((1 - this.screenVector.y)* this.domElement.offsetHeight/2); 

var boundingRect = this.box.getBoundingClientRect(); 

//update the box overlays position 
this.box.style.left = (posx - boundingRect.width) + 'px'; 
this.box.style.top = posy + 'px'; 



}; 





function init() 
     { 
      scene = new THREE.Scene(); 
      camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 
      camera.position.y = 1; 
      camera.position.z = 5; 

      var width = window.innerWidth; 
      var height = window.innerHeight; 
      renderer = new THREE.WebGLRenderer({antialias:true}); 
      renderer.setSize(width, height); 
      document.body.appendChild(renderer.domElement); 
      var radius = 2.5; 
      var spheregeometry = new THREE.SphereGeometry(radius, 20, 20, 0, -6.283, 1, 1); 
      var texture = THREE.ImageUtils.loadTexture ('Sample Images/rbi00000083.jpg'); 
      texture.minFilter = THREE.NearestFilter; 
      var spherematerial = new THREE.MeshBasicMaterial({map: texture}); 
      var sphere = new THREE.Mesh(spheregeometry, spherematerial); 

      scene.add(sphere); 
      scene.add(camera); 
      scene.autoUpdate = true; 

      controls = new THREE.OrbitControls(camera, renderer.domElement); 
      controls.minPolarAngle = Math.PI/4; 
      controls.maxPolarAngle = 3*Math.PI/4; 

      for(var i = 0; i< spritearray.length;i++) 
      { 
       var Ncardinal = spritearray[i]; 
       sprite = new labelBox(Ncardinal, radius, document.body); 
       //this.marker = new THREE.Mesh(new THREE.SphereGeometry(0.05, 30, 30)); 
       //this.marker.position.copy(sprite.position); 
       //scene.add(marker); 
       spriteboxes.push(sprite); 
      } 

      //var Ncardinal = {"name": "North", "lat":0, "lon": 10}; 
      //sprite = new labelBox(Ncardinal, radius, document.body); 


     } 
    function animate() { 

    spriteboxes.forEach(function(e) { e.update()}); 
    sprite.update(); 
    requestAnimationFrame(animate); 
    controls.update(); 
    renderer.render(scene, camera); 
      } 
init(); 
animate(); 
} 
+2

可能重複[如何避免在javacript中重疊標籤?](http://stackoverflow.com/questions/39590214/how-to-avoid-labels-overlapping-in-javacript) – 2pha

+0

@ lakers1234您應該考慮刪除那個問題大部分是相同的。 –

回答

0

由於您的標籤都沒有實際的3D對象,這個問題確實已經無關3D 。你需要做的是這個(這是一個樸素的算法,可以爲大量標籤等進行優化):

  • 1.)找出每個標籤的確切標籤尺寸,存儲它們某處(使用element.offsetWidth/Height
  • 2.)計算每個標籤「錨位」,即是屏幕位置
  • 3.)使用以下算法將所有標籤:
    • 一個)計算如果放置在錨定位置(按Box,即頂部/左側,底部),則由該標籤佔據的區域您可以使用THREE.Box2-類來存儲該信息)
    • b)測試已經放置在屏幕上的所有框的交叉點(即, box.intersectsBox(otherBox))。 c)如果沒有十字路口,我們有一個放置這個方塊,並可以繼續下一個方塊
    • d)如果有交集,找到一個放置標籤的地方,我簡單地再根據標籤的相對位置再次嘗試一些像素向上/向下/向左/向右,如果在多次嘗試後找不到經過放置的位置,請務必中止(並簡單地跳過標籤) 。

它不會總是能夠找到一個地方,每一個標籤,因此是很有意義的優先級開始,將其插入到命令他們。