Snapping object to grid
by Hooman Askari
HTML
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
CSS
canvas {
border: 1px solid #ccc;
}
JavaScript
// Build using FabricJS v3.4
var canvas = new fabric.Canvas('c', { selection: false });
var snapSize = 20;
var gridSize = 20;
// create grid
for (var i = 0; i < (600 / gridSize); i++) {
canvas.add(new fabric.Line([ i * gridSize, 0, i * gridSize, 600], { stroke: '#ccc', selectable: false }));
canvas.add(new fabric.Line([ 0, i * gridSize, 600, i * gridSize], { stroke: '#ccc', selectable: false }))
}
// add objects
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
}));
function Snap(value) {
return Math.round(value / snapSize) * snapSize;
}
function SnapMoving(options) {
options.target.set({
left: Snap(options.target.left),
top: Snap(options.target.top)
});
}
function SnapScaling(options) {
var target = options.target;
var pointer = options.pointer;
var px = Snap(pointer.x);
var py = Snap(pointer.y);
var rx = (px - target.left) / target.width;
var by = (py - target.top) / target.height;
var lx = (target.left - px + (target.width * target.scaleX)) / (target.width);
var ty = (target.top - py + (target.height * target.scaleY)) / (target.height);
var a = {};
// Cannot get snap to work on some corners :-(
switch (target.__corner)
{
case "tl":
// Not working
//a = { scaleX: lx, scaleY: ty, left: px, top: py };
break;
case "mt":
a = { scaleY: ty, top: py };
break;
case "tr":
// Not working
//a = { scaleX: rx, scaleY: ty, top: py };
break;
case "ml":
a = { scaleX: lx, left: px };
break;
case "mr":
a = { scaleX: rx };
break;
case "bl":
// Not working
//a = { scaleX: lx, scaleY: by, left: px };
break;
case "mb":
a = { scaleY: by...