mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Rework frameslist for better perfomance
This commit is contained in:
parent
ebab5ecb3f
commit
fb97533cc9
@ -1,8 +1,6 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller');
|
||||
|
||||
var RENDER_MINIMUM_DELAY = 500;
|
||||
|
||||
var ACTION = {
|
||||
SELECT : 'select',
|
||||
CLONE : 'clone',
|
||||
@ -13,19 +11,21 @@
|
||||
ns.FramesListController = function (piskelController, container) {
|
||||
this.piskelController = piskelController;
|
||||
this.container = container;
|
||||
this.domInitialized = false;
|
||||
this.refreshZoom_();
|
||||
|
||||
this.lastRenderTime = 0;
|
||||
this.redrawFlag = true;
|
||||
|
||||
this.cachedFrameProcessor = new pskl.model.frame.CachedFrameProcessor();
|
||||
this.cachedFrameProcessor.setFrameProcessor(this.frameToPreviewCanvas_.bind(this));
|
||||
this.cachedFrameProcessor.setOutputCloner(this.clonePreviewCanvas_.bind(this));
|
||||
|
||||
this.initDragndropBehavior_();
|
||||
};
|
||||
|
||||
ns.FramesListController.prototype.init = function() {
|
||||
$.subscribe(Events.TOOL_RELEASED, this.flagForRedraw_.bind(this));
|
||||
$.subscribe(Events.PISKEL_RESET, this.flagForRedraw_.bind(this));
|
||||
$.subscribe(Events.PISKEL_RESET, this.flagForRedraw_.bind(this, true));
|
||||
$.subscribe(Events.USER_SETTINGS_CHANGED, this.flagForRedraw_.bind(this));
|
||||
|
||||
$.subscribe(Events.PISKEL_RESET, this.refreshZoom_.bind(this));
|
||||
@ -35,8 +35,12 @@
|
||||
this.updateScrollerOverflows();
|
||||
};
|
||||
|
||||
ns.FramesListController.prototype.flagForRedraw_ = function () {
|
||||
ns.FramesListController.prototype.flagForRedraw_ = function (reinitializeDom) {
|
||||
this.redrawFlag = true;
|
||||
|
||||
if (reinitializeDom) {
|
||||
this.domInitialized = false;
|
||||
}
|
||||
};
|
||||
|
||||
ns.FramesListController.prototype.refreshZoom_ = function () {
|
||||
@ -44,10 +48,15 @@
|
||||
};
|
||||
|
||||
ns.FramesListController.prototype.render = function () {
|
||||
if (this.redrawFlag && (Date.now() - this.lastRenderTime > RENDER_MINIMUM_DELAY)) {
|
||||
this.createPreviews_();
|
||||
if (this.redrawFlag) {
|
||||
if (!this.domInitialized) {
|
||||
this.tiles = [];
|
||||
this.addFrameTile = null;
|
||||
this.createPreviews_();
|
||||
}
|
||||
|
||||
this.updatePreviews_();
|
||||
this.redrawFlag = false;
|
||||
this.lastRenderTime = Date.now();
|
||||
}
|
||||
};
|
||||
|
||||
@ -84,16 +93,56 @@
|
||||
|
||||
if (action === ACTION.CLONE) {
|
||||
this.piskelController.duplicateFrameAt(index);
|
||||
var clonedTile = this.createPreviewTile_(index + 1);
|
||||
this.container.get(0).insertBefore(clonedTile, this.tiles[index].nextSibling);
|
||||
this.tiles.splice(index, 0, clonedTile);
|
||||
this.updateScrollerOverflows();
|
||||
} else if (action === ACTION.DELETE) {
|
||||
this.piskelController.removeFrameAt(index);
|
||||
this.container.get(0).removeChild(this.tiles[index]);
|
||||
this.tiles.splice(index, 1);
|
||||
this.updateScrollerOverflows();
|
||||
} else if (action === ACTION.SELECT) {
|
||||
this.piskelController.setCurrentFrameIndex(index);
|
||||
} else if (action === ACTION.NEW_FRAME) {
|
||||
this.piskelController.addFrame();
|
||||
var newtile = this.createPreviewTile_(this.tiles.length);
|
||||
this.tiles.push(newtile);
|
||||
this.container.get(0).insertBefore(newtile, this.addFrameTile);
|
||||
this.updateScrollerOverflows();
|
||||
}
|
||||
|
||||
this.flagForRedraw_();
|
||||
};
|
||||
|
||||
ns.FramesListController.prototype.updatePreviews_ = function () {
|
||||
for (var i = 0, length = this.tiles.length; i < length; i++) {
|
||||
// Remove selected class
|
||||
this.tiles[i].classList.remove('selected');
|
||||
|
||||
// Update tile numbers
|
||||
this.tiles[i].setAttribute('data-tile-number', i);
|
||||
this.tiles[i].querySelector('.tile-count').innerHTML = (i + 1);
|
||||
|
||||
// Check if any tile is updated
|
||||
if (this.tiles[i].getAttribute('data-tile-hash') !== this.piskelController.getCurrentLayer().getFrameAt(i).getHash()) {
|
||||
if (this.tiles[i].querySelector('canvas')) {
|
||||
this.tiles[i].querySelector('.canvas-container').replaceChild(this.getCanvasForFrame(this.piskelController.getCurrentLayer().getFrameAt(i)), this.tiles[i].querySelector('canvas'));
|
||||
} else {
|
||||
this.tiles[i].querySelector('.canvas-container').appendChild(this.getCanvasForFrame(this.piskelController.getCurrentLayer().getFrameAt(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Hide/Show buttons if needed
|
||||
var buttons = this.container.get(0).querySelectorAll('.delete-frame-action, .dnd-action');
|
||||
var display = (this.piskelController.getFrameCount() > 1) ? 'block' : 'none';
|
||||
for (var i = 0, length = buttons.length; i < length; i++) {
|
||||
buttons[i].style.display = display;
|
||||
}
|
||||
|
||||
// Add selected class
|
||||
this.tiles[this.piskelController.getCurrentFrameIndex()].classList.add('selected');
|
||||
};
|
||||
|
||||
ns.FramesListController.prototype.createPreviews_ = function () {
|
||||
@ -104,7 +153,9 @@
|
||||
var frameCount = this.piskelController.getFrameCount();
|
||||
|
||||
for (var i = 0 ; i < frameCount ; i++) {
|
||||
this.container.append(this.createPreviewTile_(i));
|
||||
var tile = this.createPreviewTile_(i);
|
||||
this.container.append(tile);
|
||||
this.tiles[i] = tile;
|
||||
}
|
||||
// Append 'new empty frame' button
|
||||
var newFrameButton = document.createElement('div');
|
||||
@ -114,12 +165,10 @@
|
||||
newFrameButton.innerHTML = '<div class="add-frame-action-icon icon-frame-plus-white">' +
|
||||
'</div><div class="label">Add new frame</div>';
|
||||
this.container.append(newFrameButton);
|
||||
|
||||
var needDragndropBehavior = (frameCount > 1);
|
||||
if (needDragndropBehavior) {
|
||||
this.initDragndropBehavior_();
|
||||
}
|
||||
this.addFrameTile = newFrameButton;
|
||||
|
||||
this.updateScrollerOverflows();
|
||||
this.domInitialized = true;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -146,6 +195,10 @@
|
||||
|
||||
this.piskelController.moveFrame(originFrameId, targetInsertionId);
|
||||
this.piskelController.setCurrentFrameIndex(targetInsertionId);
|
||||
|
||||
var tile = this.tiles.splice(originFrameId, 1)[0];
|
||||
this.tiles.splice(targetInsertionId, 0, tile);
|
||||
this.flagForRedraw_();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -157,6 +210,7 @@
|
||||
|
||||
var previewTileRoot = document.createElement('li');
|
||||
previewTileRoot.setAttribute('data-tile-number', tileNumber);
|
||||
previewTileRoot.setAttribute('data-tile-hash', currentFrame.getHash());
|
||||
previewTileRoot.setAttribute('data-tile-action', ACTION.SELECT);
|
||||
previewTileRoot.classList.add('preview-tile');
|
||||
if (this.piskelController.getCurrentFrame() == currentFrame) {
|
||||
@ -175,10 +229,14 @@
|
||||
canvasContainer.style.marginLeft = verticalMargin + 'px';
|
||||
canvasContainer.style.marginRight = verticalMargin + 'px';
|
||||
|
||||
// Add canvas background and canvas
|
||||
var canvasBackground = document.createElement('div');
|
||||
canvasBackground.className = 'canvas-background';
|
||||
canvasContainer.appendChild(canvasBackground);
|
||||
canvasContainer.appendChild(this.getCanvasForFrame(currentFrame));
|
||||
previewTileRoot.appendChild(canvasContainer);
|
||||
|
||||
// Add clone button
|
||||
var cloneFrameButton = document.createElement('button');
|
||||
cloneFrameButton.setAttribute('rel', 'tooltip');
|
||||
cloneFrameButton.setAttribute('data-placement', 'right');
|
||||
@ -188,25 +246,22 @@
|
||||
cloneFrameButton.className = 'tile-overlay duplicate-frame-action icon-frame-duplicate-white';
|
||||
previewTileRoot.appendChild(cloneFrameButton);
|
||||
|
||||
canvasContainer.appendChild(this.getCanvasForFrame(currentFrame));
|
||||
previewTileRoot.appendChild(canvasContainer);
|
||||
// Add delete button
|
||||
var deleteButton = document.createElement('button');
|
||||
deleteButton.setAttribute('rel', 'tooltip');
|
||||
deleteButton.setAttribute('data-placement', 'right');
|
||||
deleteButton.setAttribute('title', 'Delete this frame');
|
||||
deleteButton.setAttribute('data-tile-number', tileNumber);
|
||||
deleteButton.setAttribute('data-tile-action', ACTION.DELETE);
|
||||
deleteButton.className = 'tile-overlay delete-frame-action icon-frame-recyclebin-white';
|
||||
previewTileRoot.appendChild(deleteButton);
|
||||
|
||||
if (tileNumber > 0 || this.piskelController.getFrameCount() > 1) {
|
||||
// Add 'remove frame' button.
|
||||
var deleteButton = document.createElement('button');
|
||||
deleteButton.setAttribute('rel', 'tooltip');
|
||||
deleteButton.setAttribute('data-placement', 'right');
|
||||
deleteButton.setAttribute('title', 'Delete this frame');
|
||||
deleteButton.setAttribute('data-tile-number', tileNumber);
|
||||
deleteButton.setAttribute('data-tile-action', ACTION.DELETE);
|
||||
deleteButton.className = 'tile-overlay delete-frame-action icon-frame-recyclebin-white';
|
||||
previewTileRoot.appendChild(deleteButton);
|
||||
// Add 'dragndrop handle'.
|
||||
var dndHandle = document.createElement('div');
|
||||
dndHandle.className = 'tile-overlay dnd-action icon-frame-dragndrop-white' ;
|
||||
previewTileRoot.appendChild(dndHandle);
|
||||
|
||||
// Add 'dragndrop handle'.
|
||||
var dndHandle = document.createElement('div');
|
||||
dndHandle.className = 'tile-overlay dnd-action icon-frame-dragndrop-white' ;
|
||||
previewTileRoot.appendChild(dndHandle);
|
||||
}
|
||||
// Add tile count
|
||||
var tileCount = document.createElement('div');
|
||||
tileCount.className = 'tile-overlay tile-count';
|
||||
tileCount.innerHTML = tileNumber + 1;
|
||||
|
Loading…
Reference in New Issue
Block a user