mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
First layer UI. Just functional, UX far from ideal
This commit is contained in:
@@ -177,6 +177,71 @@ body {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layers container
|
||||||
|
*/
|
||||||
|
.layers-container {
|
||||||
|
border : 1px solid #444;
|
||||||
|
font-size : medium;
|
||||||
|
color: white;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layers-title {
|
||||||
|
padding : 10px;
|
||||||
|
margin: 0;
|
||||||
|
font-size : 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layers-list {
|
||||||
|
font-size : 12px;
|
||||||
|
border-bottom: 1px solid #444;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layer-item {
|
||||||
|
height:24px;
|
||||||
|
line-height: 24px;
|
||||||
|
padding : 0 10px;
|
||||||
|
border-top: 1px solid #444;
|
||||||
|
cursor : pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layer-item:hover {
|
||||||
|
background : #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-layer-item, .current-layer-item:hover {
|
||||||
|
background : #333;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layers-button-container {
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layers-button {
|
||||||
|
line-height: 24px;
|
||||||
|
padding: 0 10px;
|
||||||
|
display: inline-block;
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid #666;
|
||||||
|
border-bottom: 1px solid #222;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #3f3f3f;
|
||||||
|
cursor: pointer;
|
||||||
|
color: white;
|
||||||
|
font-size: 0.7em;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0px -1px 0 #000;
|
||||||
|
transition: background-color 0.2s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.layers-button:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
background-color: #484848;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* User messages
|
* User messages
|
||||||
*/
|
*/
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
|
|
||||||
<div class="column right-column">
|
<div class="column right-column">
|
||||||
<iframe src="templates/preview.html" class="_ctl" onload="_ctl(event)"></iframe>
|
<iframe src="templates/preview.html" class="_ctl" onload="_ctl(event)"></iframe>
|
||||||
|
<iframe src="templates/layers.html" class="_ctl" onload="_ctl(event)"></iframe>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
this.previewsController = new pskl.controller.PreviewFilmController(this.piskelController, $('#preview-list'));
|
this.previewsController = new pskl.controller.PreviewFilmController(this.piskelController, $('#preview-list'));
|
||||||
this.previewsController.init();
|
this.previewsController.init();
|
||||||
|
|
||||||
|
this.layersController = new pskl.controller.LayersController(this.piskelController);
|
||||||
|
this.layersController.init();
|
||||||
|
|
||||||
this.settingsController = new pskl.controller.SettingsController(this.piskelController);
|
this.settingsController = new pskl.controller.SettingsController(this.piskelController);
|
||||||
this.settingsController.init();
|
this.settingsController.init();
|
||||||
|
59
js/controller/LayersController.js
Normal file
59
js/controller/LayersController.js
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace('pskl.controller');
|
||||||
|
|
||||||
|
ns.LayersController = function (piskelController) {
|
||||||
|
this.piskelController = piskelController;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.LayersController.prototype.init = function () {
|
||||||
|
this.layerItemTemplate_ = pskl.utils.Template.get('layer-item-template');
|
||||||
|
this.rootEl = document.querySelectorAll('.layers-container')[0];
|
||||||
|
this.layersListEl = document.querySelectorAll('.layers-list')[0];
|
||||||
|
|
||||||
|
this.rootEl.addEventListener('click', this.onClick_.bind(this));
|
||||||
|
|
||||||
|
$.subscribe(Events.FRAMESHEET_RESET, this.renderLayerList_.bind(this));
|
||||||
|
|
||||||
|
this.renderLayerList_();
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.LayersController.prototype.renderLayerList_ = function () {
|
||||||
|
this.layersListEl.innerHTML = '';
|
||||||
|
var layers = this.piskelController.getLayers();
|
||||||
|
layers.forEach(this.addLayerItem.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.LayersController.prototype.addLayerItem = function (layer) {
|
||||||
|
var layerItemHtml = pskl.utils.Template.replace(this.layerItemTemplate_, {
|
||||||
|
layername : layer.getName()
|
||||||
|
});
|
||||||
|
var layerItem = pskl.utils.Template.createFromHTML(layerItemHtml);
|
||||||
|
if (this.piskelController.getCurrentLayer() === layer) {
|
||||||
|
layerItem.classList.add('current-layer-item');
|
||||||
|
}
|
||||||
|
this.layersListEl.insertBefore(layerItem, this.layersListEl.firstChild);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.LayersController.prototype.onClick_ = function (evt) {
|
||||||
|
var el = evt.target || evt.srcElement;
|
||||||
|
if (el.nodeName == 'BUTTON') {
|
||||||
|
this.onButtonClick_(el);
|
||||||
|
} else if (el.nodeName == 'LI') {
|
||||||
|
var layerName = el.getAttribute('data-layer-name');
|
||||||
|
this.piskelController.selectLayerByName(layerName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.LayersController.prototype.onButtonClick_ = function (button) {
|
||||||
|
var action = button.getAttribute('data-action');
|
||||||
|
if (action == 'up') {
|
||||||
|
this.piskelController.moveLayerUp();
|
||||||
|
} else if (action == 'down') {
|
||||||
|
this.piskelController.moveLayerDown();
|
||||||
|
} else if (action == 'add') {
|
||||||
|
this.piskelController.createLayer();
|
||||||
|
} else if (action == 'delete') {
|
||||||
|
this.piskelController.removeCurrentLayer();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
@@ -12,12 +12,10 @@
|
|||||||
|
|
||||||
$.subscribe(Events.PRIMARY_COLOR_UPDATED, $.proxy(function(evt, color) {
|
$.subscribe(Events.PRIMARY_COLOR_UPDATED, $.proxy(function(evt, color) {
|
||||||
this.updateColorPicker_(color, $('#color-picker'));
|
this.updateColorPicker_(color, $('#color-picker'));
|
||||||
this.addColorToPalette_(color);
|
|
||||||
}, this));
|
}, this));
|
||||||
|
|
||||||
$.subscribe(Events.SECONDARY_COLOR_UPDATED, $.proxy(function(evt, color) {
|
$.subscribe(Events.SECONDARY_COLOR_UPDATED, $.proxy(function(evt, color) {
|
||||||
this.updateColorPicker_(color, $('#secondary-color-picker'));
|
this.updateColorPicker_(color, $('#secondary-color-picker'));
|
||||||
this.addColorToPalette_(color);
|
|
||||||
}, this));
|
}, this));
|
||||||
|
|
||||||
// Initialize colorpickers:
|
// Initialize colorpickers:
|
||||||
|
@@ -22,6 +22,10 @@
|
|||||||
return this.piskel.getWidth();
|
return this.piskel.getWidth();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.getLayers = function () {
|
||||||
|
return this.piskel.getLayers();
|
||||||
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.getCurrentLayer = function () {
|
ns.PiskelController.prototype.getCurrentLayer = function () {
|
||||||
return this.piskel.getLayerAt(this.currentLayerIndex);
|
return this.piskel.getLayerAt(this.currentLayerIndex);
|
||||||
};
|
};
|
||||||
@@ -32,7 +36,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.getFrameAt = function (index) {
|
ns.PiskelController.prototype.getFrameAt = function (index) {
|
||||||
var frames = this.piskel.getLayers().map(function (l) {
|
var frames = this.getLayers().map(function (l) {
|
||||||
return l.getFrameAt(index);
|
return l.getFrameAt(index);
|
||||||
});
|
});
|
||||||
return pskl.utils.FrameUtils.merge(frames);
|
return pskl.utils.FrameUtils.merge(frames);
|
||||||
@@ -47,7 +51,7 @@
|
|||||||
ns.PiskelController.prototype.getMergedFrameAt;
|
ns.PiskelController.prototype.getMergedFrameAt;
|
||||||
|
|
||||||
ns.PiskelController.prototype.addEmptyFrame = function () {
|
ns.PiskelController.prototype.addEmptyFrame = function () {
|
||||||
var layers = this.piskel.getLayers();
|
var layers = this.getLayers();
|
||||||
layers.forEach(function (l) {
|
layers.forEach(function (l) {
|
||||||
l.addFrame(this.createEmptyFrame_());
|
l.addFrame(this.createEmptyFrame_());
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
@@ -59,7 +63,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.removeFrameAt = function (index) {
|
ns.PiskelController.prototype.removeFrameAt = function (index) {
|
||||||
var layers = this.piskel.getLayers();
|
var layers = this.getLayers();
|
||||||
layers.forEach(function (l) {
|
layers.forEach(function (l) {
|
||||||
l.removeFrameAt(index);
|
l.removeFrameAt(index);
|
||||||
});
|
});
|
||||||
@@ -72,14 +76,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.duplicateFrameAt = function (index) {
|
ns.PiskelController.prototype.duplicateFrameAt = function (index) {
|
||||||
var layers = this.piskel.getLayers();
|
var layers = this.getLayers();
|
||||||
layers.forEach(function (l) {
|
layers.forEach(function (l) {
|
||||||
l.duplicateFrameAt(index);
|
l.duplicateFrameAt(index);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.moveFrame = function (fromIndex, toIndex) {
|
ns.PiskelController.prototype.moveFrame = function (fromIndex, toIndex) {
|
||||||
var layers = this.piskel.getLayers();
|
var layers = this.getLayers();
|
||||||
layers.forEach(function (l) {
|
layers.forEach(function (l) {
|
||||||
l.moveFrame(fromIndex, toIndex);
|
l.moveFrame(fromIndex, toIndex);
|
||||||
});
|
});
|
||||||
@@ -100,13 +104,58 @@
|
|||||||
$.publish(Events.FRAMESHEET_RESET);
|
$.publish(Events.FRAMESHEET_RESET);
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.createLayer = function (name) {
|
ns.PiskelController.prototype.selectLayer = function (layer) {
|
||||||
var layer = new pskl.model.Layer(name);
|
var index = this.getLayers().indexOf(layer);
|
||||||
for (var i = 0 ; i < this.getFrameCount() ; i++) {
|
if (index != -1) {
|
||||||
layer.addFrame(this.createEmptyFrame_());
|
this.setCurrentLayerIndex(index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.selectLayerByName = function (name) {
|
||||||
|
if (this.hasLayerForName_(name)) {
|
||||||
|
var layer = this.piskel.getLayersByName(name)[0];
|
||||||
|
this.selectLayer(layer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.createLayer = function (name) {
|
||||||
|
if (!name) {
|
||||||
|
name = "Layer " + (this.getLayers().length + 1);
|
||||||
|
}
|
||||||
|
if (!this.hasLayerForName_(name)) {
|
||||||
|
var layer = new pskl.model.Layer(name);
|
||||||
|
for (var i = 0 ; i < this.getFrameCount() ; i++) {
|
||||||
|
layer.addFrame(this.createEmptyFrame_());
|
||||||
|
}
|
||||||
|
this.piskel.addLayer(layer);
|
||||||
|
this.setCurrentLayerIndex(this.piskel.getLayers().length - 1);
|
||||||
|
} else {
|
||||||
|
throw 'Layer name should be unique';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.hasLayerForName_ = function (name) {
|
||||||
|
return this.piskel.getLayersByName(name).length > 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.moveLayerUp = function () {
|
||||||
|
var layer = this.getCurrentLayer();
|
||||||
|
this.piskel.moveLayerUp(layer);
|
||||||
|
this.selectLayer(layer);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.moveLayerDown = function () {
|
||||||
|
var layer = this.getCurrentLayer();
|
||||||
|
this.piskel.moveLayerDown(layer);
|
||||||
|
this.selectLayer(layer);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PiskelController.prototype.removeCurrentLayer = function () {
|
||||||
|
if (this.getLayers().length > 1) {
|
||||||
|
var layer = this.getCurrentLayer();
|
||||||
|
this.piskel.removeLayer(layer);
|
||||||
|
this.setCurrentLayerIndex(0);
|
||||||
}
|
}
|
||||||
this.piskel.addLayer(layer);
|
|
||||||
this.setCurrentLayerIndex(this.piskel.getLayers().length - 1);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PiskelController.prototype.serialize = function () {
|
ns.PiskelController.prototype.serialize = function () {
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
// Expand drawer when clicking 'Settings' tab.
|
// Expand drawer when clicking 'Settings' tab.
|
||||||
$('[data-setting]').click(function(evt) {
|
$('[data-setting]').click(function(evt) {
|
||||||
var el = evt.originalEvent.currentTarget;
|
var el = evt.originalEvent.currentTarget;
|
||||||
var setting = el.dataset.setting;
|
var setting = el.getAttribute("data-setting");
|
||||||
if (this.currentSetting != setting) {
|
if (this.currentSetting != setting) {
|
||||||
this.loadSetting(setting);
|
this.loadSetting(setting);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -5,12 +5,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.GifExportController.prototype.init = function () {
|
ns.GifExportController.prototype.init = function () {
|
||||||
this.initRadioElements_();
|
this.radioTemplate_ = pskl.utils.Template.get("export-gif-radio-template");
|
||||||
|
|
||||||
this.previewContainer = document.querySelectorAll(".export-gif-preview div")[0];
|
this.previewContainer = document.querySelectorAll(".export-gif-preview div")[0];
|
||||||
this.uploadForm = $("[name=gif-export-upload-form]");
|
|
||||||
|
|
||||||
|
this.uploadForm = $("[name=gif-export-upload-form]");
|
||||||
this.uploadForm.submit(this.upload.bind(this));
|
this.uploadForm.submit(this.upload.bind(this));
|
||||||
|
|
||||||
|
this.initRadioElements_();
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.GifExportController.prototype.upload = function (evt) {
|
ns.GifExportController.prototype.upload = function (evt) {
|
||||||
@@ -52,18 +54,17 @@
|
|||||||
[10,true] //default
|
[10,true] //default
|
||||||
];
|
];
|
||||||
|
|
||||||
var radioTpl = $("#export-gif-radio-template").get(0);
|
|
||||||
for (var i = 0 ; i < dpis.length ; i++) {
|
for (var i = 0 ; i < dpis.length ; i++) {
|
||||||
var dpi = dpis[i];
|
var dpi = dpis[i];
|
||||||
var radio = this.createRadioForDpi_(dpi, radioTpl.innerHTML);
|
var radio = this.createRadioForDpi_(dpi);
|
||||||
radioTpl.parentNode.insertBefore(radio, radioTpl);
|
this.uploadForm.get(0).appendChild(radio);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.GifExportController.prototype.createRadioForDpi_ = function (dpi, template) {
|
ns.GifExportController.prototype.createRadioForDpi_ = function (dpi) {
|
||||||
var label = dpi[0]*this.piskelController.getWidth() + "x" + dpi[0]*this.piskelController.getHeight();
|
var label = dpi[0]*this.piskelController.getWidth() + "x" + dpi[0]*this.piskelController.getHeight();
|
||||||
var value = dpi[0];
|
var value = dpi[0];
|
||||||
var radioHTML = pskl.utils.Template.replace(template, {value : value, label : label});
|
var radioHTML = pskl.utils.Template.replace(this.radioTemplate_, {value : value, label : label});
|
||||||
var radio = pskl.utils.Template.createFromHTML(radioHTML);
|
var radio = pskl.utils.Template.createFromHTML(radioHTML);
|
||||||
|
|
||||||
if (dpi[1]) {
|
if (dpi[1]) {
|
||||||
|
@@ -48,10 +48,32 @@
|
|||||||
return this.layers[index];
|
return this.layers[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.Piskel.prototype.getLayersByName = function (name) {
|
||||||
|
return this.layers.filter(function (l) {
|
||||||
|
return l.getName() == name;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
ns.Piskel.prototype.addLayer = function (layer) {
|
ns.Piskel.prototype.addLayer = function (layer) {
|
||||||
this.layers.push(layer);
|
this.layers.push(layer);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.Piskel.prototype.moveLayerUp = function (layer) {
|
||||||
|
var index = this.layers.indexOf(layer);
|
||||||
|
if (index > -1 && index < this.layers.length-1) {
|
||||||
|
this.layers[index] = this.layers[index+1];
|
||||||
|
this.layers[index+1] = layer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.Piskel.prototype.moveLayerDown = function (layer) {
|
||||||
|
var index = this.layers.indexOf(layer);
|
||||||
|
if (index > 0) {
|
||||||
|
this.layers[index] = this.layers[index-1];
|
||||||
|
this.layers[index-1] = layer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ns.Piskel.prototype.removeLayer = function (layer) {
|
ns.Piskel.prototype.removeLayer = function (layer) {
|
||||||
var index = this.layers.indexOf(layer);
|
var index = this.layers.indexOf(layer);
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
|
@@ -44,6 +44,7 @@ exports.scripts = [
|
|||||||
"js/controller/PiskelController.js",
|
"js/controller/PiskelController.js",
|
||||||
"js/controller/DrawingController.js",
|
"js/controller/DrawingController.js",
|
||||||
"js/controller/PreviewFilmController.js",
|
"js/controller/PreviewFilmController.js",
|
||||||
|
"js/controller/LayersController.js",
|
||||||
"js/controller/AnimatedPreviewController.js",
|
"js/controller/AnimatedPreviewController.js",
|
||||||
"js/controller/ToolController.js",
|
"js/controller/ToolController.js",
|
||||||
"js/controller/PaletteController.js",
|
"js/controller/PaletteController.js",
|
||||||
|
13
templates/layers.html
Normal file
13
templates/layers.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="layers-container">
|
||||||
|
<h3 class="layers-title">Layers</h3>
|
||||||
|
<script type="text/template" id="layer-item-template">
|
||||||
|
<li class="layer-item" data-layer-name="{{layername}}">{{layername}}</li>
|
||||||
|
</script>
|
||||||
|
<ul class="layers-list"></ul>
|
||||||
|
<div class="layers-button-container">
|
||||||
|
<button class="layers-button" data-action="add" >Add</button>
|
||||||
|
<button class="layers-button" data-action="delete" >Delete</button>
|
||||||
|
<button class="layers-button" data-action="up" >↑</button>
|
||||||
|
<button class="layers-button" data-action="down" >↓</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
Reference in New Issue
Block a user