1

Surfaces created with Famo.us/Angular and translated to a negative Z position don't receive ng-click events in Chrome. This seems to be a known WebKit bug and is not a problem in Firefox; see an example in the below Plunker.

Now I would like to have a collection of surfaces floating in and out along the Z-axis and be able to click on any of them to bring it to the foreground, which is a problem in Chrome when they have a somewhat large negative Z value.

I could have the surfaces fa-pipe-to an EventHandler, but the event data doesn't seem to contain information about the source of the event, so I'm not able to discern exactly what surface was clicked.

What is a good way to implement this behaviour that plays well in Chrome?

The Famo.us Periodic Table Demo implements a behaviour similar to what I have in mind: Surfaces float there in and out and it works well in Chrome. How is it done there? ...haven't been able to figure that out from the minified code.

The Unity game engine provides a raycasting functionality, where you can get objects hit under a mouse click. Maybe I should implement something similar, but my guess is that picking surfaces in the Periodic Table Demo is done in a simpler way. Did they maybe just make sure that the surfaces stay in positive Z locations?

Here's an example rendering a red square at Z=0, which receives a click event in Chrome, while the green square rendered at Z=-200 won't get a click event, unless you'll run the example in Firefox:

http://plnkr.co/edit/UZp4oB?p=preview

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Clicking on Famo.us surfaces in deep z-space</title>
  <link href="famous-angular.css" rel="stylesheet" type="text/css">
  <link href="style.css" rel="stylesheet" type="text/css">

  <script src="https://code.famo.us/famous/global/0.2.2/famous.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
  <script src="famous-angular.js"></script>
</head>
<body ng-app="faScrollViewExampleApp">

  <fa-app ng-controller="ScrollCtrl" fa-perspective="1000">

    <fa-view ng-repeat="surface in surfaces">

      <fa-modifier fa-size="[200, 200]" 
          fa-translate="[200*$index, 200*$index, surface.zIndex]">
       <fa-surface fa-background-color="surface.color"
          ng-click="surfaceClick($index)">

         I'm in z = {{surface.zIndex}}

       </fa-surface>
      </fa-modifier>      

    </fa-view>

  </fa-app>

  <script>
    angular.module('faScrollViewExampleApp', ['famous.angular'])
        .controller('ScrollCtrl', ['$scope', '$famous', function($scope, $famous) {

          $scope.surfaces = [
            {color: 'red', zIndex: 0}, 
            {color: 'green', zIndex: -200} ];

          $scope.surfaceClick = function( index ) {

            alert( "index " + index + " clicked");
          }

      }]);
  </script>
</body>
</html>
Community
  • 1
  • 1
Bjorn Thor Jonsson
  • 827
  • 1
  • 10
  • 21

1 Answers1

2

If you inspect the DOM, the element <div class="famous-angular-clipping-container"> has no transform-style:preserve-3d on the famous-angular-clipping-container. The default for transform-style is flat and not to inherit from the parent.

<div class="famous-angular-clipping-container">
  <div class="famous-angular-container" style="perspective: 1000px; -webkit-perspective: 1000;">
    <div class="famous-surface ng-click-active" style="opacity: 0.999999; -webkit-transform-origin: 0% 0% 0px; -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); width: 200px; height: 200px; background-color: red;">
      <div class="fa-surface"><span class="ng-binding ng-scope">
         I'm in z = 0
       </span>
      </div>
    </div>
    <div class="famous-surface" style="opacity: 0.999999; -webkit-transform-origin: 0% 0% 0px; -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 200, 200, -200, 1); width: 200px; height: 200px; background-color: green;">
      <div class="fa-surface"><span class="ng-binding ng-scope">
         I'm in z = -200
       </span>
      </div>
    </div>
  </div>
</div>

Not sure if this is by design in famous-angular specs, but if it is added to the class then it fixes the issue.

.famous-angular-clipping-container {
    -webkit-transform-style: preserve-3d;
    transform-style: preserve-3d;
    overflow: hidden;
    width: 100%;
    height: 100%;
}
talves
  • 13,993
  • 5
  • 40
  • 63
  • It might be best to check with the developers of `famous-angular` to see if this was intended behavior or a bug. – talves Apr 21 '15 at 01:18
  • Many thanks @talves for pointing to the `transform-style` CSS property! Setting it to the `preserve-3d` value solves the problem, but also introduces a new behaviour, where [surfaces with a lower Z translation value can appear in front of those in higher Z](http://plnkr.co/edit/36zfpT?p=preview), if they were added later to the DOM. This can be solved [by ensuring that surfaces with a lower Z translation also have a z-index CSS property set to a lower value](http://plnkr.co/edit/8MAMsZ?p=preview). Then things seem to work just fine. – Bjorn Thor Jonsson Apr 21 '15 at 12:47
  • Maybe this changed behaviour is why the default `transform-style` is `flat` in `famous-angular`. Also, [transform-style is currently flagged as experimental technology](https://developer.mozilla.org/en-US/docs/Web/CSS/transform-style). – Bjorn Thor Jonsson Apr 21 '15 at 12:50
  • Glad that helped, but I am not sure if that will be the end of the solution. It seems the `famous-angular` repo is not being completely maintained at the moment. There is a lot of waiting for "Mixed Mode" before people start putting time into updating libraries that use `Famo.us`. I myself have put my own projects on hold until then. – talves Apr 21 '15 at 15:47
  • Yeah, Mixed Mode definitely sounds interesting and it will be fun diving into that, but version .3 is pretty good for [what I'm currently up to](https://twitter.com/gameoflikes), though moving things could be less CPU hungry :) – Bjorn Thor Jonsson Apr 21 '15 at 21:44