JSFiddle - React, Tailwind, and code Playground

by rdvornov

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/basis.js/1.10.2/basis.min.js"></script>

JavaScript

var Node = basis.ui.Node;
var Expression = basis.data.value.Expression;

var targetSize = 25;
var start = new Date().getTime();
var elapsed = new basis.Token(0);

var Dot = Node.subclass({
  template: `
    <b:isolate/>
    <b:style>
      .dot {
        position: absolute;
        background: #61dafb;
        font: normal 15px sans-serif;
        text-align: center;
        cursor: pointer;
      }
      .dot:hover {
        background: #ff0;
      }
    </b:style>
    <div class="dot" style="
      width: {size}px;
      height: {size}px;
      left: {x}px;
      top: {y}px;
      border-radius: 50%;
      line-height: {size}px" event-mouseenter="enter" event-mouseleave="leave">
      {caption}
    </div>
  `,
  binding: {
    x: 'data:',
    y: 'data:',
    size: {
      events: 'update',
      getter: function(node) {
        return node.data.size * 1.3;
      }
    },
    caption: function(node) {
      return new Expression(node.hover, node.data.text, function(hover, text) {
        return hover ? '*' + text + '*' : text;
      });
    }
  },
  action: {
    enter: function() {
      this.hover.set(true);
    },
    leave: function() {
      this.hover.set(false);
    }
  },
  init: function() {
    this.hover = new basis.Token(false);
    Node.prototype.init.call(this);
  },
  destroy: function() {
    this.hover.destroy();
    this.hover = null;
    Node.ptototype.destroy.call(this);
  }
});

function nestedFactory(x, y, size, text) {
  if (size <= targetSize) {
    return new Dot({
      data: {
        x: x - (targetSize / 2),
        y: y - (targetSize / 2),
        size: targetSize,
        text: text
      }
    });
  }

  size /= 2;

  return [].concat(
    nestedFactory(x, y - (size / 2), size, text),
    nestedFactory(x - size, y + (size / 2), size, text),
    nestedFactory(x + size, y + (size / 2), size, text)
  );
}

function update() {
  elapsed.set(new Date().getTime() - start);
  requestAnimationFrame(update);
}
update();

var app = new...