/**
* ImagePanel.js
*
* Released under LGPL License.
* Copyright (c) 1999-2017 Ephox Corp. All rights reserved
*
* License: http://www.tinymce.com/license
* Contributing: http://www.tinymce.com/contributing
*/
define(
'tinymce.plugins.imagetools.ui.ImagePanel',
[
'global!document',
'global!Image',
'tinymce.core.geom.Rect',
'tinymce.core.ui.Factory',
'tinymce.core.util.Promise',
'tinymce.core.util.Tools',
'tinymce.plugins.imagetools.core.LoadImage',
'tinymce.plugins.imagetools.ui.CropRect'
],
function (document, Image, Rect, Factory, Promise, Tools, LoadImage, CropRect) {
var create = function (settings) {
var Control = Factory.get('Control');
var ImagePanel = 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.loadImage(img).then(function () {
var rect, $img, lastRect = self.state.get('viewRect');
$img = self.$el.find('img');
if ($img[0]) {
$img.replaceWith(img);
} else {
var bg = document.createElement('div');
bg.className = 'mce-imagepanel-bg';
self.getEl().appendChild(bg);
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, $bg, zoom, rect, elm;
elm = this.getEl();
zoom = this.zoom();
rect = this.state.get('rect');
$img = this.$el.find('img');
$bg = this.$el.find('.mce-imagepanel-bg');
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
});
$bg.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(),
function () {
self.fire('crop');
}
);
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);
});
}
});
return new ImagePanel(settings);
};
return {
create: create
};
}
);
|