React/Redux + Fabric.js

by teqoz

HTML

<!-- 
	Please use Redux DevTools for Chrome or Firefox to see the store changes and time traveling
	https://github.com/zalmoxisus/redux-devtools-extension
	Inspired by https://jsfiddle.net/STHayden/2pncoLb5/
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.4/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.5/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.js"></script>
<div id="container">
</div>

Babel + JSX

// don't be scared, just some initial objects to play with (fabric's serialized JSON)
const initialState = {
   canvasObject: {
      "objects": [{
         "type": "circle",
         "originX": "center",
         "originY": "center",
         "left": 50,
         "top": 50,
         "width": 100,
         "height": 100,
         "fill": "#FF00FF",
         "stroke": null,
         "strokeWidth": 1,
         "strokeDashArray": null,
         "strokeLineCap": "butt",
         "strokeLineJoin": "miter",
         "strokeMiterLimit": 10,
         "scaleX": 1,
         "scaleY": 1,
         "angle": 0,
         "flipX": false,
         "flipY": false,
         "opacity": 1,
         "shadow": null,
         "visible": true,
         "clipTo": null,
         "backgroundColor": "",
         "fillRule": "nonzero",
         "globalCompositeOperation": "source-over",
         "transformMatrix": null,
         "radius": 50,
         "startAngle": 0,
         "endAngle": 6.283185307179586
      }, {
         "type": "rect",
         "originX": "center",
         "originY": "center",
         "left": 126,
         "top": 210,
         "width": 100,
         "height": 100,
         "fill": "#FF0000",
         "stroke": null,
         "strokeWidth": 1,
         "strokeDashArray": null,
         "strokeLineCap": "butt",
         "strokeLineJoin": "miter",
         "strokeMiterLimit": 10,
         "scaleX": 1,
         "scaleY": 1,
         "angle": 0,
         "flipX": false,
         "flipY": false,
         "opacity": 1,
         "shadow": null,
         "visible": true,
         "clipTo": null,
         "backgroundColor": "",
         "fillRule": "nonzero",
         "globalCompositeOperation": "source-over",
         "transformMatrix": null,
         "radius": 50,
         "startAngle": 0,
         "endAngle": 6.283185307179586
      }, {
         "type": "triangle",
         "originX": "center",
         "originY": "center",
         "left": 250,
         "top": 100,
       ...