Implementing interstitial tiles

Interstitial tiles are fake slides and allow us to insert drag n drop
tiles between two other.
This commit is contained in:
Vince 2012-09-08 02:50:59 +02:00
parent 39b85e6092
commit c66ce4c9ad
6 changed files with 3151 additions and 16 deletions

View File

@ -35,10 +35,29 @@
background-color: lightyellow;
}
.preview-tile.ui-draggable-dragging {
opacity: 0.3;
}
.preview-tile.droppable-active {
background-color: pink;
}
.interstitial-tile.droppable-hover-active {
background-color: purple;
}
.preview-tile.droppable-hover-active {
background-color: yellow;
}
.interstitial-tile {
visibility: hidden;
background-color: blue;
height: 10px;
}
.show-interstitial-tiles .interstitial-tile {
visibility: visible;
}

View File

@ -77,7 +77,7 @@
<!-- Core libraries: -->
<script src="js/lib/jquery-1.8.0.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script>
<script src="js/lib/jquery-ui-1.8.23.custom.js"></script>
<script src="js/lib/pubsub.js"></script>
<!-- Application wide configuration -->

View File

@ -21,24 +21,66 @@
};
ns.PreviewFilmController.prototype.createPreviews = function () {
// TODO(vincz): Full redraw on any drawing modification, optimize.
this.container.html("");
for (var i = 0, l = this.framesheet.getFrameCount(); i < l ; i++) {
this.container.append(this.createPreviewTile(i));
var frameCount = this.framesheet.getFrameCount();
for (var i = 0, l = frameCount; i < l ; i++) {
this.container.append(this.createInterstitialTile_(i));
this.container.append(this.createPreviewTile_(i));
}
this.container.append(this.createInterstitialTile_(frameCount));
var needDragndropBehavior = !!(frameCount > 1);
if(needDragndropBehavior) {
this.initDragndropBehavior_();
}
this.initTilesBehavior();
};
ns.PreviewFilmController.prototype.initTilesBehavior = function () {
/**
* @private
*/
ns.PreviewFilmController.prototype.createInterstitialTile_ = function (tileNumber) {
var initerstitialTile = document.createElement("div");
initerstitialTile.className = "interstitial-tile"
initerstitialTile.setAttribute("data-tile-type", "interstitial");
initerstitialTile.setAttribute("data-inject-drop-tile-at", tileNumber);
return initerstitialTile;
};
/**
* @private
*/
ns.PreviewFilmController.prototype.initDragndropBehavior_ = function () {
var tiles = $(".preview-tile");
// Each preview film tile is draggable.
tiles.draggable( {
containment: '#preview-list',
//containment: '.left-nav',
stack: '.preview-tile',
cursor: 'move',
revert: true
revert: true,
start: function(event, ui) {
// We only show the fake interstitial tiles when starting the
// drag n drop interaction. We hide them when the DnD is done.
$('#preview-list').addClass("show-interstitial-tiles");
},
stop: function() {
$('#preview-list').removeClass("show-interstitial-tiles");
}
});
tiles.droppable( {
// Each preview film tile is a drop target. This allow us to swap two tiles.
// However, we want to be able to insert a tile between two other tiles.
// For that we created fake interstitial tiles that are used as drop targets as well.
var droppableTiles = $(".interstitial-tile");
$.merge(droppableTiles, tiles);
droppableTiles.droppable( {
accept: ".preview-tile",
tolerance: "pointer",
activeClass: "droppable-active",
hoverClass: "droppable-hover-active",
drop: $.proxy(this.onDrop_, this)
@ -49,22 +91,55 @@
* @private
*/
ns.PreviewFilmController.prototype.onDrop_ = function( event, ui ) {
var frameId1 = parseInt($(event.srcElement).data("tile-number"), 10);
var frameId2 = parseInt($(event.target).data("tile-number"), 10);
var activeFrame;
var originFrameId = parseInt($(event.srcElement).data("tile-number"), 10);
var dropTarget = $(event.target);
if(isNaN(frameId1) || isNaN(frameId2)) {
return;
if(dropTarget.data("tile-type") == "interstitial") {
var targetInsertionId = parseInt(dropTarget.data("inject-drop-tile-at"), 10);
// In case we drop outside of the tile container
if(isNaN(originFrameId) || isNaN(targetInsertionId)) {
return;
}
console.log("origin-frame: "+originFrameId+" - targetInsertionId: "+ targetInsertionId)
this.framesheet.moveFrame(originFrameId, targetInsertionId);
activeFrame = targetInsertionId;
// The last fake interstitial tile is outside of the framesheet array bound.
// It allow us to append after the very last element in this fake slot.
// However, when setting back the active frame, we have to make sure the
// frame does exist.
if(activeFrame > (this.framesheet.getFrameCount() - 1)) {
activeFrame = targetInsertionId - 1;
}
}
else {
var targetSwapId = parseInt(dropTarget.data("tile-number"), 10);
// In case we drop outside of the tile container
if(isNaN(originFrameId) || isNaN(targetSwapId)) {
return;
}
console.log("origin-frame: "+originFrameId+" - targetSwapId: "+ targetSwapId)
this.framesheet.swapFrames(originFrameId, targetSwapId);
activeFrame = targetSwapId;
}
this.framesheet.swapFrames(frameId1, frameId2);
// TODO(vincz): deprecate
piskel.setActiveFrameAndRedraw(frameId2);
$('#preview-list').removeClass("show-interstitial-tiles");
// TODO(vincz): deprecate.
piskel.setActiveFrameAndRedraw(activeFrame);
// TODO(vincz): move localstorage request to the model layer?
$.publish(Events.LOCALSTORAGE_REQUEST);
};
ns.PreviewFilmController.prototype.createPreviewTile = function(tileNumber) {
/**
* @private
* TODO(vincz): clean this giant rendering function & remove listeners.
*/
ns.PreviewFilmController.prototype.createPreviewTile_ = function(tileNumber) {
var frame = this.framesheet.getFrameByIndex(tileNumber);
var width = frame.getWidth() * this.dpi,
height = frame.getHeight() * this.dpi;

3017
js/lib/jquery-ui-1.8.23.custom.js vendored Executable file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
jquery-ui-1.8.23.custom.js was generated at: http://http://jqueryui.com/download
and contains:
jQuery ui core:
core
widget
position
mouse
Interactions:
Draggable
Droppable
Resizable

View File

@ -96,6 +96,16 @@
this.frames.splice(index + 1, 0, frame.clone());
};
ns.FrameSheet.prototype.moveFrame = function(originIndex, destinationIndex) {
var frameToMove = this.getFrameByIndex(originIndex);
this.frames.splice(destinationIndex, 0,frameToMove);
if(destinationIndex <= originIndex) {
originIndex++;
}
this.removeFrameByIndex(originIndex);
};
ns.FrameSheet.prototype.swapFrames = function(indexFrame1, indexFrame2) {
if(isNaN(indexFrame1) || isNaN(indexFrame1) ||
(!this.hasFrameAtIndex(indexFrame1) && !this.hasFrameAtIndex(indexFrame2))) {