Browse Source

add sorting

Gregg Tavares 6 years ago
parent
commit
bf7fc66af0

+ 69 - 0
threejs/lessons/threejs-align-html-elements-to-3d.md

@@ -303,6 +303,69 @@ use gpu based picking like we covered in the [picking
 article](threejs-picking.html) but that is also not free. Which solution you
 article](threejs-picking.html) but that is also not free. Which solution you
 chose depends on your needs.
 chose depends on your needs.
 
 
+Another issue is the order the labels appear. If we change the code to have
+longer labels
+
+```js
+const cubes = [
+-  makeInstance(geometry, 0x44aa88,  0, 'Aqua'),
+-  makeInstance(geometry, 0x8844aa, -2, 'Purple'),
+-  makeInstance(geometry, 0xaa8844,  2, 'Gold'),
++  makeInstance(geometry, 0x44aa88,  0, 'Aqua Colored Box'),
++  makeInstance(geometry, 0x8844aa, -2, 'Purple Colored Box'),
++  makeInstance(geometry, 0xaa8844,  2, 'Gold Colored Box'),
+];
+```
+
+and set the CSS so these don't wrap
+
+```css
+#labels>div {
++  white-space: nowrap;
+```
+
+Then we can run into this issue
+
+<div class="threejs_center"><img src="resources/images/label-sorting-issue.png" style="width: 401px;"></div>
+
+You can see above the purple box is in the back but its label is in front of the aqua box.
+
+We can fix this by setting the `zIndex` of each element. The projected position has a `z` value
+that goes from -1 in front to positive 1 in back. `zIndex` is required to be an integer and goes the
+opposite direction meaning for `zIndex` greater values are in front so the following code should work.
+
+```js
+// convert the normalized position to CSS coordinates
+const x = (tempV.x *  .5 + .5) * canvas.clientWidth;
+const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
+
+// move the elem to that position
+elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
++// set the zIndex for sorting
++elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
+```
+
+Because of the way the projected z value works we need to pick a large number to spread out the values
+otherwise many will have the same value. To make sure the labels don't overlap with other parts of
+the page we can tell the browser to create a new [stacking context](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context)
+by setting the `z-index` of the container of the labels
+
+```css
+#labels {
+  position: absolute;  /* let us position ourself inside the container */
++  z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
+  left: 0;             /* make our position the top left of the container */
+  top: 0;
+  color: white;
+  z-index: 0;
+}
+```
+
+and now the labels should always be in the correct order.
+
+{{{example url="../threejs-align-html-to-3d-w-sorting.html" }}}
+
 While we're at it let's do one more example to show one more issue.
 While we're at it let's do one more example to show one more issue.
 Let's draw a globe like Google Maps and label the countries.
 Let's draw a globe like Google Maps and label the countries.
 
 
@@ -460,6 +523,9 @@ function updateLabels() {
 
 
     // move the elem to that position
     // move the elem to that position
     elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
     elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+    // set the zIndex for sorting
+    elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
   }
   }
 }
 }
 ```
 ```
@@ -565,6 +631,9 @@ function updateLabels() {
 
 
     // move the elem to that position
     // move the elem to that position
     countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
     countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+    // set the zIndex for sorting
+    elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
   }
   }
 }
 }
 ```
 ```

+ 4 - 0
threejs/threejs-align-html-elements-to-3d-globe-too-many-labels.html

@@ -23,6 +23,7 @@
     }
     }
     #labels {
     #labels {
       position: absolute;  /* let us position ourself inside the container */
       position: absolute;  /* let us position ourself inside the container */
+      z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
       left: 0;             /* make our position the top left of the container */
       left: 0;             /* make our position the top left of the container */
       top: 0;
       top: 0;
       color: white;
       color: white;
@@ -164,6 +165,9 @@ function main() {
 
 
       // move the elem to that position
       // move the elem to that position
       elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
       elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+      // set the zIndex for sorting
+      elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
     }
     }
   }
   }
 
 

+ 5 - 1
threejs/threejs-align-html-elements-to-3d-globe.html

@@ -23,6 +23,7 @@
     }
     }
     #labels {
     #labels {
       position: absolute;  /* let us position ourself inside the container */
       position: absolute;  /* let us position ourself inside the container */
+      z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
       left: 0;             /* make our position the top left of the container */
       left: 0;             /* make our position the top left of the container */
       top: 0;
       top: 0;
       color: white;
       color: white;
@@ -216,7 +217,10 @@ function main() {
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
 
 
       // move the elem to that position
       // move the elem to that position
-      countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+      elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+      // set the zIndex for sorting
+      elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
     }
     }
   }
   }
 
 

+ 5 - 1
threejs/threejs-indexed-textures-picking-and-highlighting.html

@@ -23,6 +23,7 @@
     }
     }
     #labels {
     #labels {
       position: absolute;  /* let us position ourself inside the container */
       position: absolute;  /* let us position ourself inside the container */
+      z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
       left: 0;             /* make our position the top left of the container */
       left: 0;             /* make our position the top left of the container */
       top: 0;
       top: 0;
       color: white;
       color: white;
@@ -295,7 +296,10 @@ function main() {
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
 
 
       // move the elem to that position
       // move the elem to that position
-      countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+      elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+      // set the zIndex for sorting
+      elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
     }
     }
   }
   }
 
 

+ 5 - 1
threejs/threejs-indexed-textures-picking-debounced.html

@@ -23,6 +23,7 @@
     }
     }
     #labels {
     #labels {
       position: absolute;  /* let us position ourself inside the container */
       position: absolute;  /* let us position ourself inside the container */
+      z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
       left: 0;             /* make our position the top left of the container */
       left: 0;             /* make our position the top left of the container */
       top: 0;
       top: 0;
       color: white;
       color: white;
@@ -295,7 +296,10 @@ function main() {
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
 
 
       // move the elem to that position
       // move the elem to that position
-      countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+      elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+      // set the zIndex for sorting
+      elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
     }
     }
   }
   }
 
 

+ 5 - 1
threejs/threejs-indexed-textures-picking.html

@@ -23,6 +23,7 @@
     }
     }
     #labels {
     #labels {
       position: absolute;  /* let us position ourself inside the container */
       position: absolute;  /* let us position ourself inside the container */
+      z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
       left: 0;             /* make our position the top left of the container */
       left: 0;             /* make our position the top left of the container */
       top: 0;
       top: 0;
       color: white;
       color: white;
@@ -226,7 +227,10 @@ function main() {
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
 
 
       // move the elem to that position
       // move the elem to that position
-      countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+      elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+      // set the zIndex for sorting
+      elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
     }
     }
   }
   }
 
 

+ 5 - 1
threejs/threejs-indexed-textures-random-colors.html

@@ -23,6 +23,7 @@
     }
     }
     #labels {
     #labels {
       position: absolute;  /* let us position ourself inside the container */
       position: absolute;  /* let us position ourself inside the container */
+      z-index: 0;          /* make a new stacking context so children don't sort with rest of page */
       left: 0;             /* make our position the top left of the container */
       left: 0;             /* make our position the top left of the container */
       top: 0;
       top: 0;
       color: white;
       color: white;
@@ -275,7 +276,10 @@ function main() {
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
       const y = (tempV.y * -.5 + .5) * canvas.clientHeight;
 
 
       // move the elem to that position
       // move the elem to that position
-      countryInfo.elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+      elem.style.transform = `translate(-50%, -50%) translate(${x}px,${y}px)`;
+
+      // set the zIndex for sorting
+      elem.style.zIndex = (-tempV.z * .5 + .5) * 100000 | 0;
     }
     }
   }
   }