JSFiddle - React, Tailwind, and code Playground
by vmachan
HTML
<script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.14/d3.min.js"></script>
<body>
<div id="main" style="width: 1000px; overflow: hidden;">
<div id="drawarea" style="width: 800px; background-color: #FFEEFF; float: left;">
<canvas id="canvas"
width="800"
height="600"
style="border:1px solid #000000;">
</canvas>
</div>
<div id="sidebar" align="center" style="width: 160px; background-color: #EEEEEE; float: left; margin-left: 10px;">
<input id="createBox" type="button" name="btnCreateBox" value="Add box" />
<input id="createCircle" type="button" name="btnCreateCircle" value="Add circle" />
<input id="addChildWithPolyLine" type="button" name="btnAddChildWithPolyLine" value="Add child with Polyline" />
<hr/>
<input id="showObject" type="button" name="btnShowObject" value="Show selected object" />
<input id="renderAll" type="button" name="btnRenderAll" value="Render All" />
<input id="dumpCanvasObj" type="button" name="btnDumpCanvasObj" value="Dump canvas object" />
<hr/>
<input id="undoMod" type="button" name="btnUndoMod" value="Undo" />
<input id="redoMod" type="button" name="btnRedoMod" value="Redo" />
<hr/>
<input id="showSavedState" type="button" name="btnShowSavedState" value="Show Saved State" />
<hr/>
<label id="cursor"></label>
<hr/>
<label id="mousePos"></label>
<hr/>
<label id="objPos"></label>
</div>
<div class="rightClickMenu" id="rightClickMenu">
<ul>
...
CSS
.rightClickMenu
{
position:absolute;
display: none;
width: 80px;
margin: 0;
padding: 0;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.35);
border-radius: 4px;
font-family: Lucida Grande;
font-size: 14px;
line-height: 15px;
}
.rightClickMenu ul
{
list-style: none;
margin: 0;
padding: 0;
}
.rightClickMenu li
{
width: 80px;
color:#fff;
border:none;
background: rgba(255, 255, 255, 0.95);
box-shadow: 0px 8px 15px rgba(0, 0, 0, 0.35);
border-radius: 4px;
padding: 3px 5px 4px;
}
.rightClickMenu li:first-child
{
width: 80px;
margin: 0;
padding: 3px 5px 4px;
}
.rightClickMenu a
{
color: 'darkgray';
text-decoration: none;
display: block;
margin: 0;
padding: 3px 0 4px;
}
.rightClickMenu a:hover
{
background: -webkit-linear-gradient(top, #648bf5, #2866f2);
background: linear-gradient(to bottom, #648bf5 0%, #2866f2 100%);
border-top: 1px solid #5a82eb;
border-bottom: 1px solid #1758e7;
color: #fff;
}
menu rightClickMenu a:hover::after {
color: #fff;
}
JavaScript
['object:moving', 'object:scaling', 'object:rotating'].forEach(mouseMovePolyLine);
var vertexFocus = null; // For showing polyline vertices when mouse moves over it
var gIsMouseAtVertex = null;
var gVertexSelected = false;
var gSelectedObject = null;
var gSelectedPointInPolyLine = null;
var gSaveHistory = true;
var gSavedStates = [];
var gObjectList = [];
var gUndoPtr = 0;
var canvas;
var gContextObj = null;
var curX, curY;
var MAX_UNDO = 10;
var MIN_UNDO = 1;
$('canvas').bind('contextmenu', function (env)
{
// console.log("right clicked");
var objectFound = false;
var clickPoint = new fabric.Point(env.offsetX, env.offsetY);
env.preventDefault();
canvas.forEachObject(function (obj)
{
if (!objectFound && obj.containsPoint(clickPoint))
{
objectFound = true;
var cnvsPos = $('canvas').offset();
curX = env.clientX;
curY = env.clientY;
$('#rightClickMenu').css({'top': curY, 'left': curX}).fadeIn('slow');
gContextObj = obj;
}
});
return false; //stops the event propigation
});
function Point(x, y) {
this.x = x;
this.y = y;
}
function guid()
{
function s4()
{
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
}
function getGlobalCoordinates(thisObj, thisParent)
{
var gX = thisParent.getCenterPoint().x + thisObj.x;
var gY = thisParent.getCenterPoint().y + thisObj.y;
return (new Point(gX, gY));
...