Enhancement : choose anchor for resize canvas

This commit is contained in:
jdescottes
2015-02-17 02:06:52 +01:00
parent 84f366e7e4
commit d310a77893
13 changed files with 372 additions and 174 deletions

View File

@@ -0,0 +1,89 @@
(function () {
var ns = $.namespace('pskl.controller.settings.resize');
ns.AbstractResizeController = function (piskelController, container) {
this.piskelController = piskelController;
this.container = container;
};
ns.AbstractResizeController.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.widthInput.addEventListener('keyup', this.onSizeInputKeyUp_.bind(this));
this.heightInput.addEventListener('keyup', this.onSizeInputKeyUp_.bind(this));
this.cancelButton = this.container.querySelector('.resize-cancel-button');
this.cancelButton.addEventListener('click', this.onCancelButtonClicked_.bind(this));
this.resizeForm = this.container.querySelector('form');
this.resizeForm.addEventListener('submit', this.onResizeFormSubmit_.bind(this));
this.maintainRatioCheckbox = this.container.querySelector('.resize-ratio-checkbox');
this.maintainRatioCheckbox.addEventListener('change', this.onMaintainRatioChange_.bind(this));
this.lastInput = this.widthInput;
};
ns.AbstractResizeController.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());
pskl.app.piskelController.setPiskel(piskel, true);
$.publish(Events.CLOSE_SETTINGS_DRAWER);
};
ns.AbstractResizeController.prototype.resizeLayer_ = function (layer) {
var resizedFrames = layer.getFrames().map(this.resizeFrame_.bind(this));
return pskl.model.Layer.fromFrames(layer.getName(), resizedFrames);
};
ns.AbstractResizeController.prototype.resizeFrame_ = Constants.ABSTRACT_FUNCTION;
ns.AbstractResizeController.prototype.onCancelButtonClicked_ = function () {
$.publish(Events.CLOSE_SETTINGS_DRAWER);
};
ns.AbstractResizeController.prototype.onMaintainRatioChange_ = function (evt) {
var target = evt.target;
if (target.checked) {
this.synchronizeSizeInputs_(this.lastInput);
}
};
ns.AbstractResizeController.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.AbstractResizeController.prototype.synchronizeSizeInputs_ = function (sizeInput) {
var value = parseInt(sizeInput.value, 10);
if (isNaN(value)) {
value = 0;
}
var height = this.piskelController.getHeight(),
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);
}
};
})();

View File

@@ -0,0 +1,124 @@
(function () {
var ns = $.namespace('pskl.controller.settings.resize');
var ORIGIN = {
TOPLEFT : 'TOPLEFT',
TOP : 'TOP',
TOPRIGHT : 'TOPRIGHT',
MIDDLELEFT : 'MIDDLELEFT',
MIDDLE : 'MIDDLE',
MIDDLERIGHT : 'MIDDLERIGHT',
BOTTOMLEFT : 'BOTTOMLEFT',
BOTTOM : 'BOTTOM',
BOTTOMRIGHT : 'BOTTOMRIGHT'
};
ns.ResizeCanvasController = function (piskelController, container) {
this.superclass.constructor.call(this, piskelController, container);
this.origin = ORIGIN.TOPLEFT;
};
pskl.utils.inherit(ns.ResizeCanvasController, ns.AbstractResizeController);
ns.ResizeCanvasController.prototype.init = function () {
this.superclass.init.call(this);
this.resizeOrigin = document.querySelector('.resize-origin-container');
this.resizeOrigin.addEventListener('click', this.onResizeOriginClick_.bind(this));
this.setOrigin_(ORIGIN.TOPLEFT);
};
/****************/
/* RESIZE LOGIC */
/****************/
ns.ResizeCanvasController.prototype.resizeFrame_ = function (frame) {
var width = parseInt(this.widthInput.value, 10);
var height = parseInt(this.heightInput.value, 10);
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.ResizeCanvasController.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.ResizeCanvasController.prototype.translateX_ = function (x, width, resizedWidth) {
if (this.origin.indexOf('LEFT') != -1) {
return x;
} else if (this.origin.indexOf('RIGHT') != -1) {
return x - (width - resizedWidth);
} else {
return x - Math.round((width - resizedWidth)/2);
}
};
ns.ResizeCanvasController.prototype.translateY_ = function (y, height, resizedHeight) {
if (this.origin.indexOf('TOP') != -1) {
return y;
} else if (this.origin.indexOf('BOTTOM') != -1) {
return y - (height - resizedHeight);
} else {
return y - Math.round((height - resizedHeight)/2);
}
};
/*****************/
/* ANCHOR WIDGET */
/*****************/
ns.ResizeCanvasController.prototype.onResizeOriginClick_ = function (evt) {
var origin = evt.target.dataset.origin;
if (origin && ORIGIN[origin]) {
this.setOrigin_(origin);
}
};
ns.ResizeCanvasController.prototype.setOrigin_ = function (origin) {
this.origin = origin;
var previous = document.querySelector('.resize-origin-option.selected');
if (previous) {
previous.classList.remove('selected');
}
var selected = document.querySelector('.resize-origin-option[data-origin="' + origin + '"]');
if (selected) {
selected.classList.add('selected');
this.refreshNeighbors_(selected);
}
};
ns.ResizeCanvasController.prototype.refreshNeighbors_ = function (selected) {
var options = document.querySelectorAll('.resize-origin-option');
for (var i = 0 ; i < options.length ; i++) {
options[i].removeAttribute('data-neighbor');
}
var selectedIndex = Array.prototype.indexOf.call(options, selected);
this.setNeighborhood_(options[selectedIndex - 1], 'left');
this.setNeighborhood_(options[selectedIndex + 1], 'right');
this.setNeighborhood_(options[selectedIndex - 3], 'top');
this.setNeighborhood_(options[selectedIndex + 3], 'bottom');
};
ns.ResizeCanvasController.prototype.setNeighborhood_ = function (el, neighborhood) {
var origin = this.origin.toLowerCase();
var isNeighborhoodValid = origin.indexOf(neighborhood) === -1;
if (isNeighborhoodValid) {
el.setAttribute('data-neighbor', neighborhood);
}
};
})();

View File

@@ -0,0 +1,19 @@
(function () {
var ns = $.namespace('pskl.controller.settings.resize');
ns.ResizeContentController = function (piskelController, container) {
this.superclass.constructor.call(this, piskelController, container);
};
pskl.utils.inherit(ns.ResizeContentController, ns.AbstractResizeController);
ns.ResizeContentController.prototype.init = function () {
this.superclass.init.call(this);
};
ns.ResizeContentController.prototype.resizeFrame_ = function (frame) {
var width = parseInt(this.widthInput.value, 10);
var height = parseInt(this.heightInput.value, 10);
return pskl.utils.FrameUtils.resize(frame, width, height, false);
};
})();

View File

@@ -0,0 +1,16 @@
(function () {
var ns = $.namespace('pskl.controller.settings.resize');
ns.ResizeController = function (piskelController) {
var resizeCanvasContainer = document.querySelector('.resize-canvas');
this.resizeCanvasController = new ns.ResizeCanvasController(piskelController, resizeCanvasContainer);
var resizeContentContainer = document.querySelector('.resize-content');
this.resizeContentController = new ns.ResizeContentController(piskelController, resizeContentContainer);
};
ns.ResizeController.prototype.init = function () {
this.resizeCanvasController.init();
this.resizeContentController.init();
};
})();