JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
<button>Dorito</button>
CSS
canvas {
border: 1px solid #ccc;
}
JavaScript
var canvas = new fabric.Canvas('c', {
selection: false
});
var grid = 50;
for (var i = 0; i < (600 / grid); i++) {
canvas.add(new fabric.Line([i * grid, 0, i * grid, 600], {
stroke: '#ccc',
selectable: false
}));
canvas.add(new fabric.Line([0, i * grid, 600, i * grid], {
stroke: '#ccc',
selectable: false
}))
}
canvas.add(new fabric.Rect({
left: 100,
top: 100,
width: 50,
height: 50,
fill: '#faa',
originX: 'left',
originY: 'top',
centeredRotation: true
}));
canvas.add(new fabric.Circle({
left: 300,
top: 300,
radius: 50,
fill: '#9f9',
originX: 'left',
originY: 'top',
centeredRotation: true
}));
canvas.on('object:moving', function(options) {
options.target.set({
left: Math.round(options.target.left / grid) * grid,
top: Math.round(options.target.top / grid) * grid
});
});
canvas.on("object:modified", function(modEvtData) {
var modifiedObj = modEvtData.target;
if (modifiedObj.angle) {
modifiedObj.straighten();
canvas.renderAll();
}
});
/*
canvas.on("object:modified", function(modEvtData) {
var modifiedObj = modEvtData.target;
if (modifiedObj.angle && snapAfterRotate) {
modifiedObj.setAngle(lastClosestAngle).setCoords();
snapAfterRotate = false;
canvas.renderAll();
}
});
var lastClosestAngle = 0;
var snapAfterRotate = false;
function calculateClosestAngle(targetObj) {
var currentAngle = targetObj.angle.toFixed(0);
snapAfterRotate = true;
if (currentAngle >= 45 && currentAngle < 135) {
return 90;
} else if (currentAngle >= 135 && currentAngle < 225) {
return 180;
} else if (currentAngle >= 225 && currentAngle < 315) {
return 270;
} else if ((currentAngle >= 315 && currentAngle <= 360) || (currentAngle >= 0 && currentAngle < 45)) {
return 0;
}
return currentAngle;
}
canvas.on("object:rotating", function(rotEvtData) {
var targetObj = rotEvtData.target;
lastClosestAngle = calculateClosestAngle(targetObj);
});
*/