Files
piskel/src/js/controller/settings/resize/ResizeController.js
2015-04-14 18:02:33 +02:00

161 lines
5.6 KiB
JavaScript

(function () {
var ns = $.namespace('pskl.controller.settings.resize');
ns.ResizeController = function (piskelController) {
this.piskelController = piskelController;
this.container = document.querySelector('.resize-canvas');
var anchorWidgetContainer = this.container.querySelector('.resize-origin-container');
this.anchorWidget = new ns.AnchorWidget(anchorWidgetContainer);
this.defaultSizeController = new ns.DefaultSizeController(piskelController);
};
pskl.utils.inherit(ns.ResizeController, pskl.controller.settings.AbstractSettingController);
ns.ResizeController.prototype.init = function () {
this.widthInput = this.container.querySelector('[name="resize-width"]');
this.heightInput = this.container.querySelector('[name="resize-height"]');
this.widthInput.value = this.piskelController.getWidth();
this.heightInput.value = this.piskelController.getHeight();
this.addEventListener(this.widthInput, 'keyup', this.onSizeInputKeyUp_);
this.addEventListener(this.heightInput, 'keyup', this.onSizeInputKeyUp_);
this.resizeForm = this.container.querySelector('form');
this.addEventListener(this.resizeForm, 'submit', this.onResizeFormSubmit_);
this.resizeContentCheckbox = this.container.querySelector('.resize-content-checkbox');
this.addEventListener(this.resizeContentCheckbox, 'change', this.onResizeContentChange_);
this.maintainRatioCheckbox = this.container.querySelector('.resize-ratio-checkbox');
this.addEventListener(this.maintainRatioCheckbox, 'change', this.onMaintainRatioChange_);
this.anchorWidget.setOrigin(ns.AnchorWidget.ORIGIN.TOPLEFT);
this.lastInput = this.widthInput;
this.defaultSizeController.init();
};
ns.ResizeController.prototype.destroy = function () {
this.anchorWidget.destroy();
this.superclass.destroy.call(this);
};
ns.ResizeController.prototype.onResizeFormSubmit_ = function (evt) {
evt.preventDefault();
var resizedLayers = this.piskelController.getLayers().map(this.resizeLayer_.bind(this));
var piskel = pskl.model.Piskel.fromLayers(resizedLayers, this.piskelController.getPiskel().getDescriptor());
// propagate savepath to new Piskel
piskel.savePath = pskl.app.piskelController.getSavePath();
pskl.app.piskelController.setPiskel(piskel, true);
$.publish(Events.CLOSE_SETTINGS_DRAWER);
};
ns.ResizeController.prototype.resizeLayer_ = function (layer) {
var resizedFrames = layer.getFrames().map(this.resizeFrame_.bind(this));
return pskl.model.Layer.fromFrames(layer.getName(), resizedFrames);
};
ns.ResizeController.prototype.onResizeContentChange_ = function (evt) {
var target = evt.target;
if (target.checked) {
this.anchorWidget.disable();
} else {
this.anchorWidget.enable();
}
};
ns.ResizeController.prototype.onMaintainRatioChange_ = function (evt) {
var target = evt.target;
if (target.checked) {
this.synchronizeSizeInputs_(this.lastInput);
}
};
ns.ResizeController.prototype.onSizeInputKeyUp_ = function (evt) {
var target = evt.target;
if (this.maintainRatioCheckbox.checked) {
this.synchronizeSizeInputs_(target);
}
this.lastInput = target;
};
/**
* Based on the value of the provided sizeInput (considered as emitter)
* update the value of the other sizeInput to match the current width/height ratio
* @param {HTMLElement} origin either widthInput or heightInput
*/
ns.ResizeController.prototype.synchronizeSizeInputs_ = function (sizeInput) {
var value = parseInt(sizeInput.value, 10);
if (isNaN(value)) {
value = 0;
}
var height = this.piskelController.getHeight();
var width = this.piskelController.getWidth();
if (sizeInput === this.widthInput) {
this.heightInput.value = Math.round(value * height / width);
} else if (sizeInput === this.heightInput) {
this.widthInput.value = Math.round(value * width / height);
}
};
/***********************/
/* RESIZE LOGIC */
/***********************/
ns.ResizeController.prototype.resizeFrame_ = function (frame) {
var width = parseInt(this.widthInput.value, 10);
var height = parseInt(this.heightInput.value, 10);
if (this.resizeContentCheckbox.checked) {
return pskl.utils.FrameUtils.resize(frame, width, height, false);
} else {
var resizedFrame = new pskl.model.Frame(width, height);
frame.forEachPixel(function (color, x, y) {
var translated = this.translateCoordinates_(x, y, frame, resizedFrame);
if (resizedFrame.containsPixel(translated.x, translated.y)) {
resizedFrame.setPixel(translated.x, translated.y, color);
}
}.bind(this));
return resizedFrame;
}
};
ns.ResizeController.prototype.translateCoordinates_ = function (x, y, frame, resizedFrame) {
return {
x : this.translateX_(x, frame.width, resizedFrame.width),
y : this.translateY_(y, frame.height, resizedFrame.height)
};
};
ns.ResizeController.prototype.translateX_ = function (x, width, resizedWidth) {
var origin = this.anchorWidget.getOrigin();
if (origin.indexOf('LEFT') != -1) {
return x;
} else if (origin.indexOf('RIGHT') != -1) {
return x - (width - resizedWidth);
} else {
return x - Math.round((width - resizedWidth) / 2);
}
};
ns.ResizeController.prototype.translateY_ = function (y, height, resizedHeight) {
var origin = this.anchorWidget.getOrigin();
if (origin.indexOf('TOP') != -1) {
return y;
} else if (origin.indexOf('BOTTOM') != -1) {
return y - (height - resizedHeight);
} else {
return y - Math.round((height - resizedHeight) / 2);
}
};
})();