@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,306 lines (1,145 loc) • 52.5 kB
JavaScript
import './kendo.dropdownlist.js';
import './kendo.toolbar.js';
import './kendo.core.js';
import './kendo.form.js';
import './kendo.html.button.js';
import './kendo.buttongroup.js';
import './kendo.draganddrop.js';
import './kendo.upload.js';
import './kendo.list.js';
import './kendo.data.js';
import './kendo.data.odata.js';
import './kendo.licensing.js';
import '@progress/kendo-licensing';
import './kendo.data.xml.js';
import './kendo.popup.js';
import './kendo.label.js';
import './kendo.floatinglabel.js';
import './kendo.icons.js';
import './kendo.html.icon.js';
import './kendo.html.base.js';
import '@progress/kendo-svg-icons';
import './kendo.actionsheet.js';
import './dropdowns-loader-00xUvouJ.js';
import './kendo.mobile.scroller.js';
import './kendo.fx.js';
import './kendo.userevents.js';
import './kendo.virtuallist.js';
import './valueMapper-CXgI6HWc.js';
import './kendo.splitbutton.js';
import './kendo.button.menu.js';
import './kendo.dropdownbutton.js';
import './kendo.menu.js';
import './kendo.togglebutton.js';
import './kendo.button.js';
import './kendo.badge.js';
import './kendo.editable.js';
import './kendo.checkbox.js';
import './kendo.toggleinputbase.js';
import './kendo.html.input.js';
import './kendo.datepicker.js';
import './kendo.calendar.js';
import './kendo.selectable.js';
import './kendo.dateinput.js';
import '@progress/kendo-dateinputs-common';
import './kendo.numerictextbox.js';
import './prefix-suffix-containers-B9VRe3lS.js';
import './kendo.textbox.js';
import './kendo.validator.js';
import './kendo.binder.js';
import './kendo.otpinput.js';
import './kendo.progressbar.js';
(function($, undefined$1) {
var kendo = window.kendo,
extend = $.extend,
Class = kendo.Class,
NS = ".k-imageeditor-pane",
CLICK = "click";
var paneStyles = {
form: "k-imageeditor-pane-form",
cropOverlay: "k-imageeditor-crop-overlay",
crop: "k-imageeditor-crop",
resizeHandle: "k-resize-handle",
resizeHandlePrefix: "k-resize-"
};
const paneButtonSelector = "[ref-pane-button]";
var round = function(f) {
return Math.round(f * 1000) / 1000;
};
var Pane = Class.extend({
init: function(imageeditor) {
var that = this;
that.imageeditor = imageeditor;
if (that.imageeditor.currentPaneTool) {
that.imageeditor.currentPaneTool.destroy();
}
that.element = $("<div role='form' aria-label='Image edit pane.'></div>").addClass(paneStyles.form);
},
open: function() {
var that = this,
imageeditor = that.imageeditor,
commonMessages = imageeditor.options.messages.common;
imageeditor.paneWrapper.append(that.element);
that.formWidget = new kendo.ui.Form(that.element, extend(that.formSettings(), {
buttonsTemplate: () =>
kendo.html.renderButton(`<button ref-pane-button data-action='confirm'>${commonMessages.confirm}</button>`, {
icon: 'check',
themeColor: 'primary'
}) +
kendo.html.renderButton(`<button ref-pane-button data-action='cancel'>${commonMessages.cancel}</button>`, {
icon: 'cancel-outline'
})
}));
that.bindButtonEvents();
imageeditor.paneWrapper.show();
imageeditor.currentPaneTool = that;
},
bindButtonEvents: function() {
var that = this,
formWidget = that.formWidget,
buttons = formWidget.element.find(paneButtonSelector);
that._clickHandler = that._click.bind(that);
buttons.on(CLICK + NS, that._clickHandler);
},
_click: function(ev) {
var that = this,
target = $(ev.target).closest(paneButtonSelector),
action = target.data("action");
if (that[action]) {
that[action]();
}
},
cancel: function() {
this.imageeditor.toolbar.element.find("[tabindex=0]").trigger("focus");
this.destroy();
},
confirm: function() {
window.console.error("Pane's confirm method is not implemented!");
this.destroy();
},
refresh: function() {
},
destroy: function() {
var that = this,
imageeditor = that.imageeditor;
that.formWidget.element.find(paneButtonSelector).off(NS);
that.formWidget.destroy();
imageeditor.paneWrapper.html("");
imageeditor.paneWrapper.hide();
delete imageeditor.currentPaneTool;
}
});
var CropPane = Pane.extend({
init: function(imageeditor) {
var that = this;
Pane.fn.init.call(that, imageeditor);
that.buildCropModel();
that.canvasUI();
},
confirm: function() {
var that = this,
model = that.formWidget._model.toJSON();
that.destroy();
that.imageeditor.executeCommand({ command: "CropImageEditorCommand", options: model });
},
formSettings: function() {
var that = this,
cropMessages = that.imageeditor.options.messages.panes.crop,
commonMessages = that.imageeditor.options.messages.common,
aspectRatioItems = cropMessages.aspectRatioItems,
aspectRatioDS = [];
if (aspectRatioItems) {
for (var key in aspectRatioItems) {
aspectRatioDS.push({ value: key, text: aspectRatioItems[key] });
}
} else {
aspectRatioDS = [
{ value: "originalRatio", text: "Original ratio" },
{ value: "1:1", text: "1:1 (Square)" },
{ value: "4:5", text: "4:5 (8:10)" },
{ value: "5:7", text: "5:7" },
{ value: "2:3", text: "2:3 (4:6)" },
{ value: "16:9", text: "16:9" }
];
}
return {
formData: that._model,
change: that.onChange.bind(that),
items: [{
type: "group",
label: cropMessages.title || "Crop Image",
layout: "grid",
grid: { cols: 2, gutter: "0 8px" },
items: [{
label: cropMessages.aspectRatio || "Aspect ratio:",
field: "aspectRatio",
editor: "DropDownList",
editorOptions: {
dataValueField: "value",
dataTextField: "text",
dataSource: aspectRatioDS
},
colSpan: 2
}, {
label: cropMessages.orientation,
field: "orientation",
editor: that._orientationEditor.bind(that),
colSpan: 2
}, {
label: commonMessages.width || "Width:",
field: "width",
attributes: { style: "max-width: 100px;" },
editor: "NumericTextBox",
editorOptions: {
format: "n0",
max: that._model.width,
min: 0
},
colSpan: 1
}, {
label: commonMessages.height || "Height:",
field: "height",
attributes: { style: "max-width: 100px;" },
editor: "NumericTextBox",
editorOptions: {
format: "n0",
max: that._model.height,
min: 0
},
colSpan: 1
}, {
label: commonMessages.lockAspectRatio || "Lock aspect ratio",
field: "lockAspectRatio",
colSpan: 2
}
]
}]
};
},
_orientationEditor: function(container, options) {
var that = this,
cropMessages = that.imageeditor.options.messages.panes.crop,
value = options.model[options.field];
that._orientationWidget = $("<div name='" + options.field + "'></div>")
.appendTo(container)
.kendoButtonGroup({
items: [
{ text: cropMessages.portrait || "Portrait", attributes: { "data-value": "portrait" }, selected: value === "portrait" },
{ text: cropMessages.landscape || "Landscape", attributes: { "data-value": "landscape" }, selected: value === "landscape" }
],
select: function(ev) {
var value = ev.sender.wrapper.find(".k-selected").data("value");
options.model.set(options.field, value);
}
}).data("kendoButtonGroup");
},
buildCropModel: function() {
var that = this,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement(),
width = canvas.width,
height = canvas.height;
that._model = {
top: 0,
left: 0,
aspectRatio: "originalRatio",
width: width,
height: height,
orientation: (width - height < 0) ? "portrait" : "landscape",
lockAspectRatio: true
};
},
canvasUI: function() {
var that = this,
imageeditor = that.imageeditor,
canvasContainer = that.imageeditor.canvasContainer,
cropOverlay = $("<div></div>").addClass(paneStyles.cropOverlay),
cropElement = $("<div></div>").addClass(paneStyles.crop),
handle = "<span class='" + paneStyles.resizeHandle + "'></span>",
handles = [ "nw", "n", "ne", "w", "e", "sw", "s", "se" ],
zoomLevel = imageeditor.getZoomLevel();
for (var i = 0; i < handles.length; i++) {
var handleElm = $(handle)
.addClass(paneStyles.resizeHandlePrefix + handles[i])
.attr("data-orientation", handles[i]);
that._initResizeHandle(handleElm);
cropElement.append(handleElm);
}
that.cropElement = cropElement;
that._canvasUI = cropOverlay
.append(cropElement)
.appendTo(canvasContainer);
var width = Math.round(that._model.width * zoomLevel);
var height = Math.round(that._model.height * zoomLevel);
var borderWidth = parseInt(that.cropElement.css("border-top-width"), 10);
that.cropElement.css({
width: width,
height: height,
backgroundImage: "url('" + imageeditor._image.src + "')",
backgroundSize: kendo.format("{0}px {1}px", width, height),
backgroundClip: "content-box",
backgroundPosition: kendo.format("-{0}px -{0}px", borderWidth)
});
that.cropElement.kendoDraggable({
ignore: "." + paneStyles.resizeHandle,
drag: function(ev) {
that._adjustTopLeft(ev.target.offsetTop + ev.y.delta, ev.target.offsetLeft + ev.x.delta);
}
});
},
refresh: function() {
var that = this,
newModel = that.formWidget._model,
zoomLevel = that.imageeditor.getZoomLevel(),
width = Math.round(newModel.width * zoomLevel),
height = Math.round(newModel.height * zoomLevel),
top = Math.round(newModel.top * zoomLevel),
left = Math.round(newModel.left * zoomLevel),
borderWidth = parseInt(that.cropElement.css("border-top-width"), 10);
that.cropElement.css({
top: top,
left: left,
width: width,
height: height,
backgroundSize: kendo.format("{0}px {1}px", that._model.width * zoomLevel, that._model.height * zoomLevel),
backgroundPosition: kendo.format("-{0}px -{1}px", left + borderWidth, top + borderWidth)
});
},
_initResizeHandle: function(handle) {
var that = this;
handle.kendoDraggable({
drag: function(ev) {
var $target = $(ev.sender.element),
newModel = that.formWidget._model,
oldModel = that._model,
orientation = $target.data("orientation"),
adjustments = {},
zoomLevel = that.imageeditor.getZoomLevel(),
correctedLeft = newModel.left * zoomLevel,
correctedTop = newModel.top * zoomLevel;
if (orientation.indexOf("w") >= 0) {
adjustments.left = that.cropElement[0].offsetLeft + ev.x.delta;
adjustments.width = that.cropElement[0].offsetWidth - ev.x.delta;
} else if (orientation.indexOf("e") >= 0) {
adjustments.width = that.cropElement[0].offsetWidth + ev.x.delta;
}
if (orientation.indexOf("n") >= 0) {
adjustments.top = that.cropElement[0].offsetTop + ev.y.delta;
adjustments.height = that.cropElement[0].offsetHeight - ev.y.delta;
} else if (orientation.indexOf("s") >= 0) {
adjustments.height = that.cropElement[0].offsetHeight + ev.y.delta;
}
if (adjustments.width && ((adjustments.left || correctedLeft) + adjustments.width <= oldModel.width * zoomLevel)) {
newModel.set("width", Math.round(adjustments.width / zoomLevel));
}
if (adjustments.height && ((adjustments.top || correctedTop) + adjustments.height <= oldModel.height * zoomLevel)) {
newModel.set("height", Math.round(adjustments.height / zoomLevel));
}
if (adjustments.top || adjustments.left) {
that._adjustTopLeft(adjustments.top, adjustments.left);
}
}
});
},
_adjustTopLeft: function(top, left, compare) {
var that = this,
compareModel = compare || that.formWidget._model,
newModel = that.formWidget._model,
oldModel = that._model,
zoomLevel = that.imageeditor.getZoomLevel();
if (top >= 0 && (top / zoomLevel) + compareModel.height <= oldModel.height) {
newModel.set("top", Math.round(top / zoomLevel));
}
if (left >= 0 && (left / zoomLevel) + compareModel.width <= oldModel.width) {
newModel.set("left", Math.round(left / zoomLevel));
}
},
onChange: function(ev) {
var that = this,
zoomLevel = that.imageeditor.getZoomLevel(),
newModel = ev.sender._model,
oldModel = that._model,
maxWidth = oldModel.width,
maxHeight = oldModel.height,
originalRatio = oldModel.width + ":" + oldModel.height,
gcd = that._gcd(oldModel.width, oldModel.height);
originalRatio = oldModel.width / gcd + ":" + oldModel.height / gcd;
if (ev.field === "aspectRatio" && ev.value === "originalRatio") {
newModel.set("top", 0);
newModel.set("left", 0);
newModel.set("orientation", oldModel.orientation);
newModel.set("width", oldModel.width);
newModel.set("height", oldModel.height);
} else if (ev.field === "orientation") {
var tempModel = extend({}, newModel, {
width: newModel.height,
height: newModel.width
});
var newSize = that._calcSize(tempModel, originalRatio, maxWidth, maxHeight);
newModel.set("width", newSize.width);
newModel.set("height", newSize.height);
that._orientationWidget.select(ev.value === "portrait" ? 0 : 1);
} else if (newModel.lockAspectRatio) {
var force = ev.field;
var size = that._calcSize(newModel, originalRatio, maxWidth, maxHeight, force);
newModel.set("width", size.width);
newModel.set("height", size.height);
}
var width = Math.round(newModel.width * zoomLevel);
var height = Math.round(newModel.height * zoomLevel);
var top = Math.round(newModel.top * zoomLevel);
var left = Math.round(newModel.left * zoomLevel);
var borderWidth = parseInt(that.cropElement.css("border-top-width"), 10);
that.cropElement.css({
top: top,
left: left,
width: width,
height: height,
backgroundPosition: kendo.format("-{0}px -{1}px", left + borderWidth, top + borderWidth)
});
},
_calcSize: function(model, originalRatio, maxWidth, maxHeight, force) {
var width = Math.min(model.width, maxWidth),
height = Math.min(model.height, maxHeight),
isPortrait = model.orientation === "portrait",
ratios = model.aspectRatio;
if (ratios.indexOf(":") < 0) {
ratios = originalRatio;
}
ratios = ratios.split(":").map(function(value) {
return parseInt(value, 10);
});
var wRatio = isPortrait ? Math.min(ratios[0], ratios[1]) : Math.max(ratios[0], ratios[1]);
var hRatio = !isPortrait ? Math.min(ratios[0], ratios[1]) : Math.max(ratios[0], ratios[1]);
var expectedRatio = round(wRatio / hRatio);
var realRatio = round(width / height);
var sizeByRatio = {
width: Math.round(height * expectedRatio),
height: Math.round(width / expectedRatio)
};
if (force === "width") {
return {
width: width,
height: sizeByRatio.height
};
}
if (force === "height") {
return {
width: sizeByRatio.width,
height: height
};
}
if (realRatio > expectedRatio) {
width = sizeByRatio.width;
} else if (realRatio < expectedRatio) {
height = sizeByRatio.height;
}
return {
width: width,
height: height
};
},
_gcd: function(a, b) {
return (b === 0) ? a : this._gcd (b, a % b);
},
destroy: function() {
kendo.destroy(this._canvasUI);
this._canvasUI.remove();
Pane.fn.destroy.call(this);
}
});
var ResizePane = Pane.extend({
init: function(imageeditor) {
Pane.fn.init.call(this, imageeditor);
this.buildResizeModel();
},
confirm: function() {
var that = this,
originalWidth = that._model.width,
originalHeight = that._model.height,
model = that.formWidget._model.toJSON();
if (model.measure === "percents") {
model.width = originalWidth * (model.width / 100);
model.height = originalHeight * (model.height / 100);
}
that.imageeditor.executeCommand({ command: "ResizeImageEditorCommand", options: model });
that.destroy();
},
formSettings: function() {
var that = this,
resizeMessages = that.imageeditor.options.messages.panes.resize,
commonMessages = that.imageeditor.options.messages.common;
return {
formData: that._model,
change: that.onChange.bind(that),
items: [{
type: "group",
label: resizeMessages.title || "Resize image",
layout: "grid",
grid: { cols: 2, gutter: "0 8px" },
items: [{
label: commonMessages.width || "Width:",
field: "width",
attributes: { style: "max-width: 100px;" },
editor: "NumericTextBox",
editorOptions: {
format: "n0",
min: 0
},
colSpan: 1
}, {
field: "measureW",
editor: "DropDownList",
attributes: { style: "max-width: 100px;" },
label: { text: " ", encoded: false },
editorOptions: {
dataTextField: "text",
dataValueField: "value",
dataSource: [
{ text: resizeMessages.pixels || "Pixels", value: "pixels" },
{ text: resizeMessages.percents || "Percents", value: "percents" }
]
},
colSpan: 1
}, {
label: commonMessages.height || "Height:",
field: "height",
attributes: { style: "max-width: 100px;" },
editor: "NumericTextBox",
editorOptions: {
format: "n0",
min: 0
},
colSpan: 1
}, {
field: "measureH",
label: { text: " ", encoded: false },
attributes: { style: "max-width: 100px;" },
editor: "DropDownList",
editorOptions: {
dataTextField: "text",
dataValueField: "value",
dataSource: [
{ text: resizeMessages.pixels || "Pixels", value: "pixels" },
{ text: resizeMessages.percents || "Percents", value: "percents" }
]
},
colSpan: 1
}, {
label: commonMessages.lockAspectRatio || "Lock aspect ratio",
field: "lockAspectRatio",
colSpan: 2
}]
}]
};
},
buildResizeModel: function() {
var that = this,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement(),
width = canvas.width,
height = canvas.height;
that._model = {
width: width,
height: height,
measure: "pixels",
measureW: "pixels",
measureH: "pixels",
lockAspectRatio: true,
ratio: round(width / height)
};
},
onChange: function(ev) {
var that = this,
newModel = ev.sender._model,
aspectRatioLocked = newModel.lockAspectRatio;
if (ev.field === "measureW" || ev.field === "measureH") {
newModel.set("measureW", ev.value);
newModel.set("measureH", ev.value);
newModel.set("measure", ev.value);
} else if (ev.field === "measure") {
that.resetNumericsTo(ev.value);
} else if (ev.field === "width" && aspectRatioLocked && !that._preventChange) {
newModel.set("height", newModel.width / newModel.ratio);
} else if (ev.field === "height" && aspectRatioLocked && !that._preventChange) {
newModel.set("width", newModel.height * newModel.ratio);
}
newModel.set("ratio", round(newModel.width / newModel.height));
},
resetNumericsTo: function(type) {
var that = this,
originalWidth = that._model.width,
originalHeight = that._model.height,
formWidget = that.formWidget,
model = formWidget._model,
widthNumeric = formWidget.element.find("[name=width]").data("kendoNumericTextBox"),
heightNumeric = formWidget.element.find("[name=height]").data("kendoNumericTextBox"),
isPercent = type === "percents",
options = {
percents: {
format: "#\\\%"
},
pixels: {
format: "n0"
}
};
widthNumeric.setOptions(options[type]);
heightNumeric.setOptions(options[type]);
that._preventChange = true;
model.set("width", isPercent ? (originalWidth / widthNumeric.value()) * 100 : originalWidth * (widthNumeric.value() / 100));
model.set("height", isPercent ? (originalHeight / heightNumeric.value()) * 100 : originalHeight * (heightNumeric.value() / 100));
that._preventChange = false;
}
});
extend(kendo.ui, {
imageeditor: {
ImageEditorPane: Pane,
panes: {
crop: CropPane,
resize: ResizePane
}
}
});
})(window.kendo.jQuery);
(function($, undefined$1) {
var kendo = window.kendo,
imageeditorNS = kendo.ui.imageeditor,
extend = $.extend,
Class = kendo.Class;
var Command = Class.extend({
init: function(options) {
this.options = extend({}, options, this.options);
this.imageeditor = options.imageeditor;
}
});
var OpenPaneImageEditorCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this,
imageeditor = that.imageeditor,
pane = new imageeditorNS.panes[that.options.value](imageeditor);
pane.open();
pane.element.find(":kendoFocusable").first().trigger("focus");
}
});
var ZoomImageEditorCommand = Command.extend({
options: {
zoomStep: 0.05,
spacing: 20
},
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this,
options = that.options,
value = options.value,
imageeditor = that.imageeditor,
imgHeight = imageeditor._image.height,
currentZoom = imageeditor.getZoomLevel(),
newHeight = imgHeight,
zoomInOut = value === "zoomIn" || value === "zoomOut";
if (!isNaN(value)) {
value = parseFloat(value);
} else if (typeof value === "string") {
value = that._processStringValue(value, currentZoom);
}
newHeight = Math.round(imgHeight * value);
if (newHeight > 0) {
$(imageeditor._canvas).css("height", newHeight);
imageeditor._zoomLevel = value;
}
if (imageeditor.currentPaneTool) {
imageeditor.currentPaneTool.refresh();
}
if (zoomInOut) {
imageeditor.toolbar.element.find("[tabindex=0]").trigger("focus");
}
},
_processStringValue: function(value, initialZoom) {
var that = this,
options = that.options,
imageeditor = that.imageeditor,
imgHeight = imageeditor._image.height,
expectedHeight = imageeditor.canvasWrapper.height() - options.spacing,
zoomStep = options.zoomStep;
switch (value) {
case "zoomIn":
return initialZoom + zoomStep;
case "zoomOut":
return initialZoom - zoomStep;
case "fitToScreen":
return Math.round((expectedHeight / imgHeight) * 100) / 100;
default:
return 1;
}
}
});
var CropImageEditorCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this,
options = that.options,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement(),
ctx = imageeditor.getCurrent2dContext(),
croppedImage = ctx.getImageData(options.left, options.top, options.width, options.height);
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = options.width;
canvas.height = options.height;
ctx.putImageData(croppedImage, 0, 0);
imageeditor.drawImage(canvas.toDataURL()).done(function(image) {
imageeditor.drawCanvas(image);
imageeditor.toolbar.element.find("[tabindex=0]").trigger("focus");
}).fail(function(ev) {
imageeditor.trigger("error", ev);
});
}
});
var ResizeImageEditorCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this,
options = that.options,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement(),
ctx = imageeditor.getCurrent2dContext(),
image = imageeditor.getCurrentImage();
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = options.width;
canvas.height = options.height;
ctx.drawImage(image, 0, 0, options.width, options.height);
imageeditor.drawImage(canvas.toDataURL()).done(function(image) {
imageeditor.drawCanvas(image);
imageeditor.toolbar.element.find("[tabindex=0]").trigger("focus");
}).fail(function(ev) {
imageeditor.trigger("error", ev);
});
}
});
var UndoImageEditorCommand = Command.extend({
exec: function() {
var that = this,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement(),
ctx = imageeditor.getCurrent2dContext(),
image = imageeditor.undoStack.pop();
if (image) {
imageeditor.redoStack.push(imageeditor.getCurrentImage());
delete imageeditor._image;
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
imageeditor.drawImage(canvas.toDataURL()).done(function(image) {
imageeditor.drawCanvas(image);
imageeditor.toolbar.element.find("[tabindex=0]").trigger("focus");
}).fail(function(ev) {
imageeditor.trigger("error", ev);
});
}
}
});
var RedoImageEditorCommand = Command.extend({
exec: function() {
var that = this,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement(),
ctx = imageeditor.getCurrent2dContext(),
image = imageeditor.redoStack.pop();
if (image) {
imageeditor.undoStack.push(imageeditor.getCurrentImage());
delete imageeditor._image;
ctx.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0, image.width, image.height);
imageeditor.drawImage(canvas.toDataURL()).done(function(image) {
imageeditor.drawCanvas(image);
imageeditor.toolbar.element.find("[tabindex=0]").trigger("focus");
}).fail(function(ev) {
imageeditor.trigger("error", ev);
});
}
}
});
var SaveImageEditorCommand = Command.extend({
exec: function() {
var that = this,
imageeditor = that.imageeditor,
canvas = imageeditor.getCanvasElement();
kendo.saveAs(extend({}, imageeditor.options.saveAs, {
dataURI: canvas.toDataURL()
}));
imageeditor.toolbar.element.find("[data-command=SaveImageEditorCommand]").trigger("focus");
}
});
var OpenImageEditorCommand = Command.extend({
exec: function() {
var that = this,
imageeditor = that.imageeditor,
upload = imageeditor._upload;
if (!upload) {
var input = $("<input type='file' />");
input.kendoUpload({
select: that.onSelect.bind(that),
error: that.onError.bind(that),
multiple: false,
validation: {
allowedExtensions: [".jpg", ".jpeg", ".gif", ".png", ".bmp", ".tiff", ".webp"]
}
});
imageeditor._upload = upload = input.getKendoUpload();
}
upload.element.click();
},
onSelect: function(ev) {
var that = this,
imageeditor = that.imageeditor,
file = ev.files[0].rawFile,
reader = new FileReader();
reader.addEventListener("load", function() {
imageeditor.drawImage(reader.result).done(function(image) {
if (!imageeditor.trigger("imageLoaded", { image: image })) {
imageeditor.drawCanvas(image);
imageeditor._initUndoRedoStack();
imageeditor._toggleTools();
}
}).fail(function(ev) {
imageeditor.trigger("error", ev);
});
}, false);
if (file) {
reader.readAsDataURL(file);
}
},
onError: function(ev) {
var that = this,
imageeditor = that.imageeditor;
imageeditor.trigger("error", ev);
}
});
extend(kendo.ui.imageeditor, {
ImageEditorCommand: Command,
commands: {
OpenPaneImageEditorCommand: OpenPaneImageEditorCommand,
ZoomImageEditorCommand: ZoomImageEditorCommand,
CropImageEditorCommand: CropImageEditorCommand,
ResizeImageEditorCommand: ResizeImageEditorCommand,
UndoImageEditorCommand: UndoImageEditorCommand,
RedoImageEditorCommand: RedoImageEditorCommand,
SaveImageEditorCommand: SaveImageEditorCommand,
OpenImageEditorCommand: OpenImageEditorCommand
}
});
})(window.kendo.jQuery);
const __meta__ = {
id: "imageeditor",
name: "ImageEditor",
category: "web",
depends: ["core", "toolbar", "dropdownlist"]
};
(function($, undefined$1) {
var kendo = window.kendo,
extend = $.extend,
isPlainObject = $.isPlainObject,
Widget = kendo.ui.Widget,
ui = kendo.ui,
NS = ".kendoImageEditor",
outerHeight = kendo._outerHeight,
ERROR = "error",
IMAGELOADED = "imageLoaded",
IMAGERENDERED = "imageRendered",
EXECUTE = "execute",
CLICK = "click",
TOGGLE = "toggle",
CHANGE = "change",
CANVAS_TEMPLATE = (label) => `<canvas role='img' aria-label='${label}'>Canvas element</canvas>`;
var imageEditorStyles = {
wrapper: "k-imageeditor",
header: "k-imageeditor-header",
toolbar: "k-imageeditor-toolbar",
paneWrapper: "k-imageeditor-action-pane",
contentWrapper: "k-imageeditor-content",
canvasWrapper: "k-imageeditor-canvas-container",
canvasContainer: "k-imageeditor-canvas"
};
var ImageEditor = Widget.extend({
init: function(element, options) {
var that = this;
Widget.fn.init.call(that, element, options);
options = $.extend(true, {}, options);
that._wrapper();
that._renderHeader();
that._contentWrapper();
that._keyHandler();
if (options.imageUrl) {
that._drawCanvas();
}
that._initUndoRedoStack();
that._toggleTools();
kendo.notify(that);
},
options: {
name: 'ImageEditor',
width: "100%",
height: 570,
imageUrl: "",
imageLabel: "",
toolbar: {
},
saveAs: {
fileName: "image.png"
},
messages: {
toolbar: {
open: "Open Image",
save: "Save Image",
undo: "Undo",
redo: "Redo",
crop: "Crop",
resize: "Resize",
zoomIn: "Zoom In",
zoomOut: "Zoom Out",
zoomDropdown: "Zoom options",
zoomActualSize: "Show actual size",
zoomFitToScreen: "Fit to screen"
},
panes: {
crop: {
title: "Crop Image",
aspectRatio: "Aspect Ratio:",
aspectRatioItems: {
"originalRatio": "Original ratio",
"1:1": "1:1 (Square)",
"4:5": "4:5 (8:10)",
"5:7": "5:7",
"2:3": "2:3 (4:6)",
"16:9": "16:9"
},
orientation: "Orientation:",
portrait: "Portrait",
landscape: "Landscape"
},
resize: {
title: "Resize image",
pixels: "Pixels",
percents: "Percents"
}
},
common: {
width: "Width:",
height: "Height:",
cancel: "Cancel",
confirm: "Confirm",
lockAspectRatio: "Lock aspect ratio"
}
}
},
events: [
ERROR,
IMAGELOADED,
IMAGERENDERED,
EXECUTE
],
defaultTools: {
open: { type: "button", icon: "upload", name: "open", command: "OpenImageEditorCommand", showText: "overflow" },
save: { type: "button", icon: "download", name: "save", command: "SaveImageEditorCommand", showText: "overflow", toggleCondition: "canExport" },
separator: { type: "separator" },
undo: { type: "button", icon: "undo", name: "undo", command: "UndoImageEditorCommand", showText: "overflow", toggleCondition: "undo" },
redo: { type: "button", icon: "redo", name: "redo", command: "RedoImageEditorCommand", showText: "overflow", toggleCondition: "redo" },
separator1: { type: "separator" },
crop: { type: "button", icon: "crop", name: "crop", command: "OpenPaneImageEditorCommand", options: "crop", showText: "overflow", toggleCondition: "canExport" },
resize: { type: "button", icon: "image-resize", name: "resize", command: "OpenPaneImageEditorCommand", options: "resize", showText: "overflow", toggleCondition: "canExport" },
zoomIn: { type: "button", icon: "zoom-in", name: "zoomIn", command: "ZoomImageEditorCommand", showText: "overflow", options: "zoomIn", toggleCondition: "enable" },
zoomOut: { type: "button", icon: "zoom-out", name: "zoomOut", command: "ZoomImageEditorCommand", showText: "overflow", options: "zoomOut", toggleCondition: "enable" },
zoomDropdown: {
type: "component",
name: "zoomDropdown",
command: "ZoomImageEditorCommand",
toggleCondition: "enable",
overflow: "never",
component: "DropDownList",
componentOptions: {
placeholder: "Search",
icon: "search",
dataSource: [
{ name: "zoomActualSize", icon: "zoom-actual-size", value: "actualSize" },
{ name: "zoomFitToScreen", icon: "zoom-best-fit", value: "fitToScreen" }
],
dataTextField: "text",
dataValueField: "value",
valuePrimitive: true,
template: ({ icon, text }) => `${kendo.ui.icon(kendo.htmlEncode(icon))} ${kendo.htmlEncode(text)}`,
commandOn: "change",
optionLabel: "Zoom options",
dataBound: (e) => {
e.sender.list.find(".k-list-optionlabel").hide();
}
}
}
},
_wrapper: function() {
var that = this,
options = that.options,
width = options.width,
height = options.height;
that.wrapper = that.element
.addClass(imageEditorStyles.wrapper);
if (width) {
that.wrapper.width(width);
}
if (height) {
that.wrapper.height(height);
}
that._resizeHandler = kendo.onResize(function() {
that.resize(true);
});
},
_renderHeader: function() {
var that = this,
options = that.options;
that.header = $("<div />").addClass(imageEditorStyles.header);
that.wrapper.append(that.header);
if (options.toolbar) {
that._initToolbar();
that.toolbar._tabIndex();
}
},
_initToolbar: function() {
var that = this,
options = that.options,
toolbarElement = $("<div></div>").addClass(imageEditorStyles.toolbar),
toolbarOptions = extend({}, options.toolbar),
tools = toolbarOptions.items ? toolbarOptions.items : Object.keys(that.defaultTools);
toolbarOptions.tools = tools;
toolbarOptions.defaultTools = that.defaultTools;
toolbarOptions.parentMessages = that.options.messages.toolbar;
that.header.append(toolbarElement);
that.toolbar = new kendo.ui.ToolBar(toolbarElement, toolbarOptions);
that.options.toolbar = that.toolbar.options;
that.toolbar.toggleTools();
that.toolbar.bind(CLICK, that._toolbarClick.bind(that));
that.toolbar.bind(TOGGLE, that._toolbarClick.bind(that));
that.toolbar.bind(CHANGE, that._toolbarClick.bind(that));
return that.toolbar;
},
_toolbarClick: function(ev) {
var command = $(ev.target).data("command"),
options = $(ev.target).data("options");
options = $(ev.target).val() || options;
if (!command) {
return;
}
this.executeCommand({
command: command,
options: options
});
},
_contentWrapper: function() {
var that = this,
contentWrapper = $("<div></div>").addClass(imageEditorStyles.contentWrapper),
canvasWrapper = $("<div></div>").addClass(imageEditorStyles.canvasWrapper),
canvasContainer = $("<div></div>").addClass(imageEditorStyles.canvasContainer),
paneWrapper = $("<div></div>").addClass(imageEditorStyles.paneWrapper).hide(),
toolbarHeight = outerHeight(that.header);
that.canvasWrapper = canvasWrapper;
that.canvasContainer = canvasContainer;
that.paneWrapper = paneWrapper;
canvasWrapper.append(canvasContainer);
contentWrapper.height(outerHeight(that.wrapper) - toolbarHeight);
contentWrapper.append(canvasWrapper).append(paneWrapper);
that.wrapper.append(contentWrapper);
},
_keyHandler: function() {
var that = this,
prevent = false;
that.wrapper.on("keydown" + NS, function(ev) {
if (ev.ctrlKey) {
switch (ev.keyCode) {
case 48: // ctrl+0
that.executeCommand({ command: "ZoomImageEditorCommand", options: "fitToScreen" });
prevent = true;
break;
case 189: // ctrl+-
that.executeCommand({ command: "ZoomImageEditorCommand", options: "zoomOut" });
prevent = true;
break;
case 187: // ctrl++
that.executeCommand({ command: "ZoomImageEditorCommand", options: "zoomIn" });
prevent = true;
break;
case 90: // ctrl+z
that.executeCommand({ command: "UndoImageEditorCommand" });
prevent = true;
break;
case 89: // ctrl+y
that.executeCommand({ command: "RedoImageEditorCommand" });
prevent = true;
break;
}
if (prevent) {
ev.preventDefault();
}
}
});
},
_drawCanvas: function() {
var that = this;
var imageUrl = that.options.imageUrl;
that.drawImage(imageUrl).done(function(image) {
if (!that.trigger(IMAGELOADED, { image: image })) {
that.drawCanvas(image);
}
}).fail(function(ev) {
that.trigger(ERROR, ev);
});
},
_initUndoRedoStack: function() {
var that = this;
that.undoStack = [];
that.redoStack = [];
},
_toggleTools: function() {
var that = this,
canRedo = that.redoStack.length > 0,
canUndo = that.undoStack.length > 0,
hasImage = !!that._image,
canExport = true;
try {
that._canvas.toDataURL();
} catch (error) {
canExport = false;
}
if (that.toolbar) {
that.toolbar.toggleTools({
redo: canRedo,
undo: canUndo,
enable: hasImage,
canExport: canExport
});
}
},
drawImage: function(imageUrl) {
var that = this,
deferred = new $.Deferred(),
image = new Image();
image.onload = function() {
kendo.ui.progress(that.canvasContainer, false);
deferred.resolve(image);
};
image.onerror = function() {
kendo.ui.progress(that.canvasContainer, false);
deferred.reject(arguments);
};
kendo.ui.progress(that.canvasContainer, true);
image.src = imageUrl;
return deferred.promise();
},
drawCanvas: func