forked from mirrors/easyappointments
303 lines
11 KiB
JavaScript
303 lines
11 KiB
JavaScript
;(function ($) {
|
|
'use strict';
|
|
|
|
var defaultOptions = {
|
|
minSize: 32,
|
|
step: 4
|
|
};
|
|
|
|
function preventDefault(e) {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
}
|
|
|
|
var ResizeWithCanvas = function () {
|
|
// variable to create canvas and save img in resize mode
|
|
this.resizeCanvas = document.createElement('canvas');
|
|
// to allow canvas to get focus
|
|
this.resizeCanvas.setAttribute('tabindex', '0');
|
|
this.resizeCanvas.id = 'trumbowyg-resizimg-' + (+new Date());
|
|
this.ctx = null;
|
|
this.resizeImg = null;
|
|
|
|
this.pressEscape = function (obj) {
|
|
obj.reset();
|
|
};
|
|
this.pressBackspaceOrDelete = function (obj) {
|
|
$(obj.resizeCanvas).replaceWith('');
|
|
obj.resizeImg = null;
|
|
};
|
|
|
|
// PRIVATE FUNCTION
|
|
var focusedNow = false;
|
|
var isCursorSeResize = false;
|
|
|
|
// calculate offset to change mouse over square in the canvas
|
|
var offsetX, offsetY;
|
|
var reOffset = function (canvas) {
|
|
var BB = canvas.getBoundingClientRect();
|
|
offsetX = BB.left;
|
|
offsetY = BB.top;
|
|
};
|
|
|
|
var drawRect = function (shapeData, ctx) {
|
|
// Inner
|
|
ctx.beginPath();
|
|
ctx.fillStyle = 'rgb(255, 255, 255)';
|
|
ctx.rect(shapeData.points.x, shapeData.points.y, shapeData.points.width, shapeData.points.height);
|
|
ctx.fill();
|
|
ctx.stroke();
|
|
};
|
|
|
|
var updateCanvas = function (canvas, ctx, img, canvasWidth, canvasHeight) {
|
|
ctx.translate(0.5, 0.5);
|
|
ctx.lineWidth = 1;
|
|
|
|
// image
|
|
ctx.drawImage(img, 5, 5, canvasWidth - 10, canvasHeight - 10);
|
|
|
|
// border
|
|
ctx.beginPath();
|
|
ctx.rect(5, 5, canvasWidth - 10, canvasHeight - 10);
|
|
ctx.stroke();
|
|
|
|
// square in the angle
|
|
ctx.beginPath();
|
|
ctx.fillStyle = 'rgb(255, 255, 255)';
|
|
ctx.rect(canvasWidth - 10, canvasHeight - 10, 9, 9);
|
|
ctx.fill();
|
|
ctx.stroke();
|
|
|
|
// get the offset to change the mouse cursor
|
|
reOffset(canvas);
|
|
|
|
return ctx;
|
|
};
|
|
|
|
// PUBLIC FUNCTION
|
|
// necessary to correctly print cursor over square. Called once for instance. Useless with trumbowyg.
|
|
this.init = function () {
|
|
var _this = this;
|
|
$(window).on('scroll resize', function () {
|
|
_this.reCalcOffset();
|
|
});
|
|
};
|
|
|
|
this.reCalcOffset = function () {
|
|
reOffset(this.resizeCanvas);
|
|
};
|
|
|
|
this.canvasId = function () {
|
|
return this.resizeCanvas.id;
|
|
};
|
|
|
|
this.isActive = function () {
|
|
return this.resizeImg !== null;
|
|
};
|
|
|
|
this.isFocusedNow = function () {
|
|
return focusedNow;
|
|
};
|
|
|
|
this.blurNow = function () {
|
|
focusedNow = false;
|
|
};
|
|
|
|
// restore image in the HTML of the editor
|
|
this.reset = function () {
|
|
if (this.resizeImg === null) {
|
|
return;
|
|
}
|
|
|
|
this.resizeImg.width = this.resizeCanvas.clientWidth - 10;
|
|
this.resizeImg.height = this.resizeCanvas.clientHeight - 10;
|
|
// clear style of image to avoid issue on resize because this attribute have priority over width and height attribute
|
|
this.resizeImg.removeAttribute('style');
|
|
|
|
$(this.resizeCanvas).replaceWith($(this.resizeImg));
|
|
|
|
// reset canvas style
|
|
this.resizeCanvas.removeAttribute('style');
|
|
this.resizeImg = null;
|
|
};
|
|
|
|
// setup canvas with points and border to allow the resizing operation
|
|
this.setup = function (img, resizableOptions) {
|
|
this.resizeImg = img;
|
|
|
|
if (!this.resizeCanvas.getContext) {
|
|
return false;
|
|
}
|
|
|
|
focusedNow = true;
|
|
|
|
// draw canvas
|
|
this.resizeCanvas.width = $(this.resizeImg).width() + 10;
|
|
this.resizeCanvas.height = $(this.resizeImg).height() + 10;
|
|
this.resizeCanvas.style.margin = '-5px';
|
|
this.ctx = this.resizeCanvas.getContext('2d');
|
|
|
|
// replace image with canvas
|
|
$(this.resizeImg).replaceWith($(this.resizeCanvas));
|
|
|
|
updateCanvas(this.resizeCanvas, this.ctx, this.resizeImg, this.resizeCanvas.width, this.resizeCanvas.height);
|
|
|
|
// enable resize
|
|
$(this.resizeCanvas).resizable(resizableOptions)
|
|
.on('mousedown', preventDefault);
|
|
|
|
var _this = this;
|
|
$(this.resizeCanvas)
|
|
.on('mousemove', function (e) {
|
|
var mouseX = Math.round(e.clientX - offsetX);
|
|
var mouseY = Math.round(e.clientY - offsetY);
|
|
|
|
var wasCursorSeResize = isCursorSeResize;
|
|
|
|
_this.ctx.rect(_this.resizeCanvas.width - 10, _this.resizeCanvas.height - 10, 9, 9);
|
|
isCursorSeResize = _this.ctx.isPointInPath(mouseX, mouseY);
|
|
if (wasCursorSeResize !== isCursorSeResize) {
|
|
this.style.cursor = isCursorSeResize ? 'se-resize' : 'default';
|
|
}
|
|
})
|
|
.on('keydown', function (e) {
|
|
if (!_this.isActive()) {
|
|
return;
|
|
}
|
|
|
|
var x = e.keyCode;
|
|
if (x === 27) { // ESC
|
|
_this.pressEscape(_this);
|
|
} else if (x === 8 || x === 46) { // BACKSPACE or DELETE
|
|
_this.pressBackspaceOrDelete(_this);
|
|
}
|
|
})
|
|
.on('focus', preventDefault);
|
|
|
|
this.resizeCanvas.focus();
|
|
|
|
return true;
|
|
};
|
|
|
|
// update the canvas after the resizing
|
|
this.refresh = function () {
|
|
if (!this.resizeCanvas.getContext) {
|
|
return;
|
|
}
|
|
|
|
this.resizeCanvas.width = this.resizeCanvas.clientWidth;
|
|
this.resizeCanvas.height = this.resizeCanvas.clientHeight;
|
|
updateCanvas(this.resizeCanvas, this.ctx, this.resizeImg, this.resizeCanvas.width, this.resizeCanvas.height);
|
|
};
|
|
};
|
|
|
|
// object to interact with canvas
|
|
var resizeWithCanvas = new ResizeWithCanvas();
|
|
|
|
function destroyResizable(trumbowyg) {
|
|
// clean html code
|
|
trumbowyg.$ed.find('canvas.resizable')
|
|
.resizable('destroy')
|
|
.off('mousedown', preventDefault)
|
|
.removeClass('resizable');
|
|
|
|
resizeWithCanvas.reset();
|
|
|
|
trumbowyg.syncCode();
|
|
}
|
|
|
|
$.extend(true, $.trumbowyg, {
|
|
plugins: {
|
|
resizimg: {
|
|
init: function (trumbowyg) {
|
|
trumbowyg.o.plugins.resizimg = $.extend(true, {},
|
|
defaultOptions,
|
|
trumbowyg.o.plugins.resizimg || {},
|
|
{
|
|
resizable: {
|
|
resizeWidth: false,
|
|
onDragStart: function (ev, $el) {
|
|
var opt = trumbowyg.o.plugins.resizimg;
|
|
var x = ev.pageX - $el.offset().left;
|
|
var y = ev.pageY - $el.offset().top;
|
|
if (x < $el.width() - opt.minSize || y < $el.height() - opt.minSize) {
|
|
return false;
|
|
}
|
|
},
|
|
onDrag: function (ev, $el, newWidth, newHeight) {
|
|
var opt = trumbowyg.o.plugins.resizimg;
|
|
if (newHeight < opt.minSize) {
|
|
newHeight = opt.minSize;
|
|
}
|
|
newHeight -= newHeight % opt.step;
|
|
$el.height(newHeight);
|
|
return false;
|
|
},
|
|
onDragEnd: function () {
|
|
// resize update canvas information
|
|
resizeWithCanvas.refresh();
|
|
trumbowyg.syncCode();
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
function initResizable() {
|
|
trumbowyg.$ed.find('img')
|
|
.off('click')
|
|
.on('click', function (e) {
|
|
// if I'm already do a resize, reset it
|
|
if (resizeWithCanvas.isActive()) {
|
|
resizeWithCanvas.reset();
|
|
}
|
|
// initialize resize of image
|
|
resizeWithCanvas.setup(this, trumbowyg.o.plugins.resizimg.resizable);
|
|
|
|
preventDefault(e);
|
|
});
|
|
}
|
|
|
|
trumbowyg.$c.on('tbwinit', function () {
|
|
initResizable();
|
|
|
|
// disable resize when click on other items
|
|
trumbowyg.$ed.on('click', function (e) {
|
|
// check if I've clicked out of canvas or image to reset it
|
|
if ($(e.target).is('img') || e.target.id === resizeWithCanvas.canvasId()) {
|
|
return;
|
|
}
|
|
|
|
preventDefault(e);
|
|
resizeWithCanvas.reset();
|
|
|
|
// save changes
|
|
trumbowyg.$c.trigger('tbwchange');
|
|
});
|
|
|
|
trumbowyg.$ed.on('scroll', function () {
|
|
resizeWithCanvas.reCalcOffset();
|
|
});
|
|
});
|
|
|
|
trumbowyg.$c.on('tbwfocus tbwchange', initResizable);
|
|
trumbowyg.$c.on('tbwresize', function () {
|
|
resizeWithCanvas.reCalcOffset();
|
|
});
|
|
|
|
// Destroy
|
|
trumbowyg.$c.on('tbwblur', function () {
|
|
// if I have already focused the canvas avoid destroy
|
|
if (resizeWithCanvas.isFocusedNow()) {
|
|
resizeWithCanvas.blurNow();
|
|
} else {
|
|
destroyResizable(trumbowyg);
|
|
}
|
|
});
|
|
},
|
|
destroy: function (trumbowyg) {
|
|
destroyResizable(trumbowyg);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
})(jQuery);
|