Skip to content

Instantly share code, notes, and snippets.

@bcruddy
Last active September 16, 2016 15:02
Show Gist options
  • Save bcruddy/6080258c496e91f325ea4c161b58a930 to your computer and use it in GitHub Desktop.
Save bcruddy/6080258c496e91f325ea4c161b58a930 to your computer and use it in GitHub Desktop.
var canvasDragCrop = {
_defaults: {
CANVAS_MIN_WIDTH: 100,
CANVAS_MIN_HEIGHT: 100
},
init: function (canvas, options) {
if (options === void 0) { options = {}; }
var _options = $.extend(this._defaults, options);
this.canvas = canvas;
this.canvasHeight = canvas.getHeight();
this.canvasWidth = cavnvas.getWidth();
this.CANVAS_MIN_WIDTH = _options.CANVAS_MIN_WIDTH;
this.CANVAS_MIN_HEIGHT = _options.CANVAS_MIN_HEIGHT;
this.setupCanvasDragControls();
}
setupCanvasDragControls: function () {
var $corner = $('<span>').addClass('canvas-drag-resizer');
var cornerCoords = [
{ top: this.canvasHeight / 2, left: -5, control: 'left' },
{ top: this.canvasHeight / 2, left: this.canvasWidth - 5, control: 'right' },
{ top: -5, left: this.canvasWidth / 2, control: 'top' }, // top is the same as adjusting the bottom but confusing so lets comment it out until we find a better solution
{ top: -5, left: this.canvasWidth - 5, control: 'top-right' },
{ top: -5, left: -5, control: 'top-left' },
{ top: this.canvasHeight - 5, left: this.canvasWidth / 2, control: 'bottom' },
{ top: this.canvasHeight - 5, left: this.canvasWidth - 5, control: 'bottom-right' },
{ top: this.canvasHeight - 5, left: -5, control: 'bottom-left' }
];
cornerCoords.forEach(function (c) {
$corner
.clone()
.css({ top: c.top, left: c.left })
.attr('data-control', c.control)
.appendTo('.canvas-container');
});
canvasDragCrop.canvasDragResize();
},
// resize the canvas based on drag controls
// since the canvas is relatively positioned (and fabric wraps it in .canvas-container,
// the canvas is actually two canvases) and it's parent is text-align: center, the canvas sits at the top of the container in the middle (duh).
// In order to resize it with a seeming "crop" effect, we need to position the canvas absolutely for
// top, left, and right - the bottom is fine as it will stay in place on its own.
// top and left are special cases because we also need to reposition all of the elements on the canvas to give the crop effect.
canvasDragResize: function () {
var $document = $(document);
var $controls = $('.canvas-drag-resizer');
var has = function (str, partial) {
return str.indexOf(partial) > -1;
};
var $container = $('.canvas-container');
var container = $container[0];
var rect = container.getBoundingClientRect();
var ctx = canvasDragCrop.canvas.getContext();
$document.mousedown(function (mouseDownEvent) {
var $target = $(mouseDownEvent.originalEvent.target);
if (!$target.hasClass('canvas-drag-resizer')) { return; }
var control = $target.data('control');
$document.mousemove(function (mouseMoveEvent) {
var e = mouseMoveEvent.originalEvent;
rect = container.getBoundingClientRect();
var nextHeight = 0;
if (has(control, 'top')) {
nextHeight = rect.height - e.movementY;
if (nextHeight >= canvasDragCrop.CANVAS_MIN_HEIGHT) {
$container.css({ position: 'absolute', left: rect.left, top: e.y, height: nextHeight });
canvasDragCrop.canvas.setHeight(nextHeight);
canvasDragCrop.canvas.forEachObject(function (o) {
var originY = o.get('originY');
o.set('originY', 'top');
var top = o.get('top');
o.set('top', top - e.movementY);
o.render(ctx);
o.set('originY', originY);
});
}
}
if (has(control, 'bottom')) {
nextHeight = canvasDragCrop.canvas.getHeight() + e.movementY;
if (nextHeight >= canvasDragCrop.CANVAS_MIN_HEIGHT) {
canvasDragCrop.canvas.setHeight(nextHeight);
}
}
var nextWidth = 0;
if (has(control, 'left')) {
nextWidth = canvasDragCrop.canvas.getWidth() - e.movementX;
if (nextWidth >= canvasDragCrop.CANVAS_MIN_WIDTH) {
canvasDragCrop.canvas.setWidth(nextWidth);
$container.css({ position: 'absolute', left: rect.left + e.movementX, right: rect.left + rect.width });
canvasDragCrop.canvas.forEachObject(function (o) {
var originX = o.get('originX');
o.set('originX', 'left');
var left = o.get('left');
o.set('left', left - e.movementX);
o.render(ctx);
o.set('originX', originX);
});
}
}
if (has(control, 'right')) {
nextWidth = canvasDragCrop.canvas.getWidth() + e.movementX;
if (nextWidth >= canvasDragCrop.CANVAS_MIN_WIDTH) {
canvasDragCrop.canvas.setWidth(nextWidth);
$container.css({ position: 'absolute', left: rect.left });
}
}
canvasDragCrop.canvasHeight = canvasDragCrop.canvas.getHeight();
canvasDragCrop.canvasWidth = canvasDragCrop.canvas.getWidth();
canvasDragCrop.canvas.renderAll();
canvasDragCrop.updateCanvasDragControls();
});
});
$document.mouseup(function () {
$document.off('mousemove');
canvasDragCrop.updateCanvasDragControls();
offset = $container.offset();
$container.css({ position: 'relative', left: 'unset', top: 'unset', right: 'unset', bottom: 'unset', 'margin-top': 'unset', width: designer.canvas.getWidth(), height: designer.canvas.getHeight() });
canvasDragCrop.canvas.forEachObject(function (o) {
o.setCoords();
});
});
},
updateCanvasDragControls: function () {
var width = canvasDragCrop.canvas.getWidth();
var height = canvasDragCrop.canvas.getHeight();
$('.canvas-drag-resizer[data-control="top"]').css({
'left': (width / 2) + 'px',
'top': '-5px'
});
$('.canvas-drag-resizer[data-control="bottom"]').css({
'left': (width / 2) + 'px',
'top': (height - 5) + 'px'
});
$('.canvas-drag-resizer[data-control="left"]').css({
'left': '-5px',
'top': (height / 2) + 'px'
});
$('.canvas-drag-resizer[data-control="right"]').css({
'left': (width - 5) + 'px',
'top': (height / 2) + 'px'
});
$('.canvas-drag-resizer[data-control="bottom-right"]').css({
'left': (width - 5) + 'px',
'top': (height - 5) + 'px'
});
$('.canvas-drag-resizer[data-control="bottom-left"]').css({
'left': '-5px',
'top': (height - 5) + 'px'
});
$('.canvas-drag-resizer[data-control="top-right"]').css({
'left': (width - 5) + 'px',
'top': '-5px'
});
$('.canvas-drag-resizer[data-control="top-left"]').css({
'left': '-5px',
'top': '-5px'
});
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment