Implemented with history management.
This commit is contained in:
parent
e5d89104a1
commit
89629d2939
11 changed files with 129 additions and 45 deletions
|
@ -136,7 +136,8 @@
|
|||
}
|
||||
|
||||
.preview-tile .tile-overlay.tile-count.toggled {
|
||||
background-color: rgba(111, 215, 0, 0.6);
|
||||
background-color: gold;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.preview-tile .tile-overlay.delete-frame-action {
|
||||
|
|
|
@ -116,8 +116,7 @@
|
|||
this.previewList.insertBefore(newtile, this.addFrameTile);
|
||||
this.updateScrollerOverflows();
|
||||
} else if (action == ACTION.TOGGLE) {
|
||||
var frame = this.piskelController.getCurrentLayer().getFrameAt(index);
|
||||
frame.toggled = !frame.toggled;
|
||||
this.piskelController.toggleFrameAt(index);
|
||||
}
|
||||
|
||||
this.flagForRedraw_();
|
||||
|
@ -138,9 +137,8 @@
|
|||
this.tiles[i].setAttribute('data-tile-number', i);
|
||||
this.tiles[i].querySelector('.tile-count').innerHTML = (i + 1);
|
||||
|
||||
// Update toggle
|
||||
var frame = this.piskelController.getCurrentLayer().getFrameAt(i);
|
||||
if (frame.toggled) {
|
||||
// Update visibility
|
||||
if (this.piskelController.hasVisibleFrameAt(i)) {
|
||||
this.tiles[i].querySelector('.tile-count').classList.add('toggled');
|
||||
}
|
||||
|
||||
|
|
|
@ -152,31 +152,35 @@
|
|||
this.setCurrentFrameIndex(index + 1);
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.toggleFrameAt = function (index) {
|
||||
this.getLayers().forEach(function (l) {
|
||||
l.toggleFrameAt(index);
|
||||
});
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.moveFrame = function (fromIndex, toIndex) {
|
||||
this.getLayers().forEach(function (l) {
|
||||
l.moveFrame(fromIndex, toIndex);
|
||||
});
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getFrames = function () {
|
||||
var layer = this.getCurrentLayer();
|
||||
return layer.getFrames();
|
||||
ns.PiskelController.prototype.hasVisibleFrameAt = function (index) {
|
||||
var frame = this.getCurrentLayer().getFrameAt(index);
|
||||
return frame ? frame.isVisible() : false;
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getToggledFrameIndexes = function () {
|
||||
var frameIndexes = this.getFrames()
|
||||
ns.PiskelController.prototype.getVisibleFrameIndexes = function () {
|
||||
var frameIndexes = this.getCurrentLayer().getFrames()
|
||||
/* Replace each frame with its index
|
||||
or -1 if it's not toggled */
|
||||
or -1 if it's not visible */
|
||||
.map(
|
||||
function(frame, idx) {
|
||||
var idx;
|
||||
idx += 1;
|
||||
return (frame.toggled) ? idx - 1 : -1;
|
||||
return (frame.visible) ? idx : -1;
|
||||
})
|
||||
/* Filter out untoggled frames */
|
||||
/* Filter out invisible frames */
|
||||
.filter(
|
||||
function(frame) {
|
||||
return frame >= 0;
|
||||
function(index) {
|
||||
return index >= 0;
|
||||
});
|
||||
return frameIndexes;
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
this.saveWrap_('moveLayerDown', true);
|
||||
this.saveWrap_('removeCurrentLayer', true);
|
||||
this.saveWrap_('setLayerOpacityAt', true);
|
||||
this.saveWrap_('toggleFrameAt', true);
|
||||
|
||||
var shortcuts = pskl.service.keyboard.Shortcuts;
|
||||
pskl.app.shortcutService.registerShortcut(shortcuts.MISC.PREVIOUS_FRAME, this.selectPreviousFrame.bind(this));
|
||||
|
|
|
@ -281,7 +281,7 @@
|
|||
return this.piskelController.getCurrentFrameIndex();
|
||||
} else {
|
||||
var index = Math.floor(this.elapsedTime / (1000 / this.fps));
|
||||
var frameIndexes = this.piskelController.getToggledFrameIndexes();
|
||||
var frameIndexes = this.piskelController.getVisibleFrameIndexes();
|
||||
if (frameIndexes.length <= index) {
|
||||
this.elapsedTime = 0;
|
||||
index = (frameIndexes.length) ? frameIndexes[0] : this.piskelController.getCurrentFrameIndex();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
this.version = 0;
|
||||
this.pixels = ns.Frame.createEmptyPixelGrid_(width, height);
|
||||
this.stateIndex = 0;
|
||||
this.toggled = true;
|
||||
this.visible = true;
|
||||
} else {
|
||||
throw 'Bad arguments in pskl.model.Frame constructor : ' + width + ', ' + height;
|
||||
}
|
||||
|
@ -152,4 +152,12 @@
|
|||
ns.Frame.prototype.isSameSize = function (otherFrame) {
|
||||
return this.getHeight() == otherFrame.getHeight() && this.getWidth() == otherFrame.getWidth();
|
||||
};
|
||||
|
||||
ns.Frame.prototype.toggleVisibility = function () {
|
||||
this.visible = !this.visible;
|
||||
};
|
||||
|
||||
ns.Frame.prototype.isVisible = function () {
|
||||
return this.visible;
|
||||
};
|
||||
})();
|
||||
|
|
|
@ -110,6 +110,15 @@
|
|||
}
|
||||
};
|
||||
|
||||
ns.Layer.prototype.toggleFrameAt = function (index) {
|
||||
var frame = this.frames[index];
|
||||
if (frame) {
|
||||
frame.toggleVisibility();
|
||||
} else {
|
||||
console.error('Frame not found in toggleFrameAt (at %s)', index);
|
||||
}
|
||||
};
|
||||
|
||||
ns.Layer.prototype.size = function () {
|
||||
return this.frames.length;
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
var descriptor = new pskl.model.piskel.Descriptor(name, description);
|
||||
this.piskel_ = new pskl.model.Piskel(piskelData.width, piskelData.height, piskelData.fps, descriptor);
|
||||
this.hiddenFrames = piskelData.hiddenFrames || [];
|
||||
|
||||
this.layersToLoad_ = piskelData.layers.length;
|
||||
piskelData.layers.forEach(this.deserializeLayer.bind(this));
|
||||
|
@ -73,7 +74,14 @@
|
|||
image.src = chunk.base64PNG;
|
||||
return deferred.promise;
|
||||
})).then(function () {
|
||||
frames.forEach(layer.addFrame.bind(layer));
|
||||
var hiddenFrames = this.hiddenFrames;
|
||||
frames.forEach(function (frame) {
|
||||
layer.addFrame(frame);
|
||||
var currentIndex = layer.getFrames().length - 1;
|
||||
if (hiddenFrames.indexOf(currentIndex) != -1) {
|
||||
frame.visible = false;
|
||||
}
|
||||
});
|
||||
this.layers_[index] = layer;
|
||||
this.onLayerLoaded_();
|
||||
}.bind(this)).catch(function (error) {
|
||||
|
|
|
@ -21,6 +21,16 @@
|
|||
var serializedLayers = piskel.getLayers().map(function (l) {
|
||||
return pskl.utils.serialization.Serializer.serializeLayer(l);
|
||||
});
|
||||
var frames = pskl.app.piskelController.getLayerAt(0).getFrames();
|
||||
var hiddenFrames = frames.map(function (frame, index) {
|
||||
if (frame.visible) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}).filter(function (frameIndex) {
|
||||
return frameIndex !== -1;
|
||||
});
|
||||
|
||||
return JSON.stringify({
|
||||
modelVersion : Constants.MODEL_VERSION,
|
||||
piskel : {
|
||||
|
@ -29,7 +39,8 @@
|
|||
fps : pskl.app.piskelController.getFPS(),
|
||||
height : piskel.getHeight(),
|
||||
width : piskel.getWidth(),
|
||||
layers : serializedLayers
|
||||
layers : serializedLayers,
|
||||
hiddenFrames : hiddenFrames,
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -36,23 +36,36 @@
|
|||
// Layers meta
|
||||
var layerCount = arr16[6];
|
||||
|
||||
// Layers meta
|
||||
var serializedHiddenFramesLength = arr16[7];
|
||||
|
||||
var currentIndex = 8;
|
||||
/********/
|
||||
/* DATA */
|
||||
/********/
|
||||
// Descriptor name
|
||||
var descriptorName = '';
|
||||
for (i = 0; i < descriptorNameLength; i++) {
|
||||
descriptorName += String.fromCharCode(arr16[7 + i]);
|
||||
descriptorName += String.fromCharCode(arr16[currentIndex + i]);
|
||||
}
|
||||
currentIndex += descriptorNameLength;
|
||||
|
||||
// Descriptor description
|
||||
var descriptorDescription = '';
|
||||
for (i = 0; i < descriptorDescriptionLength; i++) {
|
||||
descriptorDescription = String.fromCharCode(arr16[7 + descriptorNameLength + i]);
|
||||
descriptorDescription = String.fromCharCode(arr16[8 + descriptorNameLength + i]);
|
||||
}
|
||||
currentIndex += descriptorDescriptionLength;
|
||||
|
||||
// Hidden frames
|
||||
var serializedHiddenFrames = '';
|
||||
for (i = 0; i < serializedHiddenFramesLength; i++) {
|
||||
serializedHiddenFrames = String.fromCharCode(arr16[8 + descriptorNameLength + i]);
|
||||
}
|
||||
var hiddenFrames = serializedHiddenFrames.split('-');
|
||||
currentIndex += serializedHiddenFramesLength;
|
||||
|
||||
// Layers
|
||||
var layerStartIndex = 7 + descriptorNameLength + descriptorDescriptionLength;
|
||||
var layers = [];
|
||||
var layer;
|
||||
for (i = 0; i < layerCount; i++) {
|
||||
|
@ -60,27 +73,27 @@
|
|||
var frames = [];
|
||||
|
||||
// Meta
|
||||
var layerNameLength = arr16[layerStartIndex];
|
||||
var opacity = arr16[layerStartIndex + 1] / 65535;
|
||||
var frameCount = arr16[layerStartIndex + 2];
|
||||
var dataUriLengthFirstHalf = arr16[layerStartIndex + 3];
|
||||
var dataUriLengthSecondHalf = arr16[layerStartIndex + 4];
|
||||
var layerNameLength = arr16[currentIndex];
|
||||
var opacity = arr16[currentIndex + 1] / 65535;
|
||||
var frameCount = arr16[currentIndex + 2];
|
||||
var dataUriLengthFirstHalf = arr16[currentIndex + 3];
|
||||
var dataUriLengthSecondHalf = arr16[currentIndex + 4];
|
||||
var dataUriLength = (dataUriLengthSecondHalf >>> 0) | (dataUriLengthFirstHalf << 16 >>> 0);
|
||||
|
||||
// Name
|
||||
var layerName = '';
|
||||
for (j = 0; j < layerNameLength; j++) {
|
||||
layerName += String.fromCharCode(arr16[layerStartIndex + 5 + j]);
|
||||
layerName += String.fromCharCode(arr16[currentIndex + 5 + j]);
|
||||
}
|
||||
|
||||
// Data URI
|
||||
var dataUri = '';
|
||||
for (j = 0; j < dataUriLength; j++) {
|
||||
dataUri += String.fromCharCode(arr8[(layerStartIndex + 5 + layerNameLength) * 2 + j]);
|
||||
dataUri += String.fromCharCode(arr8[(currentIndex + 5 + layerNameLength) * 2 + j]);
|
||||
}
|
||||
dataUri = 'data:image/png;base64,' + dataUri;
|
||||
|
||||
layerStartIndex += Math.ceil(5 + layerNameLength + (dataUriLength / 2));
|
||||
currentIndex += Math.ceil(5 + layerNameLength + (dataUriLength / 2));
|
||||
|
||||
layer.name = layerName;
|
||||
layer.opacity = opacity;
|
||||
|
@ -99,6 +112,10 @@
|
|||
var frames = pskl.utils.FrameUtils.createFramesFromSpritesheet(this, layer.frameCount);
|
||||
frames.forEach(function (frame) {
|
||||
layer.model.addFrame(frame);
|
||||
var currentIndex = layer.model.getFrames().length - 1;
|
||||
if (hiddenFrames.indexOf(currentIndex) != -1) {
|
||||
frame.visible = false;
|
||||
}
|
||||
});
|
||||
|
||||
loadedLayers++;
|
||||
|
|
|
@ -101,7 +101,22 @@
|
|||
framesData.push({uri: dataUri, length: dataUriLength});
|
||||
}
|
||||
|
||||
var bytes = ns.ArrayBufferSerializer.calculateRequiredBytes(piskel, framesData);
|
||||
var frames = pskl.app.piskelController.getLayerAt(0).getFrames();
|
||||
var hiddenFrames = frames.map(function (frame, index) {
|
||||
if (frame.visible) {
|
||||
return -1;
|
||||
}
|
||||
return index;
|
||||
}).filter(function (frameIndex) {
|
||||
return frameIndex !== -1;
|
||||
});
|
||||
var serializedHiddenFrames = hiddenFrames.join('-');
|
||||
|
||||
var bytes = ns.ArrayBufferSerializer.calculateRequiredBytes(
|
||||
piskel,
|
||||
framesData,
|
||||
serializedHiddenFrames
|
||||
);
|
||||
|
||||
var buffer = new ArrayBuffer(bytes);
|
||||
var arr8 = new Uint8Array(buffer);
|
||||
|
@ -130,21 +145,33 @@
|
|||
// Layers meta
|
||||
arr16[6] = piskel.getLayers().length;
|
||||
|
||||
// Frames meta
|
||||
arr16[7] = serializedHiddenFrames.length;
|
||||
|
||||
var currentIndex = 8;
|
||||
|
||||
/********/
|
||||
/* DATA */
|
||||
/********/
|
||||
// Descriptor name
|
||||
for (i = 0; i < descriptorNameLength; i++) {
|
||||
arr16[7 + i] = descriptorName.charCodeAt(i);
|
||||
arr16[currentIndex + i] = descriptorName.charCodeAt(i);
|
||||
}
|
||||
currentIndex = currentIndex + descriptorNameLength;
|
||||
|
||||
// Descriptor description
|
||||
for (i = 0; i < descriptorDescriptionLength; i++) {
|
||||
arr16[7 + descriptorNameLength + i] = descriptorDescription.charCodeAt(i);
|
||||
arr16[currentIndex + i] = descriptorDescription.charCodeAt(i);
|
||||
}
|
||||
currentIndex = currentIndex + descriptorDescriptionLength;
|
||||
|
||||
// Hidden frames
|
||||
for (i = 0; i < serializedHiddenFrames.length; i++) {
|
||||
arr16[currentIndex + i] = serializedHiddenFrames.charCodeAt(i);
|
||||
}
|
||||
currentIndex = currentIndex + serializedHiddenFrames.length;
|
||||
|
||||
// Layers
|
||||
var layerStartIndex = 7 + descriptorNameLength + descriptorDescriptionLength;
|
||||
for (i = 0, layers = piskel.getLayers(); i < layers.length; i++) {
|
||||
var layer = layers[i];
|
||||
var frames = layer.getFrames();
|
||||
|
@ -158,23 +185,23 @@
|
|||
dataUriLength = framesData[i].length;
|
||||
|
||||
// Meta
|
||||
arr16[layerStartIndex] = layerNameLength;
|
||||
arr16[layerStartIndex + 1] = Math.floor(opacity * 65535);
|
||||
arr16[layerStartIndex + 2] = frameCount;
|
||||
arr16[layerStartIndex + 3] = ((dataUriLength & 0xffff0000) >> 16) >>> 0; // Upper 16
|
||||
arr16[layerStartIndex + 4] = ((dataUriLength & 0x0000ffff)) >>> 0; // Lower 16
|
||||
arr16[currentIndex] = layerNameLength;
|
||||
arr16[currentIndex + 1] = Math.floor(opacity * 65535);
|
||||
arr16[currentIndex + 2] = frameCount;
|
||||
arr16[currentIndex + 3] = ((dataUriLength & 0xffff0000) >> 16) >>> 0; // Upper 16
|
||||
arr16[currentIndex + 4] = ((dataUriLength & 0x0000ffff)) >>> 0; // Lower 16
|
||||
|
||||
// Name
|
||||
for (j = 0; j < layerNameLength; j++) {
|
||||
arr16[layerStartIndex + 5 + j] = layerName.charCodeAt(j);
|
||||
arr16[currentIndex + 5 + j] = layerName.charCodeAt(j);
|
||||
}
|
||||
|
||||
// Data URI
|
||||
for (j = 0; j < dataUriLength; j++) {
|
||||
arr8[(layerStartIndex + 5 + layerNameLength) * 2 + j] = dataUri.charCodeAt(j);
|
||||
arr8[(currentIndex + 5 + layerNameLength) * 2 + j] = dataUri.charCodeAt(j);
|
||||
}
|
||||
|
||||
layerStartIndex += Math.ceil(5 + layerNameLength + (dataUriLength / 2));
|
||||
currentIndex += Math.ceil(5 + layerNameLength + (dataUriLength / 2));
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
|
Loading…
Reference in a new issue