JSFiddle - React, Tailwind, and code Playground

by egon

HTML

<title>Ribbons</title>
<canvas id="ribbons" width="640" height="480"></canvas>   
<script src="main.js"></script>

CSS

html, body { background: #fff; }
#ribbons { border: 1px solid #000; }

JavaScript

(function () {
  'use strict';

  function Ribbon() {
    this.id = uuid();
    this.RibbonPath = new RibbonPath();
    this.RibbonStyle = new RibbonStyle();
  }

  function RibbonPath(){
    this.points = [];
    this.closed = false;
  }
  RibbonPath.prototype = {
    manhattan: function(a, b){
      return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
    },
    add: function(p){
      if(this.points.length == 0){
        this.points.push(p);
        return;
      }

      var last = this.points[this.points.length-1];
      if(this.manhattan(last, p) > 10 ){
         this.points.push(p);
      }
    },
    close: function(){
      this.closed = true;
    }
  };

  function RibbonStyle(){
    this.color = "hsla(" + ((Math.random()*360)|0) + ", 60%, 60%, 1)";
    this.width = 4;
  }

  var canvas = document.getElementById("ribbons");
  var context = canvas.getContext("2d");

  var Engine = {
    realtime: 0.0,
    time: 0.0,

    canvas: canvas,
    context: context,
    entity: {
      list: {},
      byId: function(id){
        return this.list[id];
      },
      add: function(en){
        this.list[en.id] = en;
        return en.id;
      },
      remove: function(id){
        delete this.list[id];
      },
      cmap: function(sys, fn){
        var args = argumentsOf(fn);
        for(var id in this.list){
          if(!this.list.hasOwnProperty(id)){ continue; }

          var en = this.list[id],
              components = [];
          for(var k = 0; k < args.length; k += 1){
            var c = en[args[k]];
            if(c == null){
              break
            }
            components.push(c);
          }

          if(components.length != args.length){
            continue;
          }

          fn.apply(sys, components);
        }
      }
    },
    systems: [],

    render: function(){
      var context = this.context;

      context.fillStyle = "hsla(0,100%,100%,0.2)";
      context.fillRect(0, 0, canvas.width, canvas.height);

     ...