diff --git a/css/style.css b/css/style.css
index 33cf7319..7008f476 100644
--- a/css/style.css
+++ b/css/style.css
@@ -24,6 +24,7 @@ ul, li {
top : 0;
bottom : 0;
width : 200px;
+ overflow-y: scroll;
background : #000;
padding : 10px;
}
@@ -32,7 +33,7 @@ ul, li {
position:absolute;
top : 0;
bottom : 0;
- left : 200px;
+ left : 220px;
right : 0;
background : #ccc;
}
@@ -49,7 +50,7 @@ ul, li {
box-shadow : 0px 0px 2px rgba(0,0,0,0.2);
}
-.preview-container canvas{
+.preview-container canvas {
border : 0px Solid transparent;
border-radius:5px 0px 0px 5px;
}
@@ -71,13 +72,43 @@ ul, li {
display : inline-block;
}
-#preview-list li{
- margin : 10px 0;
- width : 128px;
- height : 128px;
+#preview-list {
+ list-style-type: none;
}
-#preview-list li.selected{
- margin : 8px -2px;
- border : 2px Solid red;
+#preview-list .preview-tile {
+ padding : 10px;
+ overflow: hidden;
+}
+
+.preview-tile .tile-view {
+ float: left;
+}
+
+.preview-tile .tile-action {
+ display: none;
+ float: right;
+}
+
+.preview-tile:hover .tile-action {
+ display: block;
+}
+
+.preview-tile:hover {
+ background-color: lightgray;
+}
+
+#preview-list .preview-tile.selected {
+ background-color: gray;
+}
+
+::-webkit-scrollbar {
+ -webkit-appearance: none;
+ width: 7px;
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 4px;
+ background-color: rgba(180,180,180,.7);
+ -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5);
}
\ No newline at end of file
diff --git a/index.html b/index.html
index f8f0d7c9..bd5efe8b 100644
--- a/index.html
+++ b/index.html
@@ -17,10 +17,10 @@
onmousedown="piskel.onCanvasMousedown(arguments[0])"
onmouseup="piskel.onCanvasMouseup(arguments[0])">
@@ -28,6 +28,9 @@
diff --git a/js/piskel.js b/js/piskel.js
index 62c719e5..f35d0629 100644
--- a/js/piskel.js
+++ b/js/piskel.js
@@ -5,8 +5,40 @@
var piskel = {
init : function () {
this.addFrame();
+ this.initPreview();
+ },
- setInterval(this.refreshAnimatedPreview, 500);
+ initPreview : function() {
+ var scope = this;
+
+ var animFPSTuner = document.getElementById("preview-fps");
+ var animPreviewFPS = parseInt(animFPSTuner.value, 10);
+ var startPreviewRefresh = function() {
+ return setInterval(scope.refreshAnimatedPreview, 1000/animPreviewFPS);
+ };
+ var refreshUpdater = startPreviewRefresh();
+
+ animFPSTuner.addEventListener('keyup', function(evt) {
+ window.clearInterval(refreshUpdater);
+ animPreviewFPS = parseInt(animFPSTuner.value, 10);
+ if(isNaN(animPreviewFPS)) {
+ animPreviewFPS = 1;
+ }
+ if(evt.keyCode == 38) {
+ animPreviewFPS++;
+ }
+ else if (evt.keyCode == 40) {
+ animPreviewFPS--;
+ }
+ if(animPreviewFPS < 1) {
+ animPreviewFPS = 1;
+ }
+ if(animPreviewFPS > 100) {
+ animPreviewFPS = 100;
+ }
+ animFPSTuner.value = animPreviewFPS;
+ refreshUpdater = startPreviewRefresh();
+ });
},
getCurrentCanvas : function () {
@@ -22,29 +54,50 @@
},
createPreviews : function () {
- var container = $('preview-list');
+ var container = $('preview-list'), previewTile;
container.innerHTML = "";
for (var i = 0 ; i < frames.length ; i++) {
- var preview = document.createElement("li");
- if (index == i) {
- preview.className = "selected";
- }
- var canvasPreview = document.createElement("canvas");
-
- canvasPreview.setAttribute('width', '128');
- canvasPreview.setAttribute('height', '128');
-
- canvasPreview.setAttribute('onclick', 'piskel.setFrame('+i+')');
-
- canvasPreview.getContext('2d').drawImage(frames[i], 0, 0, 320, 320, 0, 0 , 128, 128);
- preview.appendChild(canvasPreview);
-
-
- container.appendChild(preview);
-
+ previewTile = this.createPreviewTile(i);
+ container.appendChild(previewTile);
}
},
+ createPreviewTile: function(tileNumber) {
+ var preview = document.createElement("li");
+ var classname = "preview-tile";
+
+ if (index == tileNumber) {
+ classname += " selected";
+ }
+ preview.className = classname;
+
+ var canvasPreview = document.createElement("canvas");
+ canvasPreview.className = "tile-view"
+
+ canvasPreview.setAttribute('width', '128');
+ canvasPreview.setAttribute('height', '128');
+ canvasPreview.setAttribute('onclick', 'piskel.setFrame('+ tileNumber +')');
+
+ var canvasPreviewDuplicateAction = document.createElement("button");
+ canvasPreviewDuplicateAction.className = "tile-action"
+ canvasPreviewDuplicateAction.innerHTML = "dup"
+ canvasPreviewDuplicateAction.setAttribute('onclick', 'piskel.duplicateFrame('+ tileNumber +')');
+
+ canvasPreview.getContext('2d').drawImage(frames[tileNumber], 0, 0, 320, 320, 0, 0 , 128, 128);
+ preview.appendChild(canvasPreview);
+ preview.appendChild(canvasPreviewDuplicateAction);
+
+ if(frames.length > 1) {
+ var canvasPreviewDeleteAction = document.createElement("button");
+ canvasPreviewDeleteAction.className = "tile-action"
+ canvasPreviewDeleteAction.innerHTML = "del"
+ canvasPreviewDeleteAction.setAttribute('onclick', 'piskel.removeFrame('+ tileNumber +')');
+ preview.appendChild(canvasPreviewDeleteAction);
+ }
+
+ return preview;
+ },
+
refreshAnimatedPreview : function () {
var context = $('animated-preview').getContext('2d');
// erase canvas, verify proper way
@@ -64,6 +117,30 @@
this.createPreviews();
},
+ removeFrame: function(frameIndex) {
+ index = frameIndex - 1 < 0 ? 0 : frameIndex - 1;
+ animIndex = 0;
+ frames.splice(frameIndex, 1);
+ $('canvas-container').innerHTML = "";
+ $('canvas-container').appendChild(this.getCurrentCanvas());
+ this.createPreviews();
+ },
+
+ duplicateFrame: function(frameIndex) {
+ index = frameIndex + 1;
+ animIndex = 0;
+ var duplicateCanvas = frames[frameIndex].cloneNode(true);
+ // Copy canvas content:
+ var context = duplicateCanvas.getContext('2d');
+ context.drawImage(frames[frameIndex], 0, 0);
+
+ // Insert cloned node into frame collection:
+ frames.splice(frameIndex + 1, 0, duplicateCanvas);
+ $('canvas-container').innerHTML = "";
+ $('canvas-container').appendChild(this.getCurrentCanvas());
+ this.createPreviews();
+ },
+
updateCursorInfo : function (event) {
var cursor = $('cursorInfo');
cursor.style.top = event.clientY + 10 + "px";
@@ -121,7 +198,7 @@
canvas.setAttribute('height', '320');
canvas.setAttribute('onmousemove', 'piskel.onCanvasMousemove(arguments[0])');
canvas.setAttribute('oncontextmenu', 'piskel.onCanvasContextMenu(arguments[0])');
- canvas.setAttribute('onclick', 'piskel.onCanvasClick(arguments[0])');
+ //canvas.setAttribute('onclick', 'piskel.onCanvasClick(arguments[0])');
var context = canvas.getContext('2d');
context.fillStyle = "white";
@@ -131,6 +208,8 @@
context.drawImage(frames[index], 0, 0, 320, 320, 0, 0 , 320, 320);
}
+ // TODO: We should probably store some metadata or enhance a domain object instead
+ // of the rendered view ? It will allow to decouple view and model and clean a bunch of code above.
frames.push(canvas);
this.setFrame(frames.length - 1);
}