block by enjalot 5442d07cb2d3a147ed36

infinite blocks

Full Screen

forked from curran‘s block:

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">

    <title>Intro to Data Vis with D3</title>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.13/d3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.6/react-dom.js"></script>

    <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" type="text/css">

    <link href="styles.css" rel="stylesheet" type="text/css">

  </head>
  <body>
    <div id="app-container"></div>
    <script src="main-build.js"></script>
  </body>
</html>

items.json

main-build.js

var NavItem = React.createClass({
  displayName: "NavItem",

  click: function (e) {
    this.props.controller.setCurrentIndex(this.props.item.index);
  },
  render: function () {
    var item = this.props.item;
    var blocksUrl = "http://bl.ocks.org/curran/" + item.id;
    var thumbnailUrl = "http://bl.ocks.org/curran/raw/" + item.id + "/thumbnail.png";
    var imgClass = "nav-item-thumbnail" + (this.props.active ? " active" : "");
    return React.createElement(
      "div",
      { className: "nav-item", onClick: this.click },
      React.createElement(
        "span",
        { className: "nav-item-title" },
        item.title
      ),
      React.createElement("img", { className: imgClass, src: thumbnailUrl })
    );
  }
});

var NavList = React.createClass({
  displayName: "NavList",

  render: function () {
    return React.createElement(
      "div",
      { className: "nav" },
      this.props.items.map(item => {
        return React.createElement(NavItem, { item: item,
          key: item.index,
          active: item.index === this.props.currentIndex,
          controller: this.props.controller });
      })
    );
  }
});

var ContentPane = React.createClass({
  displayName: "ContentPane",

  render: function () {
    var blockbuilderUrl = "http://blockbuilder.org/curran/" + this.props.item.id + "#embed=true";
    return React.createElement("iframe", { className: "content", src: blockbuilderUrl });
  }
});

var App = React.createClass({
  displayName: "App",

  getInitialState() {
    return {
      items: [],
      item: {},
      currentIndex: 0
    };
  },
  render() {
    return React.createElement(
      "div",
      { className: "app" },
      React.createElement(NavList, { items: this.state.items,
        currentIndex: this.state.currentIndex,
        controller: this.props.controller }),
      React.createElement(ContentPane, { item: this.state.item })
    );
  }
});

var mountNode = document.getElementById("app-container");
var controller = {};
var app = ReactDOM.render(React.createElement(App, { controller: controller }), mountNode);

controller.setItems = items => {
  app.setState(() => {
    return { items: items };
  });
  controller.setCurrentIndex(0);
};

controller.setCurrentIndex = currentIndex => {
  app.setState(previousState => {
    return {
      currentIndex: currentIndex,
      item: previousState.items[currentIndex]
    };
  });
};

// Increment (offset == 1) or decrement (offset == -1) the current index.
controller.incrementCurrentIndex = offset => {
  app.setState(previousState => {
    var currentIndex = previousState.currentIndex + offset;

    // Guard against going out of bounds.
    var n = previousState.items.length;
    currentIndex = currentIndex < 0 ? 0 : currentIndex;
    currentIndex = currentIndex >= n ? n - 1 : currentIndex;

    return {
      currentIndex: currentIndex,
      item: previousState.items[currentIndex]
    };
  });
};

// Load the file that configures the items and their order.
d3.json("items.json", (err, items) => {

  // Assign an index to each item.
  items.forEach((item, i) => item.index = i);

  // Set the state from the loaded data.
  controller.setItems(items);
});

// Set up navigation with arrow keys.
window.addEventListener("keydown", function (e) {
  var offsets = {

    // Decrement slide on UP (38) and LEFT (37)
    37: -1,
    38: -1,

    // Increment slide on DOWN (40) and RIGHT (39);
    39: 1,
    40: 1
  };
  controller.incrementCurrentIndex(offsets[e.keyCode]);
});

main.js

package.json

styles.css