MDL-45479 atto_image: Improve the preview area

This changes the preview area:
* to show the image at the requested size; and
* to fix the scaling issues.
This commit is contained in:
Andrew Nicols
2014-05-20 13:20:17 +12:00
committed by Sam Hemelryk
parent 1d8bebfeaf
commit b60373f3e4
5 changed files with 371 additions and 291 deletions
+6 -3
View File
@@ -1,10 +1,13 @@
.atto_image_preview {
max-width: 150px;
max-height: 150px;
width: 100%;
height: 100%;
margin-left: auto;
margin-right: auto;
}
.atto_image_preview_box {
height: 150px;
max-height: 200px;
margin-bottom: 1em;
overflow: auto;
}
.editor_atto_content img {
@@ -150,9 +150,8 @@ var CSS = {
// Add the image preview.
'<div class="mdl-align">' +
'<div class="{{CSS.IMAGEPREVIEWBOX}}">' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" id="{{elementid}}_{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'</div>' +
'<br/>' +
// Add the submit button and close the form.
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "saveimage" component}}</button>' +
@@ -198,22 +197,13 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_form: null,
/**
* Remember the image true dimensions so we can constrain resizing.
* The dimensions of the raw image before we manipulate it.
*
* @param _imageRawWidth
* @type Integer
* @param _rawImageDimensions
* @type Object
* @private
*/
_imageRawWidth: 0,
/**
* Remember the image true dimensions so we can constrain resizing.
*
* @param _imageRawHeight
* @type Integer
* @private
*/
_imageRawHeight: 0,
_rawImageDimensions: null,
initializer: function() {
this.addButton({
@@ -276,11 +266,23 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_loadPreviewImage: function(url) {
var image = new Image(), self = this;
image.onerror = function() {
var preview = self._form.one('.' + CSS.IMAGEPREVIEW);
preview.setStyles({
'display': 'none'
});
// Centre the dialogue when clearing the image preview.
self.getDialogue().centerDialogue();
};
image.onload = function() {
var input, currentwidth, currentheight, widthRatio, heightRatio;
self._imageRawWidth = this.width;
self._imageRawHeight = this.height;
self._rawImageDimensions = {
width: this.width,
height: this.height
};
input = self._form.one('.' + CSS.INPUTWIDTH);
currentwidth = input.get('value');
@@ -295,8 +297,10 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
input.set('src', this.src);
input.setStyle('display', 'inline');
input.setAttribute('src', this.src);
input.setStyles({
'display': 'inline'
});
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
@@ -314,6 +318,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
input.set('checked', widthRatio === heightRatio);
}
// Apply the image sizing.
self._autoAdjustSize(self);
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
};
@@ -348,11 +355,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
this._form.one('.' + CSS.IMAGEPRESENTATION).on('change', this._updateWarning, this);
this._form.one('.' + CSS.INPUTALT).on('change', this._updateWarning, this);
this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustHeight, this);
this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustWidth, this);
this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);
this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);
this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {
if (event.target.get('checked')) {
this._autoAdjustHeight();
this._autoAdjustSize(event);
}
}, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
@@ -367,84 +374,104 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return content;
},
/**
* Adjust the height to keep the aspect ratio.
*
* @method _autoAdjustHeight
* @private
*/
_autoAdjustHeight: function() {
var currentWidth, newHeight, currentHeight;
_autoAdjustSize: function(e, forceHeight) {
forceHeight = forceHeight || false;
var keyField = this._form.one('.' + CSS.INPUTWIDTH),
keyFieldType = 'width',
subField = this._form.one('.' + CSS.INPUTHEIGHT),
subFieldType = 'height',
constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),
keyFieldValue = keyField.get('value'),
subFieldValue = subField.get('value'),
imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),
rawPercentage,
rawSize;
// Set the width back to default if it is empty.
if (this._form.one('.' + CSS.INPUTWIDTH).get('value') === '') {
this._form.one('.' + CSS.INPUTWIDTH).set('value', this._imageRawWidth);
if (keyFieldValue === '') {
keyFieldValue = this._rawImageDimensions[keyFieldType];
keyField.set('value', keyFieldValue);
keyFieldValue = keyField.get('value');
}
if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
return;
}
// Clear the existing preview sizes.
imagePreview.setStyles({
width: null,
height: null
});
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value').trim();
// If this is a percentage based width, copy it verbatim to the height.
if (currentWidth.match(REGEX.ISPERCENT)) {
newHeight = currentWidth;
this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
} else {
currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
// Now update with the new values.
if (!constrainField.get('checked')) {
// We are not keeping the image proportion - update the preview accordingly.
if (!isNaN(newHeight)) {
this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
// Width.
if (keyFieldValue.match(REGEX.ISPERCENT)) {
rawPercentage = parseInt(keyFieldValue, 10);
rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
imagePreview.setStyle('width', rawSize + 'px');
} else {
imagePreview.setStyle('width', keyFieldValue + 'px');
}
}
},
/**
* Adjust the width to keep the aspect ratio.
*
* @method _autoAdjustWidth
* @private
*/
_autoAdjustWidth: function() {
var currentHeight, newWidth;
// Set the height back to default if it is empty.
if (this._form.one('.' + CSS.INPUTHEIGHT).get('value') === '') {
this._form.one('.' + CSS.INPUTHEIGHT).set('value', this._imageRawHeight);
}
if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
return;
}
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value').trim();
// If this is a percentage based width, copy it verbatim to the height.
if (currentHeight.match(REGEX.ISPERCENT)) {
newWidth = currentHeight;
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
} else {
currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
if (!isNaN(newWidth)) {
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
// Height.
if (subFieldValue.match(REGEX.ISPERCENT)) {
rawPercentage = parseInt(subFieldValue, 10);
rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
imagePreview.setStyle('height', rawSize + 'px');
} else {
imagePreview.setStyle('height', subFieldValue + 'px');
}
} else {
// We are keeping the image in proportion.
if (forceHeight) {
// By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.
var _temporaryValue;
_temporaryValue = keyField;
keyField = subField;
subField = _temporaryValue;
_temporaryValue = keyFieldType;
keyFieldType = subFieldType;
subFieldType = _temporaryValue;
_temporaryValue = keyFieldValue;
keyFieldValue = subFieldValue;
subFieldValue = _temporaryValue;
}
if (keyFieldValue.match(REGEX.ISPERCENT)) {
// This is a percentage based change. Copy it verbatim.
subFieldValue = keyFieldValue;
// Set the width to the calculated pixel width.
rawPercentage = parseInt(keyFieldValue, 10);
rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
// And apply the width/height to the container.
imagePreview.setStyle('width', rawSize);
rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
imagePreview.setStyle('height', rawSize);
} else {
// Calculate the scaled subFieldValue from the keyFieldValue.
subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *
this._rawImageDimensions[subFieldType]);
if (forceHeight) {
imagePreview.setStyles({
'width': subFieldValue,
'height': keyFieldValue
});
} else {
imagePreview.setStyles({
'width': keyFieldValue,
'height': subFieldValue
});
}
}
// Update the subField's value within the form to reflect the changes.
subField.set('value', subFieldValue);
}
},
@@ -506,9 +533,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.customstyle) {
form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);
}
if (properties.display) {
img.setStyle('display', properties.display);
}
if (properties.width) {
form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);
}
@@ -525,6 +549,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.presentation) {
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
}
// Update the image preview based on the form properties.
this._autoAdjustSize();
},
/**
@@ -543,7 +570,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
width: null,
height: null,
align: '',
display: 'inline',
presentation: false
},
File diff suppressed because one or more lines are too long
@@ -150,9 +150,8 @@ var CSS = {
// Add the image preview.
'<div class="mdl-align">' +
'<div class="{{CSS.IMAGEPREVIEWBOX}}">' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" id="{{elementid}}_{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'</div>' +
'<br/>' +
// Add the submit button and close the form.
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "saveimage" component}}</button>' +
@@ -198,22 +197,13 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_form: null,
/**
* Remember the image true dimensions so we can constrain resizing.
* The dimensions of the raw image before we manipulate it.
*
* @param _imageRawWidth
* @type Integer
* @param _rawImageDimensions
* @type Object
* @private
*/
_imageRawWidth: 0,
/**
* Remember the image true dimensions so we can constrain resizing.
*
* @param _imageRawHeight
* @type Integer
* @private
*/
_imageRawHeight: 0,
_rawImageDimensions: null,
initializer: function() {
this.addButton({
@@ -276,11 +266,23 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_loadPreviewImage: function(url) {
var image = new Image(), self = this;
image.onerror = function() {
var preview = self._form.one('.' + CSS.IMAGEPREVIEW);
preview.setStyles({
'display': 'none'
});
// Centre the dialogue when clearing the image preview.
self.getDialogue().centerDialogue();
};
image.onload = function() {
var input, currentwidth, currentheight, widthRatio, heightRatio;
self._imageRawWidth = this.width;
self._imageRawHeight = this.height;
self._rawImageDimensions = {
width: this.width,
height: this.height
};
input = self._form.one('.' + CSS.INPUTWIDTH);
currentwidth = input.get('value');
@@ -295,8 +297,10 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
input.set('src', this.src);
input.setStyle('display', 'inline');
input.setAttribute('src', this.src);
input.setStyles({
'display': 'inline'
});
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
@@ -314,6 +318,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
input.set('checked', widthRatio === heightRatio);
}
// Apply the image sizing.
self._autoAdjustSize(self);
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
};
@@ -348,11 +355,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
this._form.one('.' + CSS.IMAGEPRESENTATION).on('change', this._updateWarning, this);
this._form.one('.' + CSS.INPUTALT).on('change', this._updateWarning, this);
this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustHeight, this);
this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustWidth, this);
this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);
this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);
this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {
if (event.target.get('checked')) {
this._autoAdjustHeight();
this._autoAdjustSize(event);
}
}, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
@@ -367,84 +374,104 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return content;
},
/**
* Adjust the height to keep the aspect ratio.
*
* @method _autoAdjustHeight
* @private
*/
_autoAdjustHeight: function() {
var currentWidth, newHeight, currentHeight;
_autoAdjustSize: function(e, forceHeight) {
forceHeight = forceHeight || false;
var keyField = this._form.one('.' + CSS.INPUTWIDTH),
keyFieldType = 'width',
subField = this._form.one('.' + CSS.INPUTHEIGHT),
subFieldType = 'height',
constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),
keyFieldValue = keyField.get('value'),
subFieldValue = subField.get('value'),
imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),
rawPercentage,
rawSize;
// Set the width back to default if it is empty.
if (this._form.one('.' + CSS.INPUTWIDTH).get('value') === '') {
this._form.one('.' + CSS.INPUTWIDTH).set('value', this._imageRawWidth);
if (keyFieldValue === '') {
keyFieldValue = this._rawImageDimensions[keyFieldType];
keyField.set('value', keyFieldValue);
keyFieldValue = keyField.get('value');
}
if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
return;
}
// Clear the existing preview sizes.
imagePreview.setStyles({
width: null,
height: null
});
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value').trim();
// If this is a percentage based width, copy it verbatim to the height.
if (currentWidth.match(REGEX.ISPERCENT)) {
newHeight = currentWidth;
this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
} else {
currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
// Now update with the new values.
if (!constrainField.get('checked')) {
// We are not keeping the image proportion - update the preview accordingly.
if (!isNaN(newHeight)) {
this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
// Width.
if (keyFieldValue.match(REGEX.ISPERCENT)) {
rawPercentage = parseInt(keyFieldValue, 10);
rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
imagePreview.setStyle('width', rawSize + 'px');
} else {
imagePreview.setStyle('width', keyFieldValue + 'px');
}
}
},
/**
* Adjust the width to keep the aspect ratio.
*
* @method _autoAdjustWidth
* @private
*/
_autoAdjustWidth: function() {
var currentHeight, newWidth;
// Set the height back to default if it is empty.
if (this._form.one('.' + CSS.INPUTHEIGHT).get('value') === '') {
this._form.one('.' + CSS.INPUTHEIGHT).set('value', this._imageRawHeight);
}
if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
return;
}
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value').trim();
// If this is a percentage based width, copy it verbatim to the height.
if (currentHeight.match(REGEX.ISPERCENT)) {
newWidth = currentHeight;
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
} else {
currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
if (!isNaN(newWidth)) {
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
// Height.
if (subFieldValue.match(REGEX.ISPERCENT)) {
rawPercentage = parseInt(subFieldValue, 10);
rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
imagePreview.setStyle('height', rawSize + 'px');
} else {
imagePreview.setStyle('height', subFieldValue + 'px');
}
} else {
// We are keeping the image in proportion.
if (forceHeight) {
// By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.
var _temporaryValue;
_temporaryValue = keyField;
keyField = subField;
subField = _temporaryValue;
_temporaryValue = keyFieldType;
keyFieldType = subFieldType;
subFieldType = _temporaryValue;
_temporaryValue = keyFieldValue;
keyFieldValue = subFieldValue;
subFieldValue = _temporaryValue;
}
if (keyFieldValue.match(REGEX.ISPERCENT)) {
// This is a percentage based change. Copy it verbatim.
subFieldValue = keyFieldValue;
// Set the width to the calculated pixel width.
rawPercentage = parseInt(keyFieldValue, 10);
rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
// And apply the width/height to the container.
imagePreview.setStyle('width', rawSize);
rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
imagePreview.setStyle('height', rawSize);
} else {
// Calculate the scaled subFieldValue from the keyFieldValue.
subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *
this._rawImageDimensions[subFieldType]);
if (forceHeight) {
imagePreview.setStyles({
'width': subFieldValue,
'height': keyFieldValue
});
} else {
imagePreview.setStyles({
'width': keyFieldValue,
'height': subFieldValue
});
}
}
// Update the subField's value within the form to reflect the changes.
subField.set('value', subFieldValue);
}
},
@@ -506,9 +533,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.customstyle) {
form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);
}
if (properties.display) {
img.setStyle('display', properties.display);
}
if (properties.width) {
form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);
}
@@ -525,6 +549,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.presentation) {
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
}
// Update the image preview based on the form properties.
this._autoAdjustSize();
},
/**
@@ -543,7 +570,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
width: null,
height: null,
align: '',
display: 'inline',
presentation: false
},
+121 -95
View File
@@ -148,9 +148,8 @@ var CSS = {
// Add the image preview.
'<div class="mdl-align">' +
'<div class="{{CSS.IMAGEPREVIEWBOX}}">' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" id="{{elementid}}_{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'<img src="#" class="{{CSS.IMAGEPREVIEW}}" alt="" style="display: none;"/>' +
'</div>' +
'<br/>' +
// Add the submit button and close the form.
'<button class="{{CSS.INPUTSUBMIT}}" type="submit">{{get_string "saveimage" component}}</button>' +
@@ -196,22 +195,13 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_form: null,
/**
* Remember the image true dimensions so we can constrain resizing.
* The dimensions of the raw image before we manipulate it.
*
* @param _imageRawWidth
* @type Integer
* @param _rawImageDimensions
* @type Object
* @private
*/
_imageRawWidth: 0,
/**
* Remember the image true dimensions so we can constrain resizing.
*
* @param _imageRawHeight
* @type Integer
* @private
*/
_imageRawHeight: 0,
_rawImageDimensions: null,
initializer: function() {
this.addButton({
@@ -274,11 +264,23 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
_loadPreviewImage: function(url) {
var image = new Image(), self = this;
image.onerror = function() {
var preview = self._form.one('.' + CSS.IMAGEPREVIEW);
preview.setStyles({
'display': 'none'
});
// Centre the dialogue when clearing the image preview.
self.getDialogue().centerDialogue();
};
image.onload = function() {
var input, currentwidth, currentheight, widthRatio, heightRatio;
self._imageRawWidth = this.width;
self._imageRawHeight = this.height;
self._rawImageDimensions = {
width: this.width,
height: this.height
};
input = self._form.one('.' + CSS.INPUTWIDTH);
currentwidth = input.get('value');
@@ -293,8 +295,10 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
currentheight = "" + this.height;
}
input = self._form.one('.' + CSS.IMAGEPREVIEW);
input.set('src', this.src);
input.setStyle('display', 'inline');
input.setAttribute('src', this.src);
input.setStyles({
'display': 'inline'
});
input = self._form.one('.' + CSS.INPUTCONSTRAIN);
if (currentwidth.match(REGEX.ISPERCENT) && currentheight.match(REGEX.ISPERCENT)) {
@@ -312,6 +316,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
input.set('checked', widthRatio === heightRatio);
}
// Apply the image sizing.
self._autoAdjustSize(self);
// Centre the dialogue once the preview image has loaded.
self.getDialogue().centerDialogue();
};
@@ -346,11 +353,11 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
this._form.one('.' + CSS.IMAGEPRESENTATION).on('change', this._updateWarning, this);
this._form.one('.' + CSS.INPUTALT).on('change', this._updateWarning, this);
this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustHeight, this);
this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustWidth, this);
this._form.one('.' + CSS.INPUTWIDTH).on('blur', this._autoAdjustSize, this);
this._form.one('.' + CSS.INPUTHEIGHT).on('blur', this._autoAdjustSize, this, true);
this._form.one('.' + CSS.INPUTCONSTRAIN).on('change', function(event) {
if (event.target.get('checked')) {
this._autoAdjustHeight();
this._autoAdjustSize(event);
}
}, this);
this._form.one('.' + CSS.INPUTURL).on('blur', this._urlChanged, this);
@@ -365,84 +372,104 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
return content;
},
/**
* Adjust the height to keep the aspect ratio.
*
* @method _autoAdjustHeight
* @private
*/
_autoAdjustHeight: function() {
var currentWidth, newHeight, currentHeight;
_autoAdjustSize: function(e, forceHeight) {
forceHeight = forceHeight || false;
var keyField = this._form.one('.' + CSS.INPUTWIDTH),
keyFieldType = 'width',
subField = this._form.one('.' + CSS.INPUTHEIGHT),
subFieldType = 'height',
constrainField = this._form.one('.' + CSS.INPUTCONSTRAIN),
keyFieldValue = keyField.get('value'),
subFieldValue = subField.get('value'),
imagePreview = this._form.one('.' + CSS.IMAGEPREVIEW),
rawPercentage,
rawSize;
// Set the width back to default if it is empty.
if (this._form.one('.' + CSS.INPUTWIDTH).get('value') === '') {
this._form.one('.' + CSS.INPUTWIDTH).set('value', this._imageRawWidth);
if (keyFieldValue === '') {
keyFieldValue = this._rawImageDimensions[keyFieldType];
keyField.set('value', keyFieldValue);
keyFieldValue = keyField.get('value');
}
if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
return;
}
// Clear the existing preview sizes.
imagePreview.setStyles({
width: null,
height: null
});
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value').trim();
// If this is a percentage based width, copy it verbatim to the height.
if (currentWidth.match(REGEX.ISPERCENT)) {
newHeight = currentWidth;
this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
} else {
currentWidth = parseInt(this._form.one('.' + CSS.INPUTWIDTH).get('value'), 10);
newHeight = Math.round((currentWidth / this._imageRawWidth) * this._imageRawHeight);
// Now update with the new values.
if (!constrainField.get('checked')) {
// We are not keeping the image proportion - update the preview accordingly.
if (!isNaN(newHeight)) {
this._form.one('.' + CSS.INPUTHEIGHT).set('value', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', newHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
// Width.
if (keyFieldValue.match(REGEX.ISPERCENT)) {
rawPercentage = parseInt(keyFieldValue, 10);
rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
imagePreview.setStyle('width', rawSize + 'px');
} else {
imagePreview.setStyle('width', keyFieldValue + 'px');
}
}
},
/**
* Adjust the width to keep the aspect ratio.
*
* @method _autoAdjustWidth
* @private
*/
_autoAdjustWidth: function() {
var currentHeight, newWidth;
// Set the height back to default if it is empty.
if (this._form.one('.' + CSS.INPUTHEIGHT).get('value') === '') {
this._form.one('.' + CSS.INPUTHEIGHT).set('value', this._imageRawHeight);
}
if (!this._form.one('.' + CSS.INPUTCONSTRAIN).get('checked')) {
currentWidth = this._form.one('.' + CSS.INPUTWIDTH).get('value');
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value');
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', currentWidth);
return;
}
currentHeight = this._form.one('.' + CSS.INPUTHEIGHT).get('value').trim();
// If this is a percentage based width, copy it verbatim to the height.
if (currentHeight.match(REGEX.ISPERCENT)) {
newWidth = currentHeight;
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
} else {
currentHeight = parseInt(this._form.one('.' + CSS.INPUTHEIGHT).get('value'), 10);
newWidth = Math.round((currentHeight / this._imageRawHeight) * this._imageRawWidth);
if (!isNaN(newWidth)) {
this._form.one('.' + CSS.INPUTWIDTH).set('value', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('width', newWidth);
this._form.one('.' + CSS.IMAGEPREVIEW).setAttribute('height', currentHeight);
// Height.
if (subFieldValue.match(REGEX.ISPERCENT)) {
rawPercentage = parseInt(subFieldValue, 10);
rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
imagePreview.setStyle('height', rawSize + 'px');
} else {
imagePreview.setStyle('height', subFieldValue + 'px');
}
} else {
// We are keeping the image in proportion.
if (forceHeight) {
// By default we update based on width. Swap the key and sub fields around to achieve a height-based scale.
var _temporaryValue;
_temporaryValue = keyField;
keyField = subField;
subField = _temporaryValue;
_temporaryValue = keyFieldType;
keyFieldType = subFieldType;
subFieldType = _temporaryValue;
_temporaryValue = keyFieldValue;
keyFieldValue = subFieldValue;
subFieldValue = _temporaryValue;
}
if (keyFieldValue.match(REGEX.ISPERCENT)) {
// This is a percentage based change. Copy it verbatim.
subFieldValue = keyFieldValue;
// Set the width to the calculated pixel width.
rawPercentage = parseInt(keyFieldValue, 10);
rawSize = this._rawImageDimensions.width / 100 * rawPercentage;
// And apply the width/height to the container.
imagePreview.setStyle('width', rawSize);
rawSize = this._rawImageDimensions.height / 100 * rawPercentage;
imagePreview.setStyle('height', rawSize);
} else {
// Calculate the scaled subFieldValue from the keyFieldValue.
subFieldValue = Math.round((keyFieldValue / this._rawImageDimensions[keyFieldType]) *
this._rawImageDimensions[subFieldType]);
if (forceHeight) {
imagePreview.setStyles({
'width': subFieldValue,
'height': keyFieldValue
});
} else {
imagePreview.setStyles({
'width': keyFieldValue,
'height': subFieldValue
});
}
}
// Update the subField's value within the form to reflect the changes.
subField.set('value', subFieldValue);
}
},
@@ -504,9 +531,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.customstyle) {
form.one('.' + CSS.INPUTCUSTOMSTYLE).set('value', properties.customstyle);
}
if (properties.display) {
img.setStyle('display', properties.display);
}
if (properties.width) {
form.one('.' + CSS.INPUTWIDTH).set('value', properties.width);
}
@@ -523,6 +547,9 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
if (properties.presentation) {
form.one('.' + CSS.IMAGEPRESENTATION).set('checked', 'checked');
}
// Update the image preview based on the form properties.
this._autoAdjustSize();
},
/**
@@ -541,7 +568,6 @@ Y.namespace('M.atto_image').Button = Y.Base.create('button', Y.M.editor_atto.Edi
width: null,
height: null,
align: '',
display: 'inline',
presentation: false
},