examples/fancy-header/index.js
function handler(x, y, self, items, scroller) {
  var transitionPixels = 100;
  var ratio = 6;
  var headerPos = Math.max(transitionPixels - y, 0) / ratio;
  if (y < 0) {
    headerPos = transitionPixels / ratio;
  }

  switch (self.props.name) {
    case "content":
      return {
        zIndex: 3,
        y: -y + items.background.rect.height,
      };
    case "white":
      return {
        // this rounding to 0.001 and 0.9999 should not be needed.
        // some browsers were causing re-paint. So I will leave this here
        // as documentation
        opacity: Math.max(0.001, Math.min(1/transitionPixels * y, 0.9999)),
        zIndex: 5,
        y: headerPos,
      };
    case "transparent":
      return {
        zIndex: 4,
        y: headerPos,
      };
    case "background":
      return {
        scale: Math.max(1, 1 - (y / 400)),
        zIndex: 2,
        y: Math.min(0, -y),
      };
    default:
      // during development, if I create a new <ScrollItem> this is handy
      // as it will sticky this element to the bottom of the <Scroller>
      return {
        zIndex: 10,
        y: scroller.rect.height - self.rect.height,
      };
  }
}
function handler(x, y, self, items, scroller) {
  var transitionPixels = 100;
  var ratio = 6;
  var headerPos = Math.max(transitionPixels - y, 0) / ratio;
  if (y < 0) {
    headerPos = transitionPixels / ratio;
  }

  switch (self.props.name) {
    case "content":
      return {
        zIndex: 3,
        y: -y + items.background.rect.height,
      };
    case "white":
      return {
        // this rounding to 0.001 and 0.9999 should not be needed.
        // some browsers were causing re-paint. So I will leave this here
        // as documentation
        opacity: Math.max(0.001, Math.min(1/transitionPixels * y, 0.9999)),
        zIndex: 5,
        y: headerPos,
      };
    case "transparent":
      return {
        zIndex: 4,
        y: headerPos,
      };
    case "background":
      return {
        scale: Math.max(1, 1 - (y / 400)),
        zIndex: 2,
        y: Math.min(0, -y),
      };
    default:
      // during development, if I create a new <ScrollItem> this is handy
      // as it will sticky this element to the bottom of the <Scroller>
      return {
        zIndex: 10,
        y: scroller.rect.height - self.rect.height,
      };
  }
}
/*
Notice: It's a Scrollable best practice to use plain functions instead
of React bound methods. Read more about why on the minimal example.