/**
* ImagePanel.js
*
* Released under LGPL License.
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
/**
* ...
*
* @-x-less ImagePanel.less
*/
define("tinymce/imagetoolsplugin/ImagePanel", [
"tinymce/ui/Control",
"tinymce/ui/DragHelper",
"tinymce/ui/Rect",
"tinymce/util/Tools",
"tinymce/util/Promise",
"tinymce/imagetoolsplugin/CropRect"
], function(Control, DragHelper, Rect, Tools, Promise, CropRect) {
function loadImage(image) {
return new Promise(function(resolve) {
function loaded() {
image.removeEventListener('load', loaded);
resolve(image);
}
if (image.complete) {
resolve(image);
} else {
image.addEventListener('load', loaded);
}
});
}
return Control.extend({
Defaults: {
classes: "imagepanel"
},
selection: function(rect) {
if (arguments.length) {
this.state.set('rect', rect);
return this;
}
return this.state.get('rect');
},
imageSize: function() {
var viewRect = this.state.get('viewRect');
return {
w: viewRect.w,
h: viewRect.h
};
},
toggleCropRect: function(state) {
this.state.set('cropEnabled', state);
},
imageSrc: function(url) {
var self = this, img = new Image();
img.src = url;
loadImage(img).then(function() {
var rect, $img, lastRect = self.state.get('viewRect');
$img = self.$el.find('img');
if ($img[0]) {
$img.replaceWith(img);
} else {
self.getEl().appendChild(img);
}
rect = {x: 0, y: 0, w: img.naturalWidth, h: img.naturalHeight};
self.state.set('viewRect', rect);
self.state.set('rect', Rect.inflate(rect, -20, -20));
if (!lastRect || lastRect.w != rect.w || lastRect.h != rect.h) {
self.zoomFit();
}
self.repaintImage();
self.fire('load');
});
},
zoom: function(value) {
if (arguments.length) {
this.state.set('zoom', value);
return this;
}
return this.state.get('zoom');
},
postRender: function() {
this.imageSrc(this.settings.imageSrc);
return this._super();
},
zoomFit: function() {
var self = this, $img, pw, ph, w, h, zoom, padding;
padding = 10;
$img = self.$el.find('img');
pw = self.getEl().clientWidth;
ph = self.getEl().clientHeight;
w = $img[0].naturalWidth;
h = $img[0].naturalHeight;
zoom = Math.min((pw - padding) / w, (ph - padding) / h);
if (zoom >= 1) {
zoom = 1;
}
self.zoom(zoom);
},
repaintImage: function() {
var x, y, w, h, pw, ph, $img, zoom, rect, elm;
elm = this.getEl();
zoom = this.zoom();
rect = this.state.get('rect');
$img = this.$el.find('img');
pw = elm.offsetWidth;
ph = elm.offsetHeight;
w = $img[0].naturalWidth * zoom;
h = $img[0].naturalHeight * zoom;
x = Math.max(0, pw / 2 - w / 2);
y = Math.max(0, ph / 2 - h / 2);
$img.css({
left: x,
top: y,
width: w,
height: h
});
if (this.cropRect) {
this.cropRect.setRect({
x: rect.x * zoom + x,
y: rect.y * zoom + y,
w: rect.w * zoom,
h: rect.h * zoom
});
this.cropRect.setClampRect({
x: x,
y: y,
w: w,
h: h
});
this.cropRect.setViewPortRect({
x: 0,
y: 0,
w: pw,
h: ph
});
}
},
bindStates: function() {
var self = this;
function setupCropRect(rect) {
self.cropRect = new CropRect(
rect,
self.state.get('viewRect'),
self.state.get('viewRect'),
self.getEl()
);
self.cropRect.on('updateRect', function(e) {
var rect = e.rect, zoom = self.zoom();
rect = {
x: Math.round(rect.x / zoom),
y: Math.round(rect.y / zoom),
w: Math.round(rect.w / zoom),
h: Math.round(rect.h / zoom)
};
self.state.set('rect', rect);
});
self.on('remove', self.cropRect.destroy);
}
self.state.on('change:cropEnabled', function(e) {
self.cropRect.toggleVisibility(e.value);
self.repaintImage();
});
self.state.on('change:zoom', function() {
self.repaintImage();
});
self.state.on('change:rect', function(e) {
var rect = e.value;
if (!self.cropRect) {
setupCropRect(rect);
}
self.cropRect.setRect(rect);
});
}
});
});
|